diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d12ee2935ebf5..101910e66aa73 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -787,6 +787,33 @@ impl<'a> Builder<'a> { } } + // If we're statically linking in an LLVM compiled for ThinLTO, + // configure the linker accordingly. + if Mode::Rustc == mode && self.config.llvm_thin_lto && !self.config.llvm_link_shared { + if target.contains("msvc") { + // Here we assume the linker is lld-link.exe. + rustflags.arg(&format!("-Clink-arg=/opt:lldtojobs={}", self.jobs())); + } else { + // Here we assume the linker is clang and that lld is available. + // If not, there'll be linker errors. + rustflags.arg("-Clink-arg=-fuse-ld=lld"); + rustflags.arg("-Clink-arg=-flto=thin"); + + // Copy the optimization flags LLVM uses for its Release and + // RelWithDebugInfo builds. + if self.config.llvm_optimize { + if self.config.llvm_release_debuginfo { + rustflags.arg("-Clink-arg=-O2"); + } else { + rustflags.arg("-Clink-arg=-O3"); + } + } + + // Make LLD respect the `-j` option. + rustflags.arg(&format!("-Clink-arg=-Wl,--thinlto-jobs={}", self.jobs())); + } + } + // This tells Cargo (and in turn, rustc) to output more complete // dependency information. Most importantly for rustbuild, this // includes sysroot artifacts, like libstd, which means that we don't diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 7dded96e18efd..cf16bdd96a8d5 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -567,9 +567,12 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interne let file = compiler_file(builder, builder.cxx(target).unwrap(), target, "libstdc++.a"); cargo.env("LLVM_STATIC_STDCPP", file); } - if builder.config.llvm_link_shared || builder.config.llvm_thin_lto { + if builder.config.llvm_link_shared { cargo.env("LLVM_LINK_SHARED", "1"); } + if builder.config.llvm_thin_lto { + cargo.env("LLVM_LTO", "thin"); + } if builder.config.llvm_use_libcxx { cargo.env("LLVM_USE_LIBCXX", "1"); } diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile index 2f2a10a0e90ae..86862f9da3469 100644 --- a/src/ci/docker/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/dist-x86_64-linux/Dockerfile @@ -101,6 +101,7 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-linux-gnu.linker=clang \ --set target.x86_64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \ --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \ + --set llvm.link-shared=true \ --set llvm.thin-lto=true \ --set rust.jemalloc ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS diff --git a/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile b/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile index dc90c286f5cd1..90e4a6dcf9493 100644 --- a/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile +++ b/src/ci/docker/x86_64-gnu-llvm-7/Dockerfile @@ -21,11 +21,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -# using llvm-link-shared due to libffi issues -- see #34486 +# using llvm.link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --llvm-root=/usr/lib/llvm-7 \ - --enable-llvm-link-shared \ + --set llvm.link-shared=true \ --set rust.thin-lto-import-instr-limit=10 ENV SCRIPT python2.7 ../x.py test src/tools/tidy && python2.7 ../x.py test diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 405ce0307cd82..b7c90bb696126 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -127,6 +127,7 @@ fn main() { } if flag.starts_with("-flto") { + // Handled below. continue; } @@ -153,6 +154,10 @@ fn main() { cfg.define("NDEBUG", None); } + if let Ok(kind) = env::var("LLVM_LTO") { + cfg.flag(&format!("-flto={}", kind)); + } + build_helper::rerun_if_changed_anything_in_dir(Path::new("../rustllvm")); cfg.file("../rustllvm/PassWrapper.cpp") .file("../rustllvm/RustWrapper.cpp")