Skip to content

Commit

Permalink
Auto merge of rust-lang#134690 - clubby789:ci-clang-lto, r=<try>
Browse files Browse the repository at this point in the history
CI: Add LTO support to clang in dist-x86_64-linux

After rust-lang/cc-rs#1279, we attempt to pass `-flto=thin` to clang. In `dist-x86_64-linux`, we don't build clang with the `LLVMgold.so` library so this fails. This attempts to resolve this
First, pass the binutils plugin include directory to Clang, [which will build the library](https://github.com/llvm/llvm-project/blob/2d6d723a85c2d007b0359c206d66cd2e5a9f00e1/llvm/docs/GoldPlugin.rst#how-to-build-it)
Second, this library depends on the *version of libstdc++ that we built* specifically. However, despite both the RPATH and LD_LIBRARY_PATH pointing to `/rustroot/lib`, we incorrectly resolve to the system libstdc++, which doesn't load.
```
# LD_DEBUG=libs,files
      2219:    file=libstdc++.so.6 [0];  needed by /rustroot/bin/../lib/LLVMgold.so [0]
      2219:    find library=libstdc++.so.6 [0]; searching
      2219:     search path=/rustroot/bin/../lib/../lib        (RPATH from file /rustroot/bin/../lib/LLVMgold.so)
      2219:      trying file=/rustroot/bin/../lib/../lib/libstdc++.so.6
      2219:     search path=/usr/lib64/tls:/usr/lib64        (system search path)
      2219:      trying file=/usr/lib64/tls/libstdc++.so.6
      2219:      trying file=/usr/lib64/libstdc++.so.6
```

Using `LD_PRELOAD` causes it to correctly load the library

I think this is probably not the most maintainable way to do this, so opening to see if this is desired and if there's a better way of doing this
  • Loading branch information
bors committed Dec 26, 2024
2 parents 78af7da + cf1c38d commit f5caa26
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 4 deletions.
15 changes: 13 additions & 2 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,14 +989,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),
Expand Down Expand Up @@ -2270,7 +2274,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));

Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/src/core/build_steps/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh
Original file line number Diff line number Diff line change
@@ -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
Expand Down

0 comments on commit f5caa26

Please sign in to comment.