Repository navigation
Closed
Labels
C-bugCategory: This is a bug.Category: This is a bug.P-highHigh priorityHigh priorityregression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
Description
Code
I tried this code:
❯ cargo new hello_world
Creating binary (application) `hello_world` package
cnote: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
❯ cd hello_world/
❯ cross +nightly build --target aarch64-unknown-linux-gnu
[cross] warning: using newer rustc `1.80.0-nightly (d84b90375 2024-05-19)` for the target. Current active rustc on the host is `rustc 1.78.0 (9b00956e5 2024-04-29)`.
> Update with `rustup update`
Compiling hello_world v0.1.0 (/project)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.82s
❯ cargo add syn
Updating crates.io index
Adding syn v2.0.65 to dependencies
Features:
+ clone-impls
+ derive
+ parsing
+ printing
+ proc-macro
- extra-traits
- fold
- full
- test
- visit
- visit-mut
Updating crates.io index
❯ cross +nightly build --target aarch64-unknown-linux-gnu
[cross] warning: using newer rustc `1.80.0-nightly (d84b90375 2024-05-19)` for the target. Current active rustc on the host is `rustc 1.78.0 (9b00956e5 2024-04-29)`.
> Update with `rustup update`
Compiling proc-macro2 v1.0.83
Compiling unicode-ident v1.0.12
error: linking with `cc` failed: exit status: 1
|
= note: LC_ALL="C" PATH="/rust/lib/rustlib/x86_64-unknown-linux-gnu/bin:/rust/lib/rustlib/x86_64-unknown-linux-gnu/bin/self-contained:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/rust/bin" VSLANG="1033" "cc" "-m64" "/tmp/rustcAyUfnb/symbols.o" "/target/debug/build/proc-macro2-b1e0569744dc7f5d/build_script_build-b1e0569744dc7f5d.build_script_build.48684d15272f5bdb-cgu.0.rcgu.o" "/target/debug/build/proc-macro2-b1e0569744dc7f5d/build_script_build-b1e0569744dc7f5d.build_script_build.48684d15272f5bdb-cgu.1.rcgu.o" "/target/debug/build/proc-macro2-b1e0569744dc7f5d/build_script_build-b1e0569744dc7f5d.crzselpkxut2yhaw0phvg3mu9.rcgu.o" "-Wl,--as-needed" "-L" "/target/debug/deps" "-L" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-de48b8168d6cf4fa.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-9f3477fb95a0bba7.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libobject-210d920812faea91.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libmemchr-f3d3451767410a17.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libaddr2line-1a79dd36d08251de.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libgimli-886230e7120831b2.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_demangle-2caea079085a58a2.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_detect-a9d7d97cdc65a449.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libhashbrown-5727477b0a78105a.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_alloc-7e555563aa211118.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libminiz_oxide-c8f13465f1a795b2.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libadler-ee5b5774583426df.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-14df174c91007922.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcfg_if-e8bfe52be756260a.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-6275035a459b3ada.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-b6892f3c52c68f01.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/librustc_std_workspace_core-f72b956e24d1de70.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-632ae0f28c5e55ff.rlib" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-e8b7e96e438f08f6.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-B/rust/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld" "-fuse-ld=lld" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-L" "/rust/lib/rustlib/x86_64-unknown-linux-gnu/lib/self-contained" "-o" "/target/debug/build/proc-macro2-b1e0569744dc7f5d/build_script_build-b1e0569744dc7f5d" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs"
= note: cc: error: unrecognized command line option '-fuse-ld=lld'
error: could not compile `proc-macro2` (build script) due to 1 previous errorI 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:
❯ rustc +nightly --version
rustc 1.80.0-nightly (d84b90375 2024-05-19)Backtrace
Backtrace
<backtrace>
@rustbot modify labels: +regression-from-stable-to-nightly -regression-untriaged
Metadata
Metadata
Assignees
Labels
C-bugCategory: This is a bug.Category: This is a bug.P-highHigh priorityHigh priorityregression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
Activity
VorpalBlade commentedon May 20, 2024
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.
saethlin commentedon May 20, 2024
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 -
fuse-ld=lldwithout a check for a compatible gcc breaches the target tier support that we declare.VorpalBlade commentedon May 20, 2024
@saethlin The double negation is hurting my brain, what do you actually mean here?
saethlin commentedon May 20, 2024
I mean that the new behavior violates of the spirit of the target tier policy, but not the very precise guarantees we document.
lqd commentedon May 21, 2024
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
-Zgcc-ld=lldimplementation doesn't have such a version check, and that CI had gcc 9.5 available because it actually builds it from source using the GCC 4.8.5 package available.I'll look into adding the version check.
lqd commentedon May 21, 2024
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:
-Z/-Zunstable-optionsflags that won't be needed in the futurerustc --print linker-featuresreturns whether lld is supported (we'd need to add support forlinker-featuresinrustc --printfirst of course). We could also check if rust-lld exists in the sysroot here, instead of only as a fallback during compilation like rust-lld: fallback to rustc's sysroot if there's no path to the linker in the target sysroot #125263.-Z/-Clinker-features=-lld. Of course, here they could also add their own dynamic opt-in/opt-out checks, like a GCC version check.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?
VorpalBlade commentedon May 21, 2024
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
crossselecting a suitable docker image such that it can cross compile binaries that are portable to any relevant glibc based Linux distros. And it seems that works okay (even on nightly), until it tries to build a proc macro that should execute on the host in the docker container.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
cargo installdoes not make much sense.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.
apiraino commentedon May 21, 2024
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-high
petrochenkov commentedon May 22, 2024
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).
So I agree that we need to fix this somehow.
petrochenkov commentedon May 22, 2024
One possible solution is a hack similar to fallback for unsupported
-no-pieor-static-pie-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.
lqd commentedon May 22, 2024
I'll look into doing that, it seems preferable to doing the version detection on the happy path that I was working on.
petrochenkov commentedon May 22, 2024
Another possible solution is to keep a fifth copy of lld-wrapper with a name
ld(orld.exe) in addition to these fourrust/src/bootstrap/src/lib.rs
Line 75 in f0038a7
Then we won't have to pass
-fuse-ld=lldat 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).
But this can also be solved, by moving them to separate directories.
Let's try the linker rerun hack first, I think.
Auto merge of rust-lang#125417 - lqd:lld-retry, r=<try>
Auto merge of rust-lang#125417 - lqd:lld-retry, r=<try>
Rollup merge of rust-lang#125417 - lqd:lld-retry, r=petrochenkov
Unrolled build for rust-lang#125417
Rollup merge of #125417 - lqd:lld-retry, r=petrochenkov