From 3501f4aea596ecbc456c1c38751fc791fe3c866e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 4 Mar 2024 09:28:04 +0100 Subject: [PATCH] Replace libLLVM symlink with linker script It turns out that the libLLVM-N.so -> libLLVM.so.N.1 symlink is also needed when projects like miri link against librustc_driver.so. As such, we have to distribute it in real rustup components like rustc-dev, rather than only for download-ci-llvm. To avoid actually distributing symlinks (which are not supported or not fully supported by the rustup infrastructure) replace it with a linker script that does the same thing instead. --- src/bootstrap/src/core/build_steps/dist.rs | 38 +++++++++------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 067dede904f12..407694275c6ab 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2021,12 +2021,7 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) { } } -fn install_llvm_file( - builder: &Builder<'_>, - source: &Path, - destination: &Path, - install_symlink: bool, -) { +fn install_llvm_file(builder: &Builder<'_>, source: &Path, destination: &Path) { if builder.config.dry_run() { return; } @@ -2035,11 +2030,15 @@ fn install_llvm_file( // If we have a symlink like libLLVM-18.so -> libLLVM.so.18.1, install the target of the // symlink, which is what will actually get loaded at runtime. builder.install(&t!(fs::canonicalize(source)), destination, 0o644); - if install_symlink { - // If requested, also install the symlink. This is used by download-ci-llvm. - let full_dest = destination.join(source.file_name().unwrap()); - builder.copy(&source, &full_dest); - } + + // Replace the symlink itself with an equivalent linker script. This is used by + // download-ci-llvm and projects linking against librustc_driver.so. We don't use a + // symlink, as these are not allowed inside rustup components. + let link = t!(fs::read_link(source)); + t!(std::fs::write( + destination.join(source.file_name().unwrap()), + format!("INPUT({})", link.display()) + )); } else { builder.install(&source, destination, 0o644); } @@ -2048,12 +2047,7 @@ fn install_llvm_file( /// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking. /// /// Returns whether the files were actually copied. -fn maybe_install_llvm( - builder: &Builder<'_>, - target: TargetSelection, - dst_libdir: &Path, - install_symlink: bool, -) -> bool { +fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool { // If the LLVM was externally provided, then we don't currently copy // artifacts into the sysroot. This is not necessarily the right // choice (in particular, it will require the LLVM dylib to be in @@ -2102,7 +2096,7 @@ fn maybe_install_llvm( } else { PathBuf::from(file) }; - install_llvm_file(builder, &file, dst_libdir, install_symlink); + install_llvm_file(builder, &file, dst_libdir); } !builder.config.dry_run() } else { @@ -2117,7 +2111,7 @@ pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, // dynamically linked; it is already included into librustc_llvm // statically. if builder.llvm_link_shared() { - maybe_install_llvm(builder, target, &dst_libdir, false); + maybe_install_llvm(builder, target, &dst_libdir); } } @@ -2129,7 +2123,7 @@ pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection // dynamically linked; it is already included into librustc_llvm // statically. if builder.llvm_link_shared() { - maybe_install_llvm(builder, target, &dst_libdir, false); + maybe_install_llvm(builder, target, &dst_libdir); } } @@ -2224,8 +2218,6 @@ impl Step for RustDev { let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); tarball.set_overlay(OverlayKind::LLVM); - // LLVM requires a shared object symlink to exist on some platforms. - tarball.permit_symlinks(true); builder.ensure(crate::core::build_steps::llvm::Llvm { target }); @@ -2266,7 +2258,7 @@ impl Step for RustDev { // of `rustc-dev` to support the inherited `-lLLVM` when using the // compiler libraries. let dst_libdir = tarball.image_dir().join("lib"); - maybe_install_llvm(builder, target, &dst_libdir, true); + maybe_install_llvm(builder, target, &dst_libdir); let link_type = if builder.llvm_link_shared() { "dynamic" } else { "static" }; t!(std::fs::write(tarball.image_dir().join("link-type.txt"), link_type), dst_libdir);