From 71f5aed385b390dc53f8974092d5c7fd9a1ca634 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 18 Mar 2020 13:49:53 -0700 Subject: [PATCH 1/4] Rename add_lib_path to add_dylib_path --- src/bootstrap/builder.rs | 4 ++-- src/bootstrap/tool.rs | 6 +++--- src/bootstrap/util.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 602e4511ea583..4d997c83170fb 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -23,7 +23,7 @@ use crate::install; use crate::native; use crate::test; use crate::tool; -use crate::util::{self, add_lib_path, exe, libdir}; +use crate::util::{self, add_dylib_path, exe, libdir}; use crate::{Build, DocTests, GitRepo, Mode}; pub use crate::Compiler; @@ -660,7 +660,7 @@ impl<'a> Builder<'a> { return; } - add_lib_path(vec![self.rustc_libdir(compiler)], &mut cmd.command); + add_dylib_path(vec![self.rustc_libdir(compiler)], &mut cmd.command); } /// Gets a path to the compiler specified. diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 67e0ed5c58029..c8ccba467e509 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -12,7 +12,7 @@ use crate::channel; use crate::channel::GitInfo; use crate::compile; use crate::toolstate::ToolState; -use crate::util::{add_lib_path, exe, CiEnv}; +use crate::util::{add_dylib_path, exe, CiEnv}; use crate::Compiler; use crate::Mode; @@ -388,7 +388,7 @@ pub struct ErrorIndex { impl ErrorIndex { pub fn command(builder: &Builder<'_>, compiler: Compiler) -> Command { let mut cmd = Command::new(builder.ensure(ErrorIndex { compiler })); - add_lib_path( + add_dylib_path( vec![PathBuf::from(&builder.sysroot_libdir(compiler, compiler.host))], &mut cmd, ); @@ -689,7 +689,7 @@ impl<'a> Builder<'a> { } } - add_lib_path(lib_paths, &mut cmd); + add_dylib_path(lib_paths, &mut cmd); cmd } } diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index eac790fe504b8..aa097b86cd6c6 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -40,7 +40,7 @@ pub fn libdir(target: &str) -> &'static str { } /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path. -pub fn add_lib_path(path: Vec, cmd: &mut Command) { +pub fn add_dylib_path(path: Vec, cmd: &mut Command) { let mut list = dylib_path(); for path in path { list.insert(0, path); From 0536b8dcaafcfc0e51713a05eb0082a6e20725b1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 18 Mar 2020 14:07:04 -0700 Subject: [PATCH 2/4] Ensure LLVM is in the link path for rustc tools --- src/bootstrap/builder.rs | 18 ++++++++++++++++-- src/bootstrap/util.rs | 25 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4d997c83170fb..31125ec4a26a2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::time::{Duration, Instant}; -use build_helper::t; +use build_helper::{output, t}; use crate::cache::{Cache, Interned, INTERNER}; use crate::check; @@ -23,7 +23,7 @@ use crate::install; use crate::native; use crate::test; use crate::tool; -use crate::util::{self, add_dylib_path, exe, libdir}; +use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir}; use crate::{Build, DocTests, GitRepo, Mode}; pub use crate::Compiler; @@ -1034,6 +1034,20 @@ impl<'a> Builder<'a> { .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_libdir(compiler)); } + // Tools that use compiler libraries may inherit the `-lLLVM` link + // requirement, but the `-L` library path is not propagated across + // separate Cargo projects. We can add LLVM's library path to the + // platform-specific environment variable as a workaround. + // + // Note that this is disabled if LLVM itself is disabled or we're in a + // check build, where if we're in a check build there's no need to build + // all of LLVM and such. + if self.config.llvm_enabled() && self.kind != Kind::Check && mode == Mode::ToolRustc { + let llvm_config = self.ensure(native::Llvm { target }); + let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir")); + add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo); + } + if self.config.incremental { cargo.env("CARGO_INCREMENTAL", "1"); } else { diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index aa097b86cd6c6..2bc6f1939d97b 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -72,6 +72,31 @@ pub fn dylib_path() -> Vec { env::split_paths(&var).collect() } +/// Adds a list of lookup paths to `cmd`'s link library lookup path. +pub fn add_link_lib_path(path: Vec, cmd: &mut Command) { + let mut list = link_lib_path(); + for path in path { + list.insert(0, path); + } + cmd.env(link_lib_path_var(), t!(env::join_paths(list))); +} + +/// Returns the environment variable which the link library lookup path +/// resides in for this platform. +fn link_lib_path_var() -> &'static str { + if cfg!(target_env = "msvc") { "LIB" } else { "LIBRARY_PATH" } +} + +/// Parses the `link_lib_path_var()` environment variable, returning a list of +/// paths that are members of this lookup path. +fn link_lib_path() -> Vec { + let var = match env::var_os(link_lib_path_var()) { + Some(v) => v, + None => return vec![], + }; + env::split_paths(&var).collect() +} + /// `push` all components to `buf`. On windows, append `.exe` to the last component. pub fn push_exe_path(mut buf: PathBuf, components: &[&str]) -> PathBuf { let (&file, components) = components.split_last().expect("at least one component required"); From e1a6a306ad4f7bf6fe771b2a9d3362a991eb5ce1 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 18 Mar 2020 14:07:41 -0700 Subject: [PATCH 3/4] Revert "Fix missing libLLVM.so in stage0 sysroot." This reverts commit 8b9c5396ca574fad9cc7b51d16c8c96e0ae74632. --- src/bootstrap/compile.rs | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 65a00db33949e..ad494b88b3af2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -451,44 +451,6 @@ impl Step for Rustc { false, ); - // We used to build librustc_codegen_llvm as a separate step, - // which produced a dylib that the compiler would dlopen() at runtime. - // This meant that we only needed to make sure that libLLVM.so was - // installed by the time we went to run a tool using it - since - // librustc_codegen_llvm was effectively a standalone artifact, - // other crates were completely oblivious to its dependency - // on `libLLVM.so` during build time. - // - // However, librustc_codegen_llvm is now built as an ordinary - // crate during the same step as the rest of the compiler crates. - // This means that any crates depending on it will see the fact - // that it uses `libLLVM.so` as a native library, and will - // cause us to pass `-llibLLVM.so` to the linker when we link - // a binary. - // - // For `rustc` itself, this works out fine. - // During the `Assemble` step, we call `dist::maybe_install_llvm_dylib` - // to copy libLLVM.so into the `stage` directory. We then link - // the compiler binary, which will find `libLLVM.so` in the correct place. - // - // However, this is insufficient for tools that are build against stage0 - // (e.g. stage1 rustdoc). Since `Assemble` for stage0 doesn't actually do anything, - // we won't have `libLLVM.so` in the stage0 sysroot. In the past, this wasn't - // a problem - we would copy the tool binary into its correct stage directory - // (e.g. stage1 for a stage1 rustdoc built against a stage0 compiler). - // Since libLLVM.so wasn't resolved until runtime, it was fine for it to - // not exist while we were building it. - // - // To ensure that we can still build stage1 tools against a stage0 compiler, - // we explicitly copy libLLVM.so into the stage0 sysroot when building - // the stage0 compiler. This ensures that tools built against stage0 - // will see libLLVM.so at build time, making the linker happy. - if compiler.stage == 0 { - builder.info(&format!("Installing libLLVM.so to stage 0 ({})", compiler.host)); - let sysroot = builder.sysroot(compiler); - dist::maybe_install_llvm_dylib(builder, compiler.host, &sysroot); - } - builder.ensure(RustcLink { compiler: builder.compiler(compiler.stage, builder.config.build), target_compiler: compiler, From 3a2a4429a288031e7810e84b35ff13b8dd4608a4 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 19 Mar 2020 10:28:47 -0700 Subject: [PATCH 4/4] Avoid llvm-config in more situations, like bootstrap test runs --- src/bootstrap/builder.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 31125ec4a26a2..dd519506d42a0 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -698,6 +698,20 @@ impl<'a> Builder<'a> { cmd } + /// Return the path to `llvm-config` for the target, if it exists. + /// + /// Note that this returns `None` if LLVM is disabled, or if we're in a + /// check build or dry-run, where there's no need to build all of LLVM. + fn llvm_config(&self, target: Interned) -> Option { + if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run { + let llvm_config = self.ensure(native::Llvm { target }); + if llvm_config.is_file() { + return Some(llvm_config); + } + } + None + } + /// Prepares an invocation of `cargo` to be run. /// /// This will create a `Command` that represents a pending execution of @@ -1038,14 +1052,11 @@ impl<'a> Builder<'a> { // requirement, but the `-L` library path is not propagated across // separate Cargo projects. We can add LLVM's library path to the // platform-specific environment variable as a workaround. - // - // Note that this is disabled if LLVM itself is disabled or we're in a - // check build, where if we're in a check build there's no need to build - // all of LLVM and such. - if self.config.llvm_enabled() && self.kind != Kind::Check && mode == Mode::ToolRustc { - let llvm_config = self.ensure(native::Llvm { target }); - let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir")); - add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo); + if mode == Mode::ToolRustc { + if let Some(llvm_config) = self.llvm_config(target) { + let llvm_libdir = output(Command::new(&llvm_config).arg("--libdir")); + add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cargo); + } } if self.config.incremental {