-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustc can't find the linker when --sysroot
is set to a local build of the sysroot
#125246
Comments
Yes. The blog post has a summary of that PR https://blog.rust-lang.org/2024/05/17/enabling-rust-lld-on-linux.html |
That blog post doesn't mention the term "sysroot" so it doesn't help with my issue. |
FWIW what I would have expected is that rustc searches for the linker binary somewhere around |
How do you handle windows-gnu? Imo this also uses a self-contained linker by default. |
No idea. CI passes on Windows, whatever github gives us when we say |
Yeah the rust-lld linker has been in the sysroot since #85961, is used by default in e.g. some of the wasm and aarch64 targets, and rustc had flags to opt-into using it since that PR. What is new is that it is now used by bootstrap puts it in the sysroot when |
We resolve the sysroot from rustc driver, not current executable. |
Yes, the surprise is just that the linker is searched in the sysroot and thus affected by --sysroot, rather than being searched directly.
But I guess this is working as intended, I just need to add some more stuff to these custom sysroots then.
|
This broke cargo's CI since the build-std tests try to verify that nothing in the sysroot is required. Would it be possible to change it so that it will only require rust-lld if it exists in the sysroot (similar to windows-gnu and other targets)? |
Temporarily fix standard_lib tests on linux. This fixes the standard_lib tests which are broken in the latest nightly. The latest nightly now requires rust-lld to be in the sysroot for x86_64-unknown-linux-gnu. This broke these tests which were trying to verify that the standard library is not required. This temporarily removes this validation, but we should have some way of enforcing it (rust-lang/wg-cargo-std-aware#31). cc rust-lang/rust#125246
I don't know what we do on windows-gnu but we can do something similar, yes. I'll open a PR. |
FWIW I managed to add tests for windows-gnu and they work like a charm. So no copying of files seems to be required there. |
We actually hit a binutils linker bug last week on windows-gnu (not windows-gnullvm), and the linker flavor there is gnu-cc, so do these targets really use rust-lld by default? |
How does this work with cross-compilation -- I assume we are always taking the host sysroot even when building for another target? To me that seems like a sign that this shouldn't be part of the sysroot, it should be part of the rustc distribution. The sysroot is for target-related things. |
In particular, I would expect that if I set |
They do use a self-contained linker from sysroot by default, but not rust-lld. |
Thanks for the clarification. That explains why there's no existence check (and your 2nd hack for older GCCs in that other issue :). Locally, it was just using mingw's ld probably because of $PATH differences. |
Linkers are generally target-dependent, so it's pretty reasonable to ship them in target sysroot, I guess. Also there's no target vs host separation for sysroot in rustc right now, there's just one sysroot. |
I still hope to migrate both rust-lld and mingw linker to the common directory layout scheme based on |
If I'm on macOS and want to build for a Linux target, then the Given that these are binaries that need to be run on the host (i.e. the machine where the build happens), IMO the only sensible location is together with the other host stuff, i.e., where |
Ah I think I understand.
That's right, and on macOS we wouldn't look for You can try this locally on a helloworld (look for the path to $ RUSTC_LOG=rustc_codegen_ssa::back::link RUSTFLAGS="-Clink-self-contained=+linker -Zunstable-options -Zlinker-features=+lld" cargo build --target=x86_64-unknown-linux-musl
(...a big linker command with the following of interest:)
"-B/home/lqd/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld" "-fuse-ld=lld" ...
"-L" "/home/lqd/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-musl/lib" ...
"-o" "./target/x86_64-unknown-linux-musl/debug/deps/helloworld-e346cf08cdc1bbb0"
$ readelf -p .comment target/x86_64-unknown-linux-musl/debug/helloworld
String dump of section '.comment':
[ 0] Linker: LLD 18.1.6
[ 14] rustc version 1.80.0-nightly (b92758a9a 2024-05-20)
[ 48] GCC: (GNU) 9.4.0 |
Oh, so we always assume that But the fallback in your PR should solve that as well, I think. |
Rollup merge of rust-lang#125263 - lqd:lld-fallback, r=petrochenkov rust-lld: fallback to rustc's sysroot if there's no path to the linker in the target sysroot As seen in rust-lang#125246, some sysroots don't expect to contain `rust-lld` and want to keep it that way, so we fallback to the default rustc sysroot if there is no path to the linker in any of the sysroot tools search paths. This is how we locate codegen-backends' dylibs already. People also have requested an error if none of these search paths contain the self-contained linker directory, so there's also an error in that case. r? `@petrochenkov` cc `@ehuss` `@RalfJung` I'm not sure where we check for `rust-lld`'s existence on the targets where we use it by default, and if we just ignore it when missing or emit a warning (as I assume we don't emit an error), so I just checked for the existence of `gcc-ld`, where `cc` will look for the lld-wrapper binaries. <sub>*Feel free to point out better ways to do this, it's the middle of the night here.*</sub> Fixes rust-lang#125246
This is a recent regression, starting with #124129: when
--sysroot
is set, in my case to/home/r/.cache/cargo-careful
where I have prepared a locally built sysroot (that's https://github.com/RalfJung/cargo-careful), then rustc now assumes it can find the linker in the sysroot, which does not work. See RalfJung/cargo-careful#31 for some more details.It is new to me that the sysroot is supposed to contain the linker as well, is that expected behavior?
Also the error message in that case is really unhelpful.^^
Maybe rustc should check that the path it sets for
-B
actually exists before startingcc
?The text was updated successfully, but these errors were encountered: