diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 48ca5fcf3ad0e..c3845812cb5c7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -625,6 +625,12 @@ impl LinkSelfContainedDefault { _ => "crt-objects-fallback", } } + + /// Creates a `LinkSelfContained` enabling the self-contained linker for target specs (the + /// equivalent of `-Clink-self-contained=+linker` on the CLI). + pub fn with_linker() -> LinkSelfContainedDefault { + LinkSelfContainedDefault::WithComponents(LinkSelfContainedComponents::LINKER) + } } bitflags::bitflags! { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 2f970f87cc642..bdb023f401294 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -16,6 +16,12 @@ pub fn target() -> Target { | SanitizerSet::THREAD; base.supports_xray = true; + #[cfg(rust_lld)] + { + base.linker_flavor = LinkerFlavor::Gnu(Cc::Yes, Lld::Yes); + base.link_self_contained = crate::spec::LinkSelfContainedDefault::with_linker(); + } + Target { llvm_target: "x86_64-unknown-linux-gnu".into(), pointer_width: 64, diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 8ab0ef61c502e..32f819d8546ae 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1034,6 +1034,10 @@ pub fn rustc_cargo_env( cargo.rustflag("--cfg=parallel_compiler"); cargo.rustdocflag("--cfg=parallel_compiler"); } + if builder.config.lld_enabled { + cargo.rustflag("--cfg=rust_lld"); + cargo.rustdocflag("--cfg=rust_lld"); + } if builder.config.rust_verify_llvm_ir { cargo.env("RUSTC_VERIFY_LLVM_IR", "1"); } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index a871399453e4f..fbeb4092bd89a 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1372,6 +1372,7 @@ impl Config { let mut debuginfo_level_tests = None; let mut optimize = None; let mut omit_git_hash = None; + let mut lld_enabled = None; if let Some(rust) = toml.rust { set(&mut config.channel, rust.channel); @@ -1404,6 +1405,7 @@ impl Config { debuginfo_level_std = rust.debuginfo_level_std; debuginfo_level_tools = rust.debuginfo_level_tools; debuginfo_level_tests = rust.debuginfo_level_tests; + lld_enabled = rust.lld; config.rust_split_debuginfo = rust .split_debuginfo @@ -1428,7 +1430,6 @@ impl Config { config.incremental = true; } set(&mut config.use_lld, rust.use_lld); - set(&mut config.lld_enabled, rust.lld); set(&mut config.llvm_tools_enabled, rust.llvm_tools); config.rustc_parallel = rust .parallel_compiler @@ -1665,6 +1666,26 @@ impl Config { config.llvm_plugins = llvm_plugins.unwrap_or(false); config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true)); + // `x86_64-unknown-linux-gnu` now uses the self-contained linker, so we have to build + // our internal lld by default: + // - when building our in-tree llvm (the target has not set an `llvm-config`), we're able to + // build rust-lld as well + // - when using an external llvm that's downloaded from CI, rust-lld is also packaged there + // - otherwise, we're using an external llvm and lld is not available and thus, disabled + // - similarly, it's not built or used by this target when asked not to (when the config + // sets `rust.lld = false`) + if config.build.triple == "x86_64-unknown-linux-gnu" && config.hosts == &[config.build] { + let no_llvm_config = config + .target_config + .get(&config.build) + .is_some_and(|target_config| target_config.llvm_config.is_none()); + let enable_lld = config.llvm_from_ci || no_llvm_config; + // Prefer the config setting in case an explicit opt-out is needed. + config.lld_enabled = lld_enabled.unwrap_or(enable_lld); + } else { + set(&mut config.lld_enabled, lld_enabled); + } + let default = debug == Some(true); config.rust_debug_assertions = debug_assertions.unwrap_or(default); config.rust_debug_assertions_std = diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 27922c9fbbe77..7ae65b80a3f84 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -117,6 +117,10 @@ const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ // Needed to avoid the need to copy windows.lib into the sysroot. (Some(Mode::Rustc), "windows_raw_dylib", None), (Some(Mode::ToolRustc), "windows_raw_dylib", None), + // If rustc wants to use rust-lld as the default linker in a target spec. + (Some(Mode::Rustc), "rust_lld", None), + (Some(Mode::ToolRustc), "rust_lld", None), + (Some(Mode::Codegen), "rust_lld", None), ]; /// A structure representing a Rust compiler. diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index 3b3ec5da74bc9..e939a5d7eac4d 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -3,7 +3,8 @@ set -ex source shared.sh -GCC=8.5.0 +# Note: in the future when bumping to version 10.1.0, also take care of the sed block below. +GCC=9.5.0 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC @@ -22,6 +23,11 @@ cd gcc-$GCC # latter host is presented to `wget`! Therefore, we choose to download from the insecure HTTP server # instead here. # +# Note: in version 10.1.0, the URL used in `download_prerequisites` has changed from using FTP to +# using HTTP. When bumping to that gcc version, we can likely remove the sed replacement below, or +# the expression will need to be updated. That new URL is available at: +# https://github.com/gcc-mirror/gcc/blob/6e6e3f144a33ae504149dc992453b4f6dea12fdb/contrib/download_prerequisites#L35 +# sed -i'' 's|ftp://gcc\.gnu\.org/|https://gcc.gnu.org/|g' ./contrib/download_prerequisites ./contrib/download_prerequisites