about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-08-14 14:31:12 +0200
committerMichael Woerister <michaelwoerister@posteo>2018-08-29 12:27:20 +0200
commit3cf6f0db1ab61ed33c585b156a0d5c41279f0810 (patch)
treec0dee5c185faf4f010d7458a32bcfda9db92f18e /src/bootstrap
parentf4b8451ad9e2a30792f17f913ee4d1b0513d199c (diff)
downloadrust-3cf6f0db1ab61ed33c585b156a0d5c41279f0810.tar.gz
rust-3cf6f0db1ab61ed33c585b156a0d5c41279f0810.zip
bootstrap: Link LLVM tools dynamically in order to save time in ThinLTO builds.
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/dist.rs46
-rw-r--r--src/bootstrap/lib.rs4
-rw-r--r--src/bootstrap/native.rs12
3 files changed, 46 insertions, 16 deletions
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 6e473fae3be..c6ff63ad71b 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -1885,6 +1885,34 @@ impl Step for HashSign {
     }
 }
 
+// Maybe add libLLVM.so to the lib-dir. It will only have been built if
+// LLVM tools are linked dynamically.
+// Note: This function does no yet support Windows but we also don't support
+//       linking LLVM tools dynamically on Windows yet.
+fn maybe_install_llvm_dylib(builder: &Builder,
+                            target: Interned<String>,
+                            image: &Path) {
+    let src_libdir = builder
+        .llvm_out(target)
+        .join("lib");
+
+    // Usually libLLVM.so is a symlink to something like libLLVM-6.0.so.
+    // Since tools link to the latter rather than the former, we have to
+    // follow the symlink to find out what to distribute.
+    let llvm_dylib_path = src_libdir.join("libLLVM.so");
+    if llvm_dylib_path.exists() {
+        let llvm_dylib_path = llvm_dylib_path.canonicalize().unwrap_or_else(|e| {
+            panic!("dist: Error calling canonicalize path `{}`: {}",
+                   llvm_dylib_path.display(), e);
+        });
+
+        let dst_libdir = image.join("lib");
+        t!(fs::create_dir_all(&dst_libdir));
+
+        builder.install(&llvm_dylib_path, &dst_libdir, 0o644);
+    }
+}
+
 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
 pub struct LlvmTools {
     pub stage: u32,
@@ -1929,18 +1957,18 @@ impl Step for LlvmTools {
         drop(fs::remove_dir_all(&image));
 
         // Prepare the image directory
-        let bindir = builder
+        let src_bindir = builder
             .llvm_out(target)
             .join("bin");
-        let dst = image.join("lib/rustlib")
-            .join(target)
-            .join("bin");
-        t!(fs::create_dir_all(&dst));
+        let dst_bindir = image.join("bin");
+        t!(fs::create_dir_all(&dst_bindir));
         for tool in LLVM_TOOLS {
-            let exe = bindir.join(exe(tool, &target));
-            builder.install(&exe, &dst, 0o755);
+            let exe = src_bindir.join(exe(tool, &target));
+            builder.install(&exe, &dst_bindir, 0o755);
         }
 
+        maybe_install_llvm_dylib(builder, target, &image);
+
         // Prepare the overlay
         let overlay = tmp.join("llvm-tools-overlay");
         drop(fs::remove_dir_all(&overlay));
@@ -2025,7 +2053,6 @@ impl Step for Lldb {
         let dst = image.join("lib");
         t!(fs::create_dir_all(&dst));
         for entry in t!(fs::read_dir(&libdir)) {
-            // let entry = t!(entry);
             let entry = entry.unwrap();
             if let Ok(name) = entry.file_name().into_string() {
                 if name.starts_with("liblldb.") && !name.ends_with(".a") {
@@ -2060,6 +2087,9 @@ impl Step for Lldb {
             }
         }
 
+        // Copy libLLVM.so to the lib dir as well, if needed.
+        maybe_install_llvm_dylib(builder, target, &image);
+
         // Prepare the overlay
         let overlay = tmp.join("lldb-overlay");
         drop(fs::remove_dir_all(&overlay));
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 97b05059c88..b6a89e1c18f 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -1025,6 +1025,10 @@ impl Build {
         self.rust_version()
     }
 
+    fn llvm_link_tools_dynamically(&self, target: Interned<String>) -> bool {
+        (target.contains("linux-gnu") || target.contains("apple-darwin"))
+    }
+
     /// Returns the `version` string associated with this compiler for Rust
     /// itself.
     ///
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 518fe95f3dd..c28b467df50 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -171,14 +171,10 @@ impl Step for Llvm {
 
         // This setting makes the LLVM tools link to the dynamic LLVM library,
         // which saves both memory during parallel links and overall disk space
-        // for the tools.  We don't distribute any of those tools, so this is
-        // just a local concern.  However, it doesn't work well everywhere.
-        //
-        // If we are shipping llvm tools then we statically link them LLVM
-        if (target.contains("linux-gnu") || target.contains("apple-darwin")) &&
-            !builder.config.llvm_tools_enabled &&
-            !want_lldb {
-                cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
+        // for the tools. We don't do this on every platform as it doesn't work
+        // equally well everywhere.
+        if builder.llvm_link_tools_dynamically(target) && !emscripten {
+            cfg.define("LLVM_LINK_LLVM_DYLIB", "ON");
         }
 
         // For distribution we want the LLVM tools to be *statically* linked to libstdc++