SIGN IN SIGN UP
rust-lang / rust UNCLAIMED

Empowering everyone to build reliable and efficient software.

0 0 124 Rust

Auto merge of #157205 - sgasho:link_llvm_dynamically_on_mac, r=ZuseZ4

Link LLVM dynamically on aarch64-apple-darwin

--set llvm.link-shared=true on dist-aarch64-apple to link LLVM dynamically on MacOS. 
Also, I fixed some link problems, by normalizing the libLLVM.dylib name, and creating a symlink(On Linux, we use linker script, but we can not use it for MacOS. ld64 does not recognize linker scripts) from versioned dylib to unversioned libLLVM.dylib to build successfully.

## How I verified on my Mac

1. remove the old build dir

```shell
rm -rf build/
```

2. configure for rust-dev dist

```shell
./configure \
    --set llvm.download-ci-llvm=false \
    --set llvm.link-shared=true \
    --release-channel=nightly
```

3. dist

```shell
./x dist rust-dev --host=aarch64-apple-darwin --target=aarch64-apple-darwin
```

4. move tarball to /tmp(or, wherever else except for inside build/) and delete the current build dir

We create build/ for both rust-dev dist, and local build tests. Once dist finished, we have to clear the directory so we can use it for build tests

```shell
cp build/dist/rust-dev-nightly-aarch64-apple-darwin.tar.xz /tmp/

rm -rf build
```

I saw a symlink created as expected

<img width="652" height="406" alt="rust-dev artifacts" src="https://github.com/user-attachments/assets/dc49a637-8a1f-45c8-84f2-2ef101faae51" />


6. modify download.rs temporary so it gets the locally built tarball at step3

```rust
    #[cfg(not(test))]
    fn download_ci_llvm(&self, _llvm_sha: &str) {
        let tarball = PathBuf::from("/tmp/rust-dev-nightly-aarch64-apple-darwin.tar.xz");
        let llvm_root = self.ci_llvm_root();
        self.unpack(&tarball, &llvm_root, "rust-dev");
    //     let llvm_assertions = self.llvm_assertions;

    //     let cache_prefix = format!("llvm-{llvm_sha}-{llvm_assertions}");
    //     let cache_dst =
    //         self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache"));

    //     let rustc_cache = cache_dst.join(cache_prefix);
    //     if !rustc_cache.exists() {
    //         t!(fs::create_dir_all(&rustc_cache));
    //     }
    //     let base = if llvm_assertions {
    //         &self.stage0_metadata.config.artifacts_with_llvm_assertions_server
    //     } else {
    //         &self.stage0_metadata.config.artifacts_server
    //     };
    //     let version = self.artifact_version_part(llvm_sha);
    //     let filename = format!("rust-dev-{}-{}.tar.xz", version, self.host_target.triple);
    //     let tarball = rustc_cache.join(&filename);
    //     if !tarball.exists() {
    //         let help_on_error = "ERROR: failed to download llvm from ci

    // HELP: There could be two reasons behind this:
    //     1) The host triple is not supported for `download-ci-llvm`.
    //     2) Old builds get deleted after a certain time.
    // HELP: In either case, disable `download-ci-llvm` in your bootstrap.toml:

    // [llvm]
    // download-ci-llvm = false
    // ";
    //         self.download_file(&format!("{base}/{llvm_sha}/{filename}"), &tarball, help_on_error);
    //     }
    //     let llvm_root = self.ci_llvm_root();
    //     self.unpack(&tarball, &llvm_root, "rust-dev");
    }
```

7. configure for ./x build

```shell
rm -rf bootstrap.toml // delete existing config of rust-dev dist

// maybe we don't need to specify llvm.download-ci-llvm=true, since I bumped download-ci-llvm-stamp.
// but anyway, I explicitly specified it when I tested it

./configure \
    --set llvm.download-ci-llvm=true \
    --set llvm.link-shared=true \
    --release-channel=nightly
```

8. ./x build

```shell
./x build (library)
```

Result: build completed successfully

<img width="861" height="763" alt="スクリーンショット 2026-06-01 0 38 21" src="https://github.com/user-attachments/assets/9660ac43-c275-4174-b80a-3483b4acfd40" />

r? @Kobzol 

cc: @ZuseZ4
B
bors committed
bef8e620f19adbfd1530e916ab8caa296ef9c3ee