about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-11-19 08:08:26 -0800
committerGitHub <noreply@github.com>2016-11-19 08:08:26 -0800
commitb1da18fe9be180ecfcfb1691c4eb669c496996f5 (patch)
treefd9ae079f4132c999d84e2eed8d772d1bc56d6e7 /src
parentfb025b483a5ef96bba944055c47af620d2afb602 (diff)
parentf3240377e6ebdff032e9275aee8dd461e9866cbb (diff)
downloadrust-b1da18fe9be180ecfcfb1691c4eb669c496996f5.tar.gz
rust-b1da18fe9be180ecfcfb1691c4eb669c496996f5.zip
Auto merge of #37822 - cuviper:llvm-link-shared, r=alexcrichton
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.

Update: There are now four static/shared scenarios that can happen
for the supported LLVM versions:

- 3.9+: By default use `llvm-config --link-static`
- 3.9+ and `--enable-llvm-link-shared`: Use `--link-shared` instead.
- 3.8: Use `llvm-config --shared-mode` and go with its answer.
- 3.7: Just assume static, maintaining the status quo.
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/compile.rs3
-rw-r--r--src/bootstrap/config.rs2
-rw-r--r--src/librustc_llvm/build.rs45
3 files changed, 39 insertions, 11 deletions
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 5fc4f006729..236989dbcfe 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 996544a2599..60f65f62300 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,
@@ -346,6 +347,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 ca80a5269c9..6be3d1172dc 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -17,6 +17,35 @@ use std::path::{PathBuf, Path};
 
 use build_helper::output;
 
+fn detect_llvm_link(llvm_config: &Path) -> (&'static str, Option<&'static str>) {
+    let mut version_cmd = Command::new(llvm_config);
+    version_cmd.arg("--version");
+    let version_output = output(&mut version_cmd);
+    let mut parts = version_output.split('.').take(2)
+        .filter_map(|s| s.parse::<u32>().ok());
+    if let (Some(major), Some(minor)) = (parts.next(), parts.next()) {
+        if major > 3 || (major == 3 && minor >= 9) {
+            // Force the link mode we want, preferring static by default, but
+            // possibly overridden by `configure --enable-llvm-link-shared`.
+            if env::var_os("LLVM_LINK_SHARED").is_some() {
+                return ("dylib", Some("--link-shared"));
+            } else {
+                return ("static", Some("--link-static"));
+            }
+        } else if major == 3 && minor == 8 {
+            // Find out LLVM's default linking mode.
+            let mut mode_cmd = Command::new(llvm_config);
+            mode_cmd.arg("--shared-mode");
+            if output(&mut mode_cmd).trim() == "shared" {
+                return ("dylib", None);
+            } else {
+                return ("static", None);
+            }
+        }
+    }
+    ("static", None)
+}
+
 fn main() {
     println!("cargo:rustc-cfg=cargobuild");
 
@@ -123,22 +152,16 @@ fn main() {
        .cpp_link_stdlib(None) // we handle this below
        .compile("librustllvm.a");
 
+    let (llvm_kind, llvm_link_arg) = detect_llvm_link(&llvm_config);
+
     // 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.
-    let mut version_cmd = Command::new(&llvm_config);
-    version_cmd.arg("--version");
-    let version_output = output(&mut version_cmd);
-    let mut parts = version_output.split('.');
-    if let (Some(major), Some(minor)) = (parts.next().and_then(|s| s.parse::<u32>().ok()),
-                                         parts.next().and_then(|s| s.parse::<u32>().ok())) {
-        if major > 3 || (major == 3 && minor >= 9) {
-            cmd.arg("--link-static");
-        }
+    if let Some(link_arg) = llvm_link_arg {
+        cmd.arg(link_arg);
     }
 
     if !is_crossed {
@@ -174,7 +197,7 @@ fn main() {
         }
 
         let kind = if name.starts_with("LLVM") {
-            "static"
+            llvm_kind
         } else {
             "dylib"
         };