From 40874a97d27801f91f7ebcd16a0a509a57196c56 Mon Sep 17 00:00:00 2001 From: sgasho Date: Sun, 5 Apr 2026 14:27:11 +0900 Subject: [PATCH 1/2] Link LLVM dynamically on aarch64-apple-darwin --- compiler/rustc_llvm/build.rs | 10 ++++++++++ compiler/rustc_metadata/src/native_libs.rs | 10 +++++++--- src/ci/github-actions/jobs.yml | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 38c16fb1cd6d5..66b3e266a22fe 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -402,6 +402,16 @@ fn main() { continue; } + // On apple-darwin, llvm-config reports the versioned shared library name such as LLVM-22-..., but + // the distributed toolchain ships libLLVM.dylib. Normalize the link name here. + let name = + if target.contains("apple-darwin") && llvm_kind == "dylib" && name.starts_with("LLVM-") + { + "LLVM" + } else { + name + }; + let kind = if name.starts_with("LLVM") { llvm_kind } else if is_static { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index a05366d7147b9..06755a0ccf166 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -62,12 +62,15 @@ pub fn walk_native_lib_search_dirs( f(&sess.target_tlib_path.dir.join("self-contained"), false)?; } + let has_shared_llvm_apple_darwin = + sess.target.is_like_darwin && sess.target_tlib_path.dir.join("libLLVM.dylib").exists(); + // Toolchains for some targets may ship `libunwind.a`, but place it into the main sysroot // library directory instead of the self-contained directories. // Sanitizer libraries have the same issue and are also linked by name on Apple targets. // The targets here should be in sync with `copy_third_party_objects` in bootstrap. - // Finally there is shared LLVM library, which unlike compiler libraries, is linked by the name, - // therefore requiring the search path for the linker. + // On Apple targets, shared LLVM is linked by name, so when `libLLVM.dylib` is + // present in the target libdir, add that directory to the linker search path. // FIXME: implement `-Clink-self-contained=+/-unwind,+/-sanitizers`, move the shipped libunwind // and sanitizers to self-contained directory, and stop adding this search path. // FIXME: On AIX this also has the side-effect of making the list of library search paths @@ -77,7 +80,8 @@ pub fn walk_native_lib_search_dirs( || sess.target.os == Os::Linux || sess.target.os == Os::Fuchsia || sess.target.is_like_aix - || sess.target.is_like_darwin && !sess.sanitizers().is_empty() + || sess.target.is_like_darwin + && (!sess.sanitizers().is_empty() || has_shared_llvm_apple_darwin) || sess.target.os == Os::Windows && sess.target.env == Env::Gnu && sess.target.cfg_abi == CfgAbi::Llvm diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 7c0f1d3f29305..bff0046c97cb4 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -518,6 +518,7 @@ auto: --enable-sanitizers --enable-profiler --set rust.jemalloc + --set llvm.link-shared=true --set rust.lto=thin --set rust.codegen-units=1 # Aarch64 tooling only needs to support macOS 11.0 and up as nothing else From fcad99572f75d6ab762c5b7fb9e266ac76824d91 Mon Sep 17 00:00:00 2001 From: sgasho Date: Wed, 8 Apr 2026 22:39:08 +0900 Subject: [PATCH 2/2] Copy libLLVM with a versioned name --- src/bootstrap/download-ci-llvm-stamp | 2 +- src/bootstrap/src/core/build_steps/dist.rs | 19 ++++++++++++++++ src/bootstrap/src/core/build_steps/llvm.rs | 26 +++++++++++++--------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp index dd68964b75686..f6b2e50fe38ab 100644 --- a/src/bootstrap/download-ci-llvm-stamp +++ b/src/bootstrap/download-ci-llvm-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-llvm` configuration download a new version of LLVM from CI, even if the LLVM submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/154485 +Last change is for: test diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 28a7afd6c61a6..88b052216994d 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2495,6 +2495,25 @@ fn maybe_install_llvm( let llvm_dylib_path = src_libdir.join("libLLVM.dylib"); if llvm_dylib_path.exists() { builder.install(&llvm_dylib_path, dst_libdir, FileType::NativeLibrary); + + if install_symlink && let Some(llvm_config) = builder.llvm_config(target) { + let major = llvm::get_llvm_version_major(builder, &llvm_config); + let llvm_version_suffix = llvm::get_llvm_version_suffix(builder); + match llvm_version_suffix { + Some(suffix) => { + t!(fs::copy( + dst_libdir.join("libLLVM.dylib"), + dst_libdir.join(format!("libLLVM-{major}{suffix}.dylib")) + )); + } + None => { + t!(fs::copy( + dst_libdir.join("libLLVM.dylib"), + dst_libdir.join(format!("libLLVM-{major}.dylib")) + )); + } + } + }; } !builder.config.dry_run() } else if let llvm::LlvmBuildStatus::AlreadyBuilt(llvm::LlvmResult { diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index a2cf801afa11a..388eb3eaa3591 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -524,17 +524,7 @@ impl Step for Llvm { } } - let llvm_version_suffix = if let Some(ref suffix) = builder.config.llvm_version_suffix { - // Allow version-suffix="" to not define a version suffix at all. - if !suffix.is_empty() { Some(suffix.to_string()) } else { None } - } else if builder.config.channel == "dev" { - // Changes to a version suffix require a complete rebuild of the LLVM. - // To avoid rebuilds during a time of version bump, don't include rustc - // release number on the dev channel. - Some("-rust-dev".to_string()) - } else { - Some(format!("-rust-{}-{}", builder.version, builder.config.channel)) - }; + let llvm_version_suffix = get_llvm_version_suffix(builder); if let Some(ref suffix) = llvm_version_suffix { cfg.define("LLVM_VERSION_SUFFIX", suffix); } @@ -623,6 +613,20 @@ pub fn get_llvm_version_major(builder: &Builder<'_>, llvm_config: &Path) -> u8 { major_str.parse().unwrap() } +pub fn get_llvm_version_suffix(builder: &Builder<'_>) -> Option { + if let Some(ref suffix) = builder.config.llvm_version_suffix { + // Allow version-suffix="" to not define a version suffix at all. + if !suffix.is_empty() { Some(suffix.to_string()) } else { None } + } else if builder.config.channel == "dev" { + // Changes to a version suffix require a complete rebuild of the LLVM. + // To avoid rebuilds during a time of version bump, don't include rustc + // release number on the dev channel. + Some("-rust-dev".to_string()) + } else { + Some(format!("-rust-{}-{}", builder.version, builder.config.channel)) + } +} + fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { if builder.config.dry_run() { return;