From 0107a99b49751f90d6a2e735d1dc8654f62450b3 Mon Sep 17 00:00:00 2001 From: Michal Rostecki Date: Wed, 13 Mar 2024 20:22:18 +0100 Subject: [PATCH] integration-test: Prefer system-wide lld over rust-lld on Linux rust-lld on Linux is unaware of system libraries and seems like there is no way to point it to them. That often triggers issues like: ``` cargo:warning=error: linking with `rust-lld` failed: exit status: 1ger, ppv-lite86, libc... cargo:warning= | cargo:warning= = note: LC_ALL="C" PATH="/home/vadorovsky/.rustup/toolchains/stable-x86_64-un cargo:warning= = note: rust-lld: error: unable to find library -lgcc_s cargo:warning= rust-lld: error: unable to find library -lc cargo:warning= cargo:warning= cargo:warning= cargo:warning=error: aborting due to 1 previous error ``` More explanation: https://users.rust-lang.org/t/enabling-rust-lld-for-aarch64-unknown-linux-gnu/113243/2 https://github.com/rust-lang/rust/issues/130062#issuecomment-2336050640 Fixes #907 --- xtask/src/run.rs | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 8bba7a53..6878423d 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -55,12 +55,36 @@ pub fn build(target: Option<&str>, f: F) -> Result> where F: FnOnce(&mut Command) -> &mut Command, { - // Always use rust-lld and -Zbuild-std in case we're cross-compiling. + // Always use lld in case we're cross-compiling. let mut cmd = Command::new("cargo"); cmd.args(["build", "--message-format=json"]); if let Some(target) = target { - let config = format!("target.{target}.linker = \"rust-lld\""); - cmd.args(["--target", target, "--config", &config]); + // Using rust-lld directly on Linux does not work, as you are expected + // to invoke a C compiler, which then invokes the linker with necessary + // arguments, like the search path. Invoking linker directly results in + // inability to find the system libraries. + // + // On Rust nightly, the solution is to use `-Zlinker-features=+lld`, + // which tells the C compiler to use rust-lld. However, there is no + // guarantee that the build is going to be performed with nightly + // toolchain, so that's not an option. + // + // On Rust stable, the solution is to invoke lld through clang. That's + // our best bet for now. + // + // https://users.rust-lang.org/t/enabling-rust-lld-for-aarch64-unknown-linux-gnu/113243/2 + // https://github.com/rust-lang/rust/issues/130062#issuecomment-2336050640 + #[cfg(target_os = "linux")] + { + let config = format!("target.{target}.rustflags=[\"-C\", \"linker=clang\", \"-C\", \"link-arg=-fuse-ld=lld\"]"); + cmd.args(["--target", target, "--config", &config]); + } + #[cfg(not(target_os = "linux"))] + { + // On non-Linux systems, rust-lld should work fine. + let config = format!("target.{target}.linker = \"rust-lld\""); + cmd.args(["--target", target, "--config", &config]); + } } f(&mut cmd);