From b9988126ed4acb171eb449deeba341457612c3a5 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 23 Dec 2024 14:53:09 +0000 Subject: [PATCH 1/2] Add LTO support to clang in CI --- src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile | 6 ++++++ src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh | 1 + src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh | 5 +++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index e857f38e68a85..11ebbde5807bc 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -44,6 +44,8 @@ RUN mkdir -p /rustroot/bin ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig +# Clang needs to access GCC headers to enable linker plugin LTO +ENV GCC_VERSION=9.5.0 WORKDIR /tmp RUN mkdir /home/user COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ @@ -104,3 +106,7 @@ ENV DIST_SRC 1 ENV LIBCURL_NO_PKG_CONFIG 1 ENV DIST_REQUIRE_ALL_TOOLS 1 + +# FIXME: Without this, LLVMgold.so incorrectly resolves to the system +# libstdc++, instead of the one we build. +ENV LD_PRELOAD=/rustroot/lib64/libstdc++.so.6 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index 2e08c87f278c0..3c8123d90de0b 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -39,6 +39,7 @@ hide_output \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \ + -DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC_VERSION/plugin/include/" \ -DC_INCLUDE_DIRS="$INC" hide_output make -j$(nproc) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index e939a5d7eac4d..57d4d338a5065 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -1,10 +1,11 @@ #!/usr/bin/env bash -set -ex +set -eux source shared.sh # Note: in the future when bumping to version 10.1.0, also take care of the sed block below. -GCC=9.5.0 +# This version is specified in the Dockerfile +GCC=$GCC_VERSION curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC From cf1c38d2d1a34008ff01acadba0e7f6047722f7e Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 26 Dec 2024 14:00:15 +0000 Subject: [PATCH 2/2] Strip debuginfo from rustc and rustdoc binaries --- src/bootstrap/src/core/build_steps/compile.rs | 15 +++++++++++++-- src/bootstrap/src/core/build_steps/tool.rs | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6700f3ba680be..7f1ae60af2f2e 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1010,14 +1010,18 @@ impl Step for Rustc { // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with // debuginfo (via the debuginfo level of the executables using it): strip this debuginfo // away after the fact. + let target_root_dir = stamp.parent().unwrap(); if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { - let target_root_dir = stamp.parent().unwrap(); let rustc_driver = target_root_dir.join("librustc_driver.so"); strip_debug(builder, target, &rustc_driver); } + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + strip_debug(builder, target, &target_root_dir.join("rustc-main")); + builder.ensure(RustcLink::from_rustc( self, builder.compiler(compiler.stage, builder.config.build), @@ -2291,7 +2295,14 @@ pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) } let previous_mtime = t!(t!(path.metadata()).modified()); - command("strip").arg("--strip-debug").arg(path).run_capture(builder); + let result = command("strip").arg("--strip-debug").arg(path).run_capture(builder); + if result.is_failure() { + eprintln!( + "warning: `strip --strip-debug {}` failed: `{}`", + path.display(), + result.stderr() + ); + } let file = t!(fs::File::open(path)); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 04f1e10f49370..2b41429b78c4a 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -671,6 +671,9 @@ impl Step for Rustdoc { // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + compile::strip_debug(builder, target, &tool_rustdoc); let bin_rustdoc = bin_rustdoc(); builder.copy_link(&tool_rustdoc, &bin_rustdoc); bin_rustdoc