-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Cross compilation fails on Rust nightly when using proc macro crates due to GCC not understanding -fuse-ld=lld
#125330
Comments
Also reported as cross-rs/cross#1496 but it seems to me that it is a rust regression that rust tries to use a gcc option when the installed GCC version is too old to support said option. |
I agree that this is a regression. Our tier 1 targets support GLIBC 2.17+ which dates back to 2012 but -fuse-ld=lld in gcc was merged in 2018. While we do not explicitly declare support for any gcc or distro version, GLIBC 2.17+ is generally interpreted as RHEL/CentOS 7. Unfortunately, the platforms that the toolchain can run on often constrains what platforms can be targeted. We currently do not provide a mechanism to target GLIBC versions older than the host. So I do not think it is not a big stretch to argue that passing - |
@saethlin The double negation is hurting my brain, what do you actually mean here? |
I mean that the new behavior violates of the spirit of the target tier policy, but not the very precise guarantees we document. |
I had expected us to have a gcc version check already, especially since our dist i686/x64 linux CI builders are based on CentOS 7, but it seems the original I'll look into adding the version check. |
Hmm, it seems
Maybe we need to reassess both of these and discuss more broadly, and/or document more precisely what we intend to rely on in the target support documentation, and/or more easily offer feature detection for users where these cases are important. The latter could be a workflow like the following, where users want to dynamically opt-out of using lld:
That would allow for users supporting multiple versions of the compiler and multiple versions of GCC if they need to. cc @petrochenkov what do you think? |
My use case is building in CI, both for testing and for distributable binaries. I don't run old distros myself (I run Arch, which is rolling release). I just rely on Now I would say that "building portable binaries for distribution" is an important use case for Rust. Any binary crate that is not targeted at rust developers might want to do this. I don't expect my users to have a rust toolchain (or any toolchain at all) installed. So asking them to use Because of the unfortunate situation on Linux with glibc backward compatibility, the only reasonable way to do this is to build on an old distro (since glibc makes sure the sure the binary is forwards compatible, but not the reverse). I believe this is a use case that needs to work. I don't particularly care about how it is made to work. Maybe rust can just bypass cc and call lld directly for example. |
WG-prioritization assigning priority (Zulip discussion). @rustbot label -I-prioritize +P-high |
On re-read it looks like in #97402 we largely assumed that LLD is enabled explicitly somehow. In that case it's quite reasonable to not support LLD on systems where GCC doesn't support it, because that's a quite small version window (between the appearance of functioning LLD and -fuse-ld=lld support in GCC). But now LLD is enabled implicitly in rustc and that increases the unsupported version window significantly (now it's from around 2012 to around 2018). |
One possible solution is a hack similar to fallback for unsupported rust/compiler/rustc_codegen_ssa/src/back/link.rs Lines 780 to 861 in f0038a7
If linker execution fails, we check its output and rerun it again after removing unsupported options. |
I'll look into doing that, it seems preferable to doing the version detection on the happy path that I was working on. |
Another possible solution is to keep a fifth copy of lld-wrapper with a name Line 75 in f0038a7
Then we won't have to pass -fuse-ld=lld at all, only -B , at least in the self-contained case.This doesn't solve the problem in the non-self-contained mode though. Also self-contained lld-named-ld will conflict with self-contained real-ld on targets where both are shipped (like windows-gnu). Let's try the linker rerun hack first, I think. |
self-contained linker: retry linking without `-fuse-ld=lld` on CCs that don't support it For the self-contained linker, this PR applies [the strategy](rust-lang#125330 (comment)) of retrying the linking step when the driver doesn't support `-fuse-ld=lld`, but with the option removed. This is the same strategy we already use of retrying when e.g. `-no-pie` is not supported. Fixes rust-lang#125330 r? `@petrochenkov` I have no idea how we could add a test here, much like we don't have one for `-no-pie` or `-static-pie` -- let me know if you have ideas -- but I tested on a CentOS7 image: ```console [root@d25b38376ede tmp]# ../build/host/stage1/bin/rustc helloworld.rs WARN rustc_codegen_ssa::back::link The linker driver does not support `-fuse-ld=lld`. Retrying without it. [root@d25b38376ede tmp]# readelf -p .comment helloworld String dump of section '.comment': [ 0] GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44) [ 2d] rustc version 1.80.0-dev ``` (I wasn't able to test with `cross` as the issue describes: I wasn't able to reproduce that behavior locally. So I'll ask for help from the OP with a try build)
self-contained linker: retry linking without `-fuse-ld=lld` on CCs that don't support it For the self-contained linker, this PR applies [the strategy](rust-lang#125330 (comment)) of retrying the linking step when the driver doesn't support `-fuse-ld=lld`, but with the option removed. This is the same strategy we already use of retrying when e.g. `-no-pie` is not supported. Fixes rust-lang#125330 r? `@petrochenkov` I have no idea how we could add a test here, much like we don't have one for `-no-pie` or `-static-pie` -- let me know if you have ideas -- but I tested on a CentOS7 image: ```console [root@d25b38376ede tmp]# ../build/host/stage1/bin/rustc helloworld.rs WARN rustc_codegen_ssa::back::link The linker driver does not support `-fuse-ld=lld`. Retrying without it. [root@d25b38376ede tmp]# readelf -p .comment helloworld String dump of section '.comment': [ 0] GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44) [ 2d] rustc version 1.80.0-dev ``` (I wasn't able to test with `cross` as the issue describes: I wasn't able to reproduce that behavior locally. So I'll ask for help from the OP with a try build) try-job: dist-aarch64-linux try-job: dist-x86_64-linux
Rollup merge of rust-lang#125417 - lqd:lld-retry, r=petrochenkov self-contained linker: retry linking without `-fuse-ld=lld` on CCs that don't support it For the self-contained linker, this PR applies [the strategy](rust-lang#125330 (comment)) of retrying the linking step when the driver doesn't support `-fuse-ld=lld`, but with the option removed. This is the same strategy we already use of retrying when e.g. `-no-pie` is not supported. Fixes rust-lang#125330 r? `@petrochenkov` I have no idea how we could add a test here, much like we don't have one for `-no-pie` or `-static-pie` -- let me know if you have ideas -- but I tested on a CentOS7 image: ```console [root@d25b38376ede tmp]# ../build/host/stage1/bin/rustc helloworld.rs WARN rustc_codegen_ssa::back::link The linker driver does not support `-fuse-ld=lld`. Retrying without it. [root@d25b38376ede tmp]# readelf -p .comment helloworld String dump of section '.comment': [ 0] GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44) [ 2d] rustc version 1.80.0-dev ``` I wasn't able to test with `cross` as the issue describes: I wasn't able to reproduce that behavior locally.
self-contained linker: retry linking without `-fuse-ld=lld` on CCs that don't support it For the self-contained linker, this PR applies [the strategy](rust-lang/rust#125330 (comment)) of retrying the linking step when the driver doesn't support `-fuse-ld=lld`, but with the option removed. This is the same strategy we already use of retrying when e.g. `-no-pie` is not supported. Fixes #125330 r? `@petrochenkov` I have no idea how we could add a test here, much like we don't have one for `-no-pie` or `-static-pie` -- let me know if you have ideas -- but I tested on a CentOS7 image: ```console [root@d25b38376ede tmp]# ../build/host/stage1/bin/rustc helloworld.rs WARN rustc_codegen_ssa::back::link The linker driver does not support `-fuse-ld=lld`. Retrying without it. [root@d25b38376ede tmp]# readelf -p .comment helloworld String dump of section '.comment': [ 0] GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44) [ 2d] rustc version 1.80.0-dev ``` I wasn't able to test with `cross` as the issue describes: I wasn't able to reproduce that behavior locally.
Code
I tried this code:
I expected to see this happen: Cross compilation should work fine
Instead, this happened: Cross compilation fails due to gcc not accepting
-fuse-ld=lld
Version it worked on
It most recently worked on: Nightly as of about a week ago, but it also works fine on stable.
Version with regression
rustc --version --verbose
:Backtrace
Backtrace
@rustbot modify labels: +regression-from-stable-to-nightly -regression-untriaged
The text was updated successfully, but these errors were encountered: