From f13391a60386fc022761c2aa03f13958d757f2ce Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 16 Nov 2016 23:28:14 -0800 Subject: [PATCH] rustbuild: allow dynamically linking LLVM The makefiles and `mklldeps.py` called `llvm-config --shared-mode` to find out if LLVM defaulted to shared or static libraries, and just went with that. But under rustbuild, `librustc_llvm/build.rs` was assuming that LLVM should be static, and even forcing `--link-static` for 3.9+. Now that build script also uses `--shared-mode` to learn the default, which should work better for pre-3.9 configured for dynamic linking, as it wasn't possible back then to choose differently via `llvm-config`. Further, the configure script now has a new `--enable-llvm-link-shared` option, which allows one to manually override `--link-shared` on 3.9+ instead of forcing static. --- configure | 1 + src/bootstrap/compile.rs | 3 +++ src/bootstrap/config.rs | 2 ++ src/librustc_llvm/build.rs | 23 ++++++++++++++++++++--- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 15bfb5e3ec26..4cdf7d085db0 100755 --- a/configure +++ b/configure @@ -624,6 +624,7 @@ opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds" opt local-rust 0 "use an installed rustc rather than downloading a snapshot" opt local-rebuild 0 "assume local-rust matches the current version, for rebuilds; implies local-rust, and is implied if local-rust already matches the current version" opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM" +opt llvm-link-shared 0 "prefer shared linking to LLVM (llvm-config --link-shared)" opt rpath 1 "build rpaths into rustc itself" opt stage0-landing-pads 1 "enable landing pads during bootstrap with stage0" # This is used by the automation to produce single-target nightlies diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 5fc4f006729d..236989dbcfeb 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -212,6 +212,9 @@ pub fn rustc<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) { cargo.env("LLVM_STATIC_STDCPP", compiler_file(build.cxx(target), "libstdc++.a")); } + if build.config.llvm_link_shared { + cargo.env("LLVM_LINK_SHARED", "1"); + } if let Some(ref s) = build.config.rustc_default_linker { cargo.env("CFG_DEFAULT_LINKER", s); } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 945d482c2aac..17796a1eacf4 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -53,6 +53,7 @@ pub struct Config { pub llvm_release_debuginfo: bool, pub llvm_version_check: bool, pub llvm_static_stdcpp: bool, + pub llvm_link_shared: bool, // rust codegen options pub rust_optimize: bool, @@ -343,6 +344,7 @@ impl Config { ("OPTIMIZE_LLVM", self.llvm_optimize), ("LLVM_VERSION_CHECK", self.llvm_version_check), ("LLVM_STATIC_STDCPP", self.llvm_static_stdcpp), + ("LLVM_LINK_SHARED", self.llvm_link_shared), ("OPTIMIZE", self.rust_optimize), ("DEBUG_ASSERTIONS", self.rust_debug_assertions), ("DEBUGINFO", self.rust_debuginfo), diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index ca80a5269c95..eb4a1da484d1 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -123,13 +123,24 @@ fn main() { .cpp_link_stdlib(None) // we handle this below .compile("librustllvm.a"); + // Find out LLVM's default linking mode. + let mut cmd = Command::new(&llvm_config); + cmd.arg("--shared-mode"); + let mut llvm_kind = if output(&mut cmd).trim() == "shared" { + "dylib" + } else { + "static" + }; + // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then // we don't pick up system libs because unfortunately they're for the host // of llvm-config, not the target that we're attempting to link. let mut cmd = Command::new(&llvm_config); cmd.arg("--libs"); - // Force static linking with "--link-static" if available. + // Force static linking with "--link-static" if available, or + // force "--link-shared" if the configuration requested it. + let llvm_link_shared = env::var_os("LLVM_LINK_SHARED").is_some(); let mut version_cmd = Command::new(&llvm_config); version_cmd.arg("--version"); let version_output = output(&mut version_cmd); @@ -137,7 +148,13 @@ fn main() { if let (Some(major), Some(minor)) = (parts.next().and_then(|s| s.parse::().ok()), parts.next().and_then(|s| s.parse::().ok())) { if major > 3 || (major == 3 && minor >= 9) { - cmd.arg("--link-static"); + if llvm_link_shared { + cmd.arg("--link-shared"); + llvm_kind = "dylib"; + } else { + cmd.arg("--link-static"); + llvm_kind = "static"; + } } } @@ -174,7 +191,7 @@ fn main() { } let kind = if name.starts_with("LLVM") { - "static" + llvm_kind } else { "dylib" };