diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6e473fae3be5c..c6ff63ad71b80 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, + 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 97b05059c88d1..b6a89e1c18fab 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) -> 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 518fe95f3ddd8..c28b467df5093 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++