linker error when building rustc with clang+lld 21 and `-C linker-plugin-lto`
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Summary
Originally reported in https://bugs.gentoo.org/964380
Occurs starting from Rust 1.90.0. Everyone facing this error tries to build Rust 1.90.0 from sources, using Rust upstream binary to bootstrap it, on a system where:
- LLVM 21 is the default C toolchain, clang and lld used for building rustc.
- LTO is enabled globally by
RUSTFLAGS="${RUSTFLAGS} -C target-cpu=native -C linker-plugin-lto"system-wide.
Such combination used to work just fine for older versions of Rust.
Command used
RUST_BACKTRACE=1 ./x.py build -v --config=bootstrap.toml
Expected behaviour
I would expect the build to succeed.
I'm still trying to understand whether we could make rustc_driver_impl build with -C linker-plugin-lto, or whether it's impossible and we should conditionally strip out the flag for that part of the build.
For now, the issue can be worked around by temporarily setting RUSTFLAGS="${RUSTFLAGS} -C target-cpu=native" just for the moment of building rustc. However, I would like to avoid doing that, if possible. Enforcing LTO flags globally is a standard practice in Gentoo and used to work.
Actual behaviour
Running `CARGO=/usr/lib/rust/1.90.0/bin/cargo CARGO_BIN_NAME=rustc-main CARGO_CRATE_NAME=rustc_main CARGO_MANIFEST_DIR=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/compiler/rustc CARGO_MANIFEST_PATH=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/compiler/rustc/Cargo.toml CARGO_PKG_AUTHORS='' CARGO_PKG_DESCRIPTION='' CARGO_PKG_HOMEPAGE='' CARGO_PKG_LICENSE='' CARGO_PKG_LICENSE_FILE='' CARGO_PKG_NAME=rustc-main CARGO_PKG_README='' CARGO_PKG_REPOSITORY='' CARGO_PKG_RUST_VERSION='' CARGO_PKG_VERSION=0.0.0 CARGO_PKG_VERSION_MAJOR=0 CARGO_PKG_VERSION_MINOR=0 CARGO_PKG_VERSION_PATCH=0 CARGO_PKG_VERSION_PRE='' CARGO_PRIMARY_PACKAGE=1 CARGO_SBOM_PATH='' LD_LIBRARY_PATH=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/release/deps OUT_DIR=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/rustc-main-630efcf6209d93df/out /var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/bootstrap/debug/rustc /var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/bootstrap/debug/rustc --crate-name rustc_main --edition=2024 compiler/rustc/src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no --cfg 'feature="llvm"' --cfg 'feature="max_level_info"' --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("check_only", "jemalloc", "llvm", "max_level_info", "rustc_randomized_layouts"))' -C metadata=7a6468985b0b531f -C extra-filename=-bbfd9d6158d1a34d --out-dir /var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps --target x86_64-unknown-linux-musl -C linker=clang-21 -L dependency=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps -L dependency=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/release/deps --extern rustc_codegen_ssa=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_codegen_ssa-13d457041e1f2354.rlib --extern rustc_driver=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_driver-d2380b03692a4f0a.so --extern rustc_driver_impl=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_driver_impl-254b9ca3ac44ae12.rlib --extern rustc_public=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_public-57fa484b4e3c29ff.rlib --extern rustc_public_bridge=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_public_bridge-7d273d7c58e4934f.rlib -C target-cpu=native -C linker-plugin-lto -Lnative=/usr/lib/llvm/20/lib -C target-feature=-crt-static --cfg=windows_raw_dylib -Csymbol-mangling-version=v0 -Zunstable-options '--check-cfg=cfg(bootstrap)' '--check-cfg=cfg(llvm_enzyme)' -Zmacro-backtrace -Csplit-debuginfo=off -Ctarget-feature=-crt-static -Clink-args=-Wl,-z,origin '-Clink-args=-Wl,-rpath,$ORIGIN/../lib' -Clinker-features=+lld -Zunstable-options -Alinker-messages -Zon-broken-pipe=kill -Zdefault-visibility=protected -Zdylib-lto -Clto=thin -Cembed-bitcode=yes -Clink-args=-Wl,--icf=all -Z binary-dep-depinfo -L native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/psm-4c52a2a752ad411a/out -L native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/blake3-4b710a6cade225a4/out -L native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/blake3-4b710a6cade225a4/out -L native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/rustc_llvm-53d79c3d485dbcab/out -L native=/usr/lib/llvm/20/lib`
error: linking with `clang-21` failed: exit status: 1
|
= note: "clang-21" "-m64" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/temp/rustccUYUa9/symbols.o" "<1 object files omitted>" "-Wl,--as-needed" "-Wl,-Bdynamic" "<sysroot>-rustc/x86_64-unknown-linux-musl/release/deps/librustc_driver-d2380b03692a4f0a.so" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-*.rlib" "-Wl,-Bdynamic" "-lLLVM-20+libcxx" "-lc++" "-ldl" "-lunwind" "-lc" "-L" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/temp/rustccUYUa9/raw-dylibs" "-fuse-ld=lld" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-Wl,-plugin-opt=O3,-plugin-opt=mcpu=znver3" "-L" "/usr/lib/llvm/20/lib" "-L" "<sysroot>-rustc/x86_64-unknown-linux-musl/release/build/psm-4c52a2a752ad411a/out" "-L" "<sysroot>-rustc/x86_64-unknown-linux-musl/release/build/blake3-4b710a6cade225a4/out" "-L" "<sysroot>-rustc/x86_64-unknown-linux-musl/release/build/blake3-4b710a6cade225a4/out" "-L" "<sysroot>-rustc/x86_64-unknown-linux-musl/release/build/rustc_llvm-53d79c3d485dbcab/out" "-L" "/usr/lib/llvm/20/lib" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-musl/lib" "-o" "<sysroot>-rustc/x86_64-unknown-linux-musl/release/deps/rustc_main-bbfd9d6158d1a34d" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs" "-Wl,-z,origin" "-Wl,-rpath,$ORIGIN/../lib" "-Wl,--icf=all"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: ld.lld: error: undefined symbol: rustc_driver_impl::main
>>> referenced by rustc_main.e7d35cd2037fc768-cgu.0
>>> /var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/rustc_main-bbfd9d6158d1a34d.lto.rustc_main-bbfd9d6158d1a34d.rustc_main.e7d35cd2037fc768-cgu.0.rcgu.o:(rustc_main::main)
clang-21: error: linker command failed with exit code 1 (use -v to see invocation)
Did not run successfully: exit status: 1
LD_LIBRARY_PATH="/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1/lib:/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/release/deps" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1/bin/rustc" "--crate-name" "rustc_main" "--edition=2024" "compiler/rustc/src/main.rs" "--error-format=json" "--json=diagnostic-rendered-ansi,artifacts,future-incompat" "--crate-type" "bin" "--emit=dep-info,link" "-C" "opt-level=3" "-C" "embed-bitcode=no" "--cfg" "feature=\"llvm\"" "--cfg" "feature=\"max_level_info\"" "--check-cfg" "cfg(docsrs,test)" "--check-cfg" "cfg(feature, values(\"check_only\", \"jemalloc\", \"llvm\", \"max_level_info\", \"rustc_randomized_layouts\"))" "-C" "metadata=7a6468985b0b531f" "-C" "extra-filename=-bbfd9d6158d1a34d" "--out-dir" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps" "--target" "x86_64-unknown-linux-musl" "-C" "linker=clang-21" "-L" "dependency=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps" "-L" "dependency=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/release/deps" "--extern" "rustc_codegen_ssa=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_codegen_ssa-13d457041e1f2354.rlib" "--extern" "rustc_driver=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_driver-d2380b03692a4f0a.so" "--extern" "rustc_driver_impl=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_driver_impl-254b9ca3ac44ae12.rlib" "--extern" "rustc_public=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_public-57fa484b4e3c29ff.rlib" "--extern" "rustc_public_bridge=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/deps/librustc_public_bridge-7d273d7c58e4934f.rlib" "-C" "target-cpu=native" "-C" "linker-plugin-lto" "-Lnative=/usr/lib/llvm/20/lib" "-C" "target-feature=-crt-static" "--cfg=windows_raw_dylib" "-Csymbol-mangling-version=v0" "-Zunstable-options" "--check-cfg=cfg(bootstrap)" "--check-cfg=cfg(llvm_enzyme)" "-Zmacro-backtrace" "-Csplit-debuginfo=off" "-Ctarget-feature=-crt-static" "-Clink-args=-Wl,-z,origin" "-Clink-args=-Wl,-rpath,$ORIGIN/../lib" "-Clinker-features=+lld" "-Zunstable-options" "-Alinker-messages" "-Zon-broken-pipe=kill" "-Zdefault-visibility=protected" "-Zdylib-lto" "-Clto=thin" "-Cembed-bitcode=yes" "-Clink-args=-Wl,--icf=all" "-Z" "binary-dep-depinfo" "-L" "native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/psm-4c52a2a752ad411a/out" "-L" "native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/blake3-4b710a6cade225a4/out" "-L" "native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/blake3-4b710a6cade225a4/out" "-L" "native=/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1-rustc/x86_64-unknown-linux-musl/release/build/rustc_llvm-53d79c3d485dbcab/out" "-L" "native=/usr/lib/llvm/20/lib" "-Wrust_2018_idioms" "-Wunused_lifetimes" "-Dwarnings" "-Wrustc::internal" "-Drustc::symbol_intern_string_literal" "-Wkeyword_idents_2024" "-Wunreachable_pub" "-Wunsafe_op_in_unsafe_fn" "-Wunused_crate_dependencies" "--sysroot" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/build/x86_64-unknown-linux-musl/stage1" "-Ztls-model=initial-exec" "--remap-path-prefix" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src=/rustc-dev/1159e78c4747b02ef996e55082b704c09b970588" "--remap-path-prefix" "/var/tmp/portage/dev-lang/rust-1.90.0-r1/work/rustc-1.90.0-src/vendor=/rust/deps" "-Z" "force-unstable-if-unmarked"
Full log attached at the end.
Bootstrap configuration (bootstrap.toml)
change-id = "ignore"
profile = "dist"
[llvm]
download-ci-llvm = false
optimize = true
release-debuginfo = false
assertions = false
ninja = true
targets = "ARM;BPF;RISCV;WebAssembly;X86"
experimental-targets = ""
link-shared = true
use-libcxx = true
static-libstdcpp = false
enable-warnings = false
[llvm.build-config]
CMAKE_VERBOSE_MAKEFILE = "ON"
CMAKE_C_FLAGS_RELEASE = "-O2 -pipe -march=native -Werror=odr -Werror=strict-aliasing"
CMAKE_CXX_FLAGS_RELEASE = "-O2 -pipe -march=native -Werror=odr -Werror=strict-aliasing"
CMAKE_EXE_LINKER_FLAGS_RELEASE = "-Wl,-O1 -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,--as-needed"
CMAKE_MODULE_LINKER_FLAGS_RELEASE = "-Wl,-O1 -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,--as-needed"
CMAKE_SHARED_LINKER_FLAGS_RELEASE = "-Wl,-O1 -Wl,--as-needed -Wl,-z,pack-relative-relocs -Wl,--as-needed"
CMAKE_STATIC_LINKER_FLAGS_RELEASE = ""
[build]
build-stage = 2
test-stage = 2
build = "x86_64-unknown-linux-musl"
host = ["x86_64-unknown-linux-musl"]
target = ["x86_64-unknown-linux-musl","bpfeb-unknown-none","bpfel-unknown-none","wasm32-unknown-unknown"]
cargo = "/usr/lib/rust/1.90.0/bin/cargo"
rustc = "/usr/lib/rust/1.90.0/bin/rustc"
rustfmt = "/usr/lib/rust/1.90.0/bin/rustfmt"
description = "gentoo"
docs = false
compiler-docs = false
submodules = false
python = "python3.14"
locked-deps = true
vendor = true
extended = true
tools = ["cargo","rustdoc","clippy","rustfmt","src"]
verbose = 2
sanitizers = false
profiler = true
cargo-native-static = false
[install]
prefix = "/usr/lib/rust/1.90.0"
sysconfdir = "etc"
docdir = "share/doc/rust"
bindir = "bin"
libdir = "lib"
mandir = "share/man"
[rust]
# https://github.com/rust-lang/rust/issues/54872
codegen-units-std = 1
optimize = true
debug = false
debug-assertions = false
debug-assertions-std = false
debuginfo-level = 0
debuginfo-level-rustc = 0
debuginfo-level-std = 0
debuginfo-level-tools = 0
debuginfo-level-tests = 0
backtrace = true
incremental = false
default-linker = "x86_64-pc-linux-musl-cc"
channel = "stable"
rpath = true
verbose-tests = true
optimize-tests = true
codegen-tests = true
omit-git-hash = false
dist-src = false
remap-debuginfo = true
lld = false
use-lld = true
# only deny warnings if doc+wasm are NOT requested, documenting stage0 wasm std fails without it
# https://github.com/rust-lang/rust/issues/74976
# https://github.com/rust-lang/rust/issues/76526
deny-warnings = true
backtrace-on-ice = true
jemalloc = false
# See https://github.com/rust-lang/rust/issues/121124
lto = "thin"
[dist]
src-tarball = false
compression-formats = ["xz"]
compression-profile = "balanced"
[target.x86_64-unknown-linux-musl]
ar = "/usr/lib/llvm/21/bin/llvm-ar"
cc = "clang-21"
cxx = "clang++-21"
linker = "clang-21"
ranlib = "/usr/lib/llvm/21/bin/llvm-ranlib"
llvm-libunwind = "system"
llvm-config = "/usr/lib/llvm/20/bin/llvm-config"
crt-static = false
musl-root = "/usr"
[target.wasm32-unknown-unknown]
linker = "lld"
# wasm target does not have profiler_builtins https://bugs.gentoo.org/848483
profiler = false
Operating system
Gentoo Linux, musl-llvm profile
HEAD
starting from 1.90.0. 1159e78c4747b02ef996e55082b704c09b970588
Additional context
I applied https://github.com/rust-lang/rust/pull/144997/commits/351e4bd1066a9d89b4d9f06c628ba0733c1850b5 as a patch to be able to bootstrap 1.90.0 with 1.90.0
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with x.py and bootstrap.toml using clang/lld 21 and global -C linker-plugin-lto. Inspect compiler/rustc/src/main.rs and the rustc_driver_impl build path to determine where the undefined rustc_driver_impl::main symbol is introduced. Done means the documented configuration builds successfully, or the affected build step conditionally handles the flag with coverage for the chosen behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100