Skip to content

rust-lld on aarch64-apple-darwin cannot load libLLVM.dylib when the toolchain rustc is invoked directly (1.99.0, regression from 1.96.1) #163947

Closed

Description

@jasonf20

On aarch64-apple-darwin, rust-lld from the 1.99.0 stable toolchain aborts at load time when the toolchain's rustc is run directly rather than through the rustup proxy, so linking a wasm32-unknown-unknown cdylib fails. Through the proxy (rustc +1.99) it links, presumably because rustup adds the toolchain's lib/ to the dylib search path. The same direct invocation works on 1.96.1 (macOS) and on 1.99.0 (aarch64 Linux). Tools that ship or pin a sysroot and invoke <sysroot>/bin/rustc by path hit this.

Reproduction

rustup toolchain install 1.99 --profile minimal --target wasm32-unknown-unknown
echo '#[unsafe(no_mangle)] pub extern "C" fn f() -> i32 { 1 }' > lib.rs
"$(rustc +1.99 --print sysroot)/bin/rustc" --crate-type=cdylib --target=wasm32-unknown-unknown lib.rs

Output

error: linking with `rust-lld` failed: signal: 6 (SIGABRT)
  = note: dyld[5821]: Library not loaded: @rpath/libLLVM.dylib
            Referenced from: ~/.rustup/toolchains/1.99-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/bin/rust-lld
            Reason: tried: '~/.rustup/toolchains/1.99-aarch64-apple-darwin/lib/rustlib/aarch64-apple-darwin/bin/../lib/libLLVM.dylib' (no such file), '/Users/runner/work/rust/rust/build/aarch64-apple-darwin/llvm/lib/libLLVM.dylib' (no such file), ...

Cause

Since #157205 (link LLVM dynamically on aarch64-apple-darwin), rust-lld loads @rpath/libLLVM.dylib:

$ otool -L .../lib/rustlib/aarch64-apple-darwin/bin/rust-lld
	@rpath/libLLVM.dylib (compatibility version 1.0.0, current version 23.1.1)
$ otool -l .../lib/rustlib/aarch64-apple-darwin/bin/rust-lld | grep -A2 LC_RPATH
         path @loader_path/../lib
         path /Users/runner/work/rust/rust/build/aarch64-apple-darwin/llvm/lib

@loader_path/../lib resolves to lib/rustlib/aarch64-apple-darwin/lib/, but the toolchain ships the dylib at the top-level lib/libLLVM.dylib. On Linux the equivalent rpath is $ORIGIN/../../../, which finds lib/libLLVM.so.*. On 1.96.1, macOS rust-lld had no libLLVM dependency at all.

Workaround

ln -s ../../../libLLVM.dylib "$(rustc +1.99 --print sysroot)/lib/rustlib/aarch64-apple-darwin/lib/libLLVM.dylib"

Meta

rustc +1.99 --version --verbose:

rustc 1.99.0 (b940084d7 2026-09-28)
host: aarch64-apple-darwin

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Oct 7, 2026
  2. maxdexh commented on Oct 7, 2026

    @maxdexh
    Member

    @rustbot transfer rust-lang/rustup

  3. transferred this issue fromrust-lang/ruston Oct 7, 2026
  4. rami3l commented on Oct 7, 2026

    @rami3l
    Member

    @maxdexh Sorry, but why transferring this issue to rustup? If this is an issue with the artifacts being generated (say the linking has a problem), rather than their means of distribution, then this is a r-l/r CD problem and I believe there is nothing we can do in r-l/rustup the repo 🤔

    That said I'd love to follow the diagnosis over there.

  5. rami3l commented on Oct 7, 2026

    @rami3l
    Member

    I've found a related issue (nix-community/fenix#253) and it seems that rustup happens to have covered up the defect, rather than rustup having the defect itself:

    rust-lang/rust#157205 (merged 2026-06-01, first stable release 1.98.0) enables llvm.link-shared=true for dist-aarch64-apple. rust-lld/rust-objcopy now link @rpath/libLLVM.dylib with rpath @loader_path/../lib, i.e. they expect lib/rustlib/<host>/lib/libLLVM.dylib. The rustc tarball only ships lib/libLLVM.dylib; the rustlib/<host>/lib copy is only produced by the llvm-tools dist step (maybe_install_llvm_target in src/bootstrap/src/core/build_steps/dist.rs).

    rustup users don't see this because rustup's proxies prepend <toolchain>/lib to DYLD_FALLBACK_LIBRARY_PATH for every invoked tool (Toolchain::set_ldpath). fenix runs upstream install.sh and provides no such shim, and the rust-mixed symlink layout doesn't help since @loader_path resolves to the real path inside the rustc store path.

    Given that, I still think r-l/r is the right place to hold this issue.

    @rustbot transfer rust-lang/rust

  6. transferred this issue fromrust-lang/rustupon Oct 7, 2026
  7. rami3l commented on Oct 7, 2026

    @rami3l
    Member

    Since the scope of my work includes toolchain distribution in general rather than just rustup, I'd love to dive further into this issue here.

  8. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Oct 7, 2026
  9. maxdexh commented on Oct 7, 2026

    @maxdexh
    Member

    yeah i misread the issue as saying it only works when calling the compiler directly, which would have made this an obvious rustup issue. The way it is, idk where the issue is

  10. added
    A-lldArea: Linkage issues specific to rust-lld
    C-bugCategory: This is a bug.
    on Oct 7, 2026
  11. rami3l commented on Oct 7, 2026

    @rami3l
    Member

    I looked more into it. On Linux we have this tweak specifically for libLLVM I believe:

    if builder.config.rpath_enabled(target)
    && helpers::use_host_linker(target)
    && llvm_output.link_shared()
    && target.contains("linux")
    {
    // So we inform LLD where it can find LLVM's libraries by adding an rpath entry to the
    // expected parent `lib` directory.
    //
    // Be careful when changing this path, we need to ensure it's quoted or escaped:
    // `$ORIGIN` would otherwise be expanded when the `LdFlags` are passed verbatim to
    // cmake.
    ldflags.push_all("-Wl,-rpath,'$ORIGIN/../../../'");
    }

    ... but somehow #157205 didn't mirror it.

    I am new to this part of bootstrap, but I'd like to attempt a fix by mirroring that on darwin.

    @rustbot claim

  12. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Oct 7, 2026
  13. 3 remaining items

  14. removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Oct 8, 2026
  15. rustbot commented on Oct 8, 2026

    @rustbot
    Collaborator

    Assigning P-critical (discussion on Zulip).

  16. apiraino commented on Oct 8, 2026

    @apiraino
    Contributor

    cc @sgasho since author of #157205

  17. sgasho commented on Oct 8, 2026

    @sgasho
    Contributor

    Thanks for the ping, and sorry for missing this in #157205.

    When I enabled llvm.link-shared for dist-aarch64-apple, I didn't realize that the Linux-only rpath tweak in Lld::run also needed to be mirrored for darwin, so it was simply left out.

    The fix in #163954 looks correct to me, thanks!

  18. added 6 commits that reference this issue on Oct 9, 2026
  19. added 2 commits that reference this issue on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-lldArea: Linkage issues specific to rust-lldC-bugCategory: This is a bug.P-criticalCritical priorityT-bootstrapRelevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions