From c90aca342540d718d8a47fe0496cdb7c6fe48339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 17 Mar 2025 21:57:44 +0100 Subject: [PATCH 01/16] use LLD by default on x64 regardless of channel --- src/bootstrap/src/core/build_steps/compile.rs | 4 +--- src/bootstrap/src/core/config/toml/rust.rs | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 560925abba6a9..8b68394d4bd5f 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1357,9 +1357,7 @@ pub fn rustc_cargo_env( } // Enable rustc's env var for `rust-lld` when requested. - if builder.config.lld_enabled - && (builder.config.channel == "dev" || builder.config.channel == "nightly") - { + if builder.config.lld_enabled { cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1"); } diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs index 642f2f2271d8f..3509c1912a6e4 100644 --- a/src/bootstrap/src/core/config/toml/rust.rs +++ b/src/bootstrap/src/core/config/toml/rust.rs @@ -612,7 +612,6 @@ impl Config { // build our internal lld and use it as the default linker, by setting the `rust.lld` config // to true by default: // - on the `x86_64-unknown-linux-gnu` target - // - on the `dev` and `nightly` channels // - when building our in-tree llvm (i.e. the target has not set an `llvm-config`), so that // we're also able to build the corresponding lld // - or when using an external llvm that's downloaded from CI, which also contains our prebuilt @@ -621,9 +620,7 @@ impl Config { // thus, disabled // - similarly, lld will not be built nor used by default when explicitly asked not to, e.g. // when the config sets `rust.lld = false` - if self.host_target.triple == "x86_64-unknown-linux-gnu" - && self.hosts == [self.host_target] - && (self.channel == "dev" || self.channel == "nightly") + if self.host_target.triple == "x86_64-unknown-linux-gnu" && self.hosts == [self.host_target] { let no_llvm_config = self .target_config From fc55497cb9da2ba32dc2c43657449c9fcbfcd545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 18 Mar 2025 08:17:38 +0100 Subject: [PATCH 02/16] add post-dist test for checking that we use LLD And remove the previous beta/stable/nightly LLD tests. --- src/tools/opt-dist/src/tests.rs | 3 +++ .../rust-lld-by-default-beta-stable/main.rs | 1 - .../rust-lld-by-default-beta-stable/rmake.rs | 14 ------------- .../main.rs | 0 .../rmake.rs | 11 ++++------ .../rust-lld-x86_64-unknown-linux-gnu/main.rs | 5 +++++ .../rmake.rs | 20 +++++++++++++++++++ 7 files changed, 32 insertions(+), 22 deletions(-) delete mode 100644 tests/run-make/rust-lld-by-default-beta-stable/main.rs delete mode 100644 tests/run-make/rust-lld-by-default-beta-stable/rmake.rs rename tests/run-make/{rust-lld-by-default-nightly => rust-lld-x86_64-unknown-linux-gnu-dist}/main.rs (100%) rename tests/run-make/{rust-lld-by-default-nightly => rust-lld-x86_64-unknown-linux-gnu-dist}/rmake.rs (59%) create mode 100644 tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs create mode 100644 tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs diff --git a/src/tools/opt-dist/src/tests.rs b/src/tools/opt-dist/src/tests.rs index 53ce772fa7792..6ee06e6069ac3 100644 --- a/src/tools/opt-dist/src/tests.rs +++ b/src/tools/opt-dist/src/tests.rs @@ -104,7 +104,10 @@ llvm-config = "{llvm_config}" "tests/incremental", "tests/mir-opt", "tests/pretty", + // Make sure that we don't use too new GLIBC symbols on x64 "tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu", + // Make sure that we use LLD by default on x64 + "tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist", "tests/ui", "tests/crashes", ]; diff --git a/tests/run-make/rust-lld-by-default-beta-stable/main.rs b/tests/run-make/rust-lld-by-default-beta-stable/main.rs deleted file mode 100644 index f328e4d9d04c3..0000000000000 --- a/tests/run-make/rust-lld-by-default-beta-stable/main.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} diff --git a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs b/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs deleted file mode 100644 index 9a08991c4b895..0000000000000 --- a/tests/run-make/rust-lld-by-default-beta-stable/rmake.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Ensure that rust-lld is *not* used as the default linker on `x86_64-unknown-linux-gnu` on stable -// or beta. - -//@ ignore-nightly -//@ only-x86_64-unknown-linux-gnu - -use run_make_support::linker::assert_rustc_doesnt_use_lld; -use run_make_support::rustc; - -fn main() { - // A regular compilation should not use rust-lld by default. We'll check that by asking the - // linker to display its version number with a link-arg. - assert_rustc_doesnt_use_lld(rustc().input("main.rs")); -} diff --git a/tests/run-make/rust-lld-by-default-nightly/main.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/main.rs similarity index 100% rename from tests/run-make/rust-lld-by-default-nightly/main.rs rename to tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/main.rs diff --git a/tests/run-make/rust-lld-by-default-nightly/rmake.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs similarity index 59% rename from tests/run-make/rust-lld-by-default-nightly/rmake.rs rename to tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs index 3ff1e2770e65e..c26f82b7d3743 100644 --- a/tests/run-make/rust-lld-by-default-nightly/rmake.rs +++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs @@ -1,17 +1,14 @@ -// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` on the nightly -// channel, and that it can also be turned off with a CLI flag. +// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` +// dist artifacts and that it can also be turned off with a CLI flag. -//@ needs-rust-lld -//@ ignore-beta -//@ ignore-stable +//@ only-dist //@ only-x86_64-unknown-linux-gnu use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld}; use run_make_support::rustc; fn main() { - // A regular compilation should use rust-lld by default. We'll check that by asking the linker - // to display its version number with a link-arg. + // A regular compilation should use rust-lld by default. assert_rustc_uses_lld(rustc().input("main.rs")); // But it can still be disabled by turning the linker feature off. diff --git a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs new file mode 100644 index 0000000000000..e9f655fc09e4c --- /dev/null +++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/main.rs @@ -0,0 +1,5 @@ +// Test linking using `cc` with `rust-lld`, which is on by default on the x86_64-unknown-linux-gnu +// target. +// See https://github.com/rust-lang/compiler-team/issues/510 for more info + +fn main() {} diff --git a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs new file mode 100644 index 0000000000000..e71a47f11e263 --- /dev/null +++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs @@ -0,0 +1,20 @@ +// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` +// and that it can also be turned off with a CLI flag. +// +// This version of the test checks that LLD is used by default when LLD is enabled in the +// toolchain. There is a separate test that checks that LLD is used for dist artifacts +// unconditionally. + +//@ needs-rust-lld +//@ only-x86_64-unknown-linux-gnu + +use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld}; +use run_make_support::rustc; + +fn main() { + // A regular compilation should use rust-lld by default. + assert_rustc_uses_lld(rustc().input("main.rs")); + + // But it can still be disabled by turning the linker feature off. + assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs")); +} From c02f85e5b7d4a497a10f777d802c969c38af0490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 19 Mar 2025 16:59:21 +0100 Subject: [PATCH 03/16] stabilize `-Zlinker-features` as `-Clinker-features` --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_session/src/options.rs | 4 ++-- compiler/rustc_target/src/spec/mod.rs | 4 ++-- tests/run-make/compressed-debuginfo-zstd/rmake.rs | 2 +- tests/run-make/rust-lld-custom-target/rmake.rs | 2 +- tests/run-make/rust-lld-link-script-provide/rmake.rs | 3 +-- .../rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs | 2 +- .../rust-lld-x86_64-unknown-linux-gnu/rmake.rs | 2 +- tests/run-make/rust-lld/rmake.rs | 10 +++++----- 10 files changed, 16 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 8c52ed6ed1234..54da4af614b68 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1398,7 +1398,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { } } - let features = sess.opts.unstable_opts.linker_features; + let features = sess.opts.cg.linker_features; // linker and linker flavor specified via command line have precedence over what the target // specification specifies diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 406a6bd335a74..3aab2c7d202b6 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -400,7 +400,7 @@ impl LinkSelfContained { } } -/// The different values that `-Z linker-features` can take on the CLI: a list of individually +/// The different values that `-C linker-features` can take on the CLI: a list of individually /// enabled or disabled features used during linking. /// /// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index f76f258d00de9..af173a168e161 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1991,6 +1991,8 @@ options! { on a C toolchain or linker installed in the system"), linker: Option = (None, parse_opt_pathbuf, [UNTRACKED], "system linker to link outputs with"), + linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED], + "a comma-separated list of linker features to enable (+) or disable (-): `lld`"), linker_flavor: Option = (None, parse_linker_flavor, [UNTRACKED], "linker flavor"), linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, @@ -2281,8 +2283,6 @@ options! { "link native libraries in the linker invocation (default: yes)"), link_only: bool = (false, parse_bool, [TRACKED], "link the `.rlink` file generated by `-Z no-link` (default: no)"), - linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED], - "a comma-separated list of linker features to enable (+) or disable (-): `lld`"), lint_llvm_ir: bool = (false, parse_bool, [TRACKED], "lint LLVM IR (default: no)"), lint_mir: bool = (false, parse_bool, [UNTRACKED], diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 010355abd7817..9c7ce8b8794b7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -722,7 +722,7 @@ impl ToJson for LinkSelfContainedComponents { } bitflags::bitflags! { - /// The `-Z linker-features` components that can individually be enabled or disabled. + /// The `-C linker-features` components that can individually be enabled or disabled. /// /// They are feature flags intended to be a more flexible mechanism than linker flavors, and /// also to prevent a combinatorial explosion of flavors whenever a new linker feature is @@ -753,7 +753,7 @@ bitflags::bitflags! { rustc_data_structures::external_bitflags_debug! { LinkerFeatures } impl LinkerFeatures { - /// Parses a single `-Z linker-features` well-known feature, not a set of flags. + /// Parses a single `-C linker-features` well-known feature, not a set of flags. pub fn from_str(s: &str) -> Option { Some(match s { "cc" => LinkerFeatures::CC, diff --git a/tests/run-make/compressed-debuginfo-zstd/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs index cd8cf223047d3..8d7e5c089daa1 100644 --- a/tests/run-make/compressed-debuginfo-zstd/rmake.rs +++ b/tests/run-make/compressed-debuginfo-zstd/rmake.rs @@ -26,7 +26,7 @@ fn prepare_and_check &mut Rustc>(to_find: &str, prepare run_in_tmpdir(|| { let mut rustc = Rustc::new(); rustc - .arg("-Zlinker-features=+lld") + .arg("-Clinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") .arg("-Cdebuginfo=full") diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index e2b065a10b170..d0db31408f7a3 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -23,7 +23,7 @@ fn main() { rustc() .crate_type("cdylib") .target("custom-target.json") - .arg("-Zlinker-features=-lld") + .arg("-Clinker-features=-lld") .input("lib.rs"), ); } diff --git a/tests/run-make/rust-lld-link-script-provide/rmake.rs b/tests/run-make/rust-lld-link-script-provide/rmake.rs index e78a411bc15f0..0bd8f68116d01 100644 --- a/tests/run-make/rust-lld-link-script-provide/rmake.rs +++ b/tests/run-make/rust-lld-link-script-provide/rmake.rs @@ -10,9 +10,8 @@ use run_make_support::rustc; fn main() { rustc() .input("main.rs") - .arg("-Zlinker-features=+lld") + .arg("-Clinker-features=+lld") .arg("-Clink-self-contained=+linker") - .arg("-Zunstable-options") .link_arg("-Tscript.t") .run(); } diff --git a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs index c26f82b7d3743..c315d36a39d7c 100644 --- a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs +++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs @@ -12,5 +12,5 @@ fn main() { assert_rustc_uses_lld(rustc().input("main.rs")); // But it can still be disabled by turning the linker feature off. - assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs")); + assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs")); } diff --git a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs index e71a47f11e263..00415d27aaf33 100644 --- a/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs +++ b/tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs @@ -16,5 +16,5 @@ fn main() { assert_rustc_uses_lld(rustc().input("main.rs")); // But it can still be disabled by turning the linker feature off. - assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs")); + assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs")); } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 9470f5d0be183..2b914f19ac089 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -12,14 +12,14 @@ fn main() { // asking the linker to display its version number with a link-arg. assert_rustc_uses_lld( rustc() - .arg("-Zlinker-features=+lld") + .arg("-Clinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") .input("main.rs"), ); // It should not be used when we explicitly opt out of lld. - assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs")); + assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs")); // While we're here, also check that the last linker feature flag "wins" when passed multiple // times to rustc. @@ -27,9 +27,9 @@ fn main() { rustc() .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") - .arg("-Zlinker-features=-lld") - .arg("-Zlinker-features=+lld") - .arg("-Zlinker-features=-lld,+lld") + .arg("-Clinker-features=-lld") + .arg("-Clinker-features=+lld") + .arg("-Clinker-features=-lld,+lld") .input("main.rs"), ); } From 12ad4fab50ff3361aafed10b475d77f4e5e4bb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 19 Mar 2025 17:13:11 +0100 Subject: [PATCH 04/16] check that `-Clinker-features=[-+]lld` can only be used on x64 linux without `-Zunstable-options` --- compiler/rustc_session/src/config.rs | 42 +++++++++++++++++-- .../run-make/rust-lld-custom-target/rmake.rs | 1 + .../linker-features-lld-disallowed-target.rs | 8 ++++ ...nker-features-lld-disallowed-target.stderr | 2 + .../ui/linking/linker-features-unstable-cc.rs | 8 ++++ .../linker-features-unstable-cc.stderr | 2 + 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.rs create mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.stderr create mode 100644 tests/ui/linking/linker-features-unstable-cc.rs create mode 100644 tests/ui/linking/linker-features-unstable-cc.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 3aab2c7d202b6..d5dac86003499 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -440,6 +440,35 @@ impl LinkerFeaturesCli { _ => None, } } + + /// Checks usage of unstable variants for linker features for the given `target_tuple`. + /// Returns `Ok` if no unstable variants are used. + pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> { + let mentioned_features = self.enabled.union(self.disabled); + let has_lld = mentioned_features.is_lld_enabled(); + + // Check that -Clinker-features=[-+]lld is not used anywhere else than on x64 + // without -Zunstable-options. + if has_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C linker-features` with lld are unstable for the `{target_tuple}` target, \ +the `-Z unstable-options` flag must also be passed to use it on this target", + )); + } + + for feature in LinkerFeatures::all() { + // Check that no other features were enabled without -Zunstable-options + // Note that this should currently be unreachable, because the `-Clinker-features` parser + // currently only accepts lld. + if feature != LinkerFeatures::LLD && mentioned_features.contains(feature) { + return Err("`-C linker-features` is stable only for the lld feature, \ +the`-Z unstable-options` flag must also be passed to use it with other features" + .to_string()); + } + } + + Ok(()) + } } /// Used with `-Z assert-incr-state`. @@ -2601,9 +2630,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M } } - if !nightly_options::is_unstable_enabled(matches) - && cg.force_frame_pointers == FramePointer::NonLeaf - { + let unstable_options_enabled = nightly_options::is_unstable_enabled(matches); + if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf { early_dcx.early_fatal( "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \ and a nightly compiler", @@ -2613,7 +2641,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M // For testing purposes, until we have more feedback about these options: ensure `-Z // unstable-options` is required when using the unstable `-C link-self-contained` and `-C // linker-flavor` options. - if !nightly_options::is_unstable_enabled(matches) { + if !unstable_options_enabled { let uses_unstable_self_contained_option = cg.link_self_contained.are_unstable_variants_set(); if uses_unstable_self_contained_option { @@ -2670,6 +2698,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let debuginfo = select_debuginfo(matches, &cg); let debuginfo_compression = unstable_opts.debuginfo_compression; + if !unstable_options_enabled { + if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) { + early_dcx.early_fatal(error); + } + } + let crate_name = matches.opt_str("crate-name"); let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); // Parse any `-l` flags, which link to native libraries. diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index d0db31408f7a3..90ba424ffe940 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -24,6 +24,7 @@ fn main() { .crate_type("cdylib") .target("custom-target.json") .arg("-Clinker-features=-lld") + .arg("-Zunstable-options") .input("lib.rs"), ); } diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.rs b/tests/ui/linking/linker-features-lld-disallowed-target.rs new file mode 100644 index 0000000000000..6ebafc4371c60 --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed-target.rs @@ -0,0 +1,8 @@ +// Check that -CLinker-features=[+-]lld can only be used on x64. +// +//@ check-fail +//@ compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib +//@ needs-llvm-components: x86 + +#![feature(no_core)] +#![no_core] diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.stderr b/tests/ui/linking/linker-features-lld-disallowed-target.stderr new file mode 100644 index 0000000000000..292fadcd0f2ec --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed-target.stderr @@ -0,0 +1,2 @@ +error: `-C linker-features` with lld are unstable for the `x86_64-unknown-linux-musl target, ` the `-Z unstable-options` flag must also be passed to use it on this target + diff --git a/tests/ui/linking/linker-features-unstable-cc.rs b/tests/ui/linking/linker-features-unstable-cc.rs new file mode 100644 index 0000000000000..08431a2aa0045 --- /dev/null +++ b/tests/ui/linking/linker-features-unstable-cc.rs @@ -0,0 +1,8 @@ +// Check that -CLinker-features with anything else than lld requires -Zunstable-options. +// +//@ check-fail +//@ compile-flags: --target=x86_64-unknown-linux-gnu -C linker-features=+cc --crate-type=rlib +//@ needs-llvm-components: x86 + +#![feature(no_core)] +#![no_core] diff --git a/tests/ui/linking/linker-features-unstable-cc.stderr b/tests/ui/linking/linker-features-unstable-cc.stderr new file mode 100644 index 0000000000000..a69b419816098 --- /dev/null +++ b/tests/ui/linking/linker-features-unstable-cc.stderr @@ -0,0 +1,2 @@ +error: incorrect value `+cc` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected + From 3bc1e0741f0a1a9a9378f4cf0ffefccc716d2fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 24 Mar 2025 09:49:26 +0100 Subject: [PATCH 05/16] stabilize `-Clink-self-contained=[+-]linker` --- compiler/rustc_session/src/config.rs | 13 +++++++++---- tests/run-make/rust-lld/rmake.rs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index d5dac86003499..4f263af28e44c 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -371,9 +371,14 @@ impl LinkSelfContained { /// components was set individually. This would also require the `-Zunstable-options` flag, to /// be allowed. fn are_unstable_variants_set(&self) -> bool { - let any_component_set = - !self.enabled_components.is_empty() || !self.disabled_components.is_empty(); - self.explicitly_set.is_none() && any_component_set + if self.explicitly_set.is_some() { + return false; + } + + // Only the linker component is stable, anything else is thus unstable. + let mentioned_components = self.enabled_components.union(self.disabled_components); + let unstable_components = mentioned_components - LinkSelfContainedComponents::LINKER; + !unstable_components.is_empty() } /// Returns whether the self-contained linker component was enabled on the CLI, using the @@ -2646,7 +2651,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M cg.link_self_contained.are_unstable_variants_set(); if uses_unstable_self_contained_option { early_dcx.early_fatal( - "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \ + "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, \ the `-Z unstable-options` flag must also be passed to use the unstable values", ); } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 2b914f19ac089..1e16bea50f253 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -14,7 +14,7 @@ fn main() { rustc() .arg("-Clinker-features=+lld") .arg("-Clink-self-contained=+linker") - .arg("-Zunstable-options") + .arg("-Zunstable-options") // needed for targets other than `x86_64-unknown-linux-gnu` .input("main.rs"), ); From 9f0fb67911535b8d3ce18cda9fa9a282a57e802a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 24 Mar 2025 12:18:24 +0100 Subject: [PATCH 06/16] add test for unstable values of `-Clink-self-contained` --- tests/run-make/rust-lld/rmake.rs | 8 +++++--- .../linking/link-self-contained-consistency.rs | 1 - .../link-self-contained-unstable.crto.stderr | 2 ++ .../link-self-contained-unstable.libc.stderr | 2 ++ .../link-self-contained-unstable.mingw.stderr | 2 ++ .../ui/linking/link-self-contained-unstable.rs | 17 +++++++++++++++++ ...nk-self-contained-unstable.sanitizers.stderr | 2 ++ .../link-self-contained-unstable.unwind.stderr | 2 ++ .../linker-features-lld-disallowed-target.rs | 5 ++++- ...linker-features-lld-disallowed-target.stderr | 2 +- tests/ui/linking/linker-features-unstable-cc.rs | 9 +++++++-- 11 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 tests/ui/linking/link-self-contained-unstable.crto.stderr create mode 100644 tests/ui/linking/link-self-contained-unstable.libc.stderr create mode 100644 tests/ui/linking/link-self-contained-unstable.mingw.stderr create mode 100644 tests/ui/linking/link-self-contained-unstable.rs create mode 100644 tests/ui/linking/link-self-contained-unstable.sanitizers.stderr create mode 100644 tests/ui/linking/link-self-contained-unstable.unwind.stderr diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 1e16bea50f253..556580f066f3e 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -1,5 +1,5 @@ -// Test linking using `cc` with `rust-lld`, using the unstable CLI described in MCP 510 -// see https://github.com/rust-lang/compiler-team/issues/510 for more info +// Test linking using `cc` with `rust-lld`, using the `-Clinker-features` and +// `-Clink-self-contained` CLI flags. //@ needs-rust-lld //@ ignore-s390x lld does not yet support s390x as target @@ -19,7 +19,9 @@ fn main() { ); // It should not be used when we explicitly opt out of lld. - assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs")); + assert_rustc_doesnt_use_lld( + rustc().arg("-Clinker-features=-lld").arg("-Zunstable-options").input("main.rs"), + ); // While we're here, also check that the last linker feature flag "wins" when passed multiple // times to rustc. diff --git a/tests/ui/linking/link-self-contained-consistency.rs b/tests/ui/linking/link-self-contained-consistency.rs index 0822743389160..e3944fc0360cd 100644 --- a/tests/ui/linking/link-self-contained-consistency.rs +++ b/tests/ui/linking/link-self-contained-consistency.rs @@ -1,7 +1,6 @@ // Checks that self-contained linking components cannot be both enabled and disabled at the same // time on the CLI. -//@ check-fail //@ revisions: one many //@ [one] compile-flags: -Clink-self-contained=-linker -Clink-self-contained=+linker -Zunstable-options //@ [many] compile-flags: -Clink-self-contained=+linker,+crto -Clink-self-contained=-linker,-crto -Zunstable-options diff --git a/tests/ui/linking/link-self-contained-unstable.crto.stderr b/tests/ui/linking/link-self-contained-unstable.crto.stderr new file mode 100644 index 0000000000000..086b22736bb6d --- /dev/null +++ b/tests/ui/linking/link-self-contained-unstable.crto.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/link-self-contained-unstable.libc.stderr b/tests/ui/linking/link-self-contained-unstable.libc.stderr new file mode 100644 index 0000000000000..086b22736bb6d --- /dev/null +++ b/tests/ui/linking/link-self-contained-unstable.libc.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/link-self-contained-unstable.mingw.stderr b/tests/ui/linking/link-self-contained-unstable.mingw.stderr new file mode 100644 index 0000000000000..086b22736bb6d --- /dev/null +++ b/tests/ui/linking/link-self-contained-unstable.mingw.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/link-self-contained-unstable.rs b/tests/ui/linking/link-self-contained-unstable.rs new file mode 100644 index 0000000000000..ad7570374751f --- /dev/null +++ b/tests/ui/linking/link-self-contained-unstable.rs @@ -0,0 +1,17 @@ +// Checks that values for `-Clink-self-contained` other than the blanket enable/disable and +// `+/-linker` require `-Zunstable-options`. + +//@ revisions: crto libc unwind sanitizers mingw +//@ [crto] compile-flags: -Clink-self-contained=+crto +//@ [libc] compile-flags: -Clink-self-contained=-libc +//@ [unwind] compile-flags: -Clink-self-contained=+unwind +//@ [sanitizers] compile-flags: -Clink-self-contained=-sanitizers +//@ [mingw] compile-flags: -Clink-self-contained=+mingw + +fn main() {} + +//[crto]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +//[libc]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +//[unwind]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +//[sanitizers]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +//[mingw]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values diff --git a/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr b/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr new file mode 100644 index 0000000000000..086b22736bb6d --- /dev/null +++ b/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/link-self-contained-unstable.unwind.stderr b/tests/ui/linking/link-self-contained-unstable.unwind.stderr new file mode 100644 index 0000000000000..086b22736bb6d --- /dev/null +++ b/tests/ui/linking/link-self-contained-unstable.unwind.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.rs b/tests/ui/linking/linker-features-lld-disallowed-target.rs index 6ebafc4371c60..641f95a486440 100644 --- a/tests/ui/linking/linker-features-lld-disallowed-target.rs +++ b/tests/ui/linking/linker-features-lld-disallowed-target.rs @@ -1,4 +1,5 @@ -// Check that -CLinker-features=[+-]lld can only be used on x64. +// Check that `-C linker-features=[+-]lld` is only stable on x64 linux, and needs `-Z +// unstable-options` elsewhere. // //@ check-fail //@ compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib @@ -6,3 +7,5 @@ #![feature(no_core)] #![no_core] + +//~? ERROR `-C linker-features` with lld are unstable for the `x86_64-unknown-linux-musl` target, the `-Z unstable-options` flag must also be passed to use it on this target diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.stderr b/tests/ui/linking/linker-features-lld-disallowed-target.stderr index 292fadcd0f2ec..033b829e3a4c2 100644 --- a/tests/ui/linking/linker-features-lld-disallowed-target.stderr +++ b/tests/ui/linking/linker-features-lld-disallowed-target.stderr @@ -1,2 +1,2 @@ -error: `-C linker-features` with lld are unstable for the `x86_64-unknown-linux-musl target, ` the `-Z unstable-options` flag must also be passed to use it on this target +error: `-C linker-features` with lld are unstable for the `x86_64-unknown-linux-musl` target, the `-Z unstable-options` flag must also be passed to use it on this target diff --git a/tests/ui/linking/linker-features-unstable-cc.rs b/tests/ui/linking/linker-features-unstable-cc.rs index 08431a2aa0045..da7651699fb9a 100644 --- a/tests/ui/linking/linker-features-unstable-cc.rs +++ b/tests/ui/linking/linker-features-unstable-cc.rs @@ -1,8 +1,13 @@ -// Check that -CLinker-features with anything else than lld requires -Zunstable-options. +// Check that only `-C linker-features=[+-]lld` is stable on x64 linux, and that other linker +// features require using `-Z unstable-options`. +// +// Note that, currently, only `lld` is parsed on the CLI, but that other linker features can exist +// internally (`cc`). // -//@ check-fail //@ compile-flags: --target=x86_64-unknown-linux-gnu -C linker-features=+cc --crate-type=rlib //@ needs-llvm-components: x86 #![feature(no_core)] #![no_core] + +//~? ERROR incorrect value `+cc` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected From 57187c8fa23802f80231775ec473e041240968c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 24 Mar 2025 12:29:55 +0100 Subject: [PATCH 07/16] update documentation --- src/doc/rustc/src/codegen-options/index.md | 34 +++++++++++++++--- .../src/compiler-flags/codegen-options.md | 4 +-- .../src/compiler-flags/linker-features.md | 35 ------------------- 3 files changed, 32 insertions(+), 41 deletions(-) delete mode 100644 src/doc/unstable-book/src/compiler-flags/linker-features.md diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index bb109adf76f41..21be7657635c9 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -235,15 +235,22 @@ coverage measurement. Its use is not recommended. ## link-self-contained -On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the -linker will use libraries and objects shipped with Rust instead of those in the system. -It takes one of the following values: +This flag controls whether the linker will use libraries and objects shipped with Rust instead of +those in the system. It also controls which binary is used for the linker itself. This allows +overriding cases when detection fails or the user wants to use shipped libraries. + +You can enable or disable the usage of any self-contained components using one of the following values: * no value: rustc will use heuristic to disable self-contained mode if system has necessary tools. * `y`, `yes`, `on`, `true`: use only libraries/objects shipped with Rust. * `n`, `no`, `off` or `false`: rely on the user or the linker to provide non-Rust libraries/objects. -This allows overriding cases when detection fails or user wants to use shipped libraries. +It is also possible to enable or disable specific self-contained components in a more granular way. +You can pass a comma-separated list of self-contained components, individually enabled +(`+component`) or disabled (`-component`). + +Currently, only the `linker` granular option is stabilized: +- `linker`: toggle the usage of self-contained linker binaries (linker, dlltool, and their necessary libraries) ## linker @@ -256,6 +263,25 @@ Note that on Unix-like targets (for example, `*-unknown-linux-gnu` or `*-unknown the C compiler (for example `cc` or `clang`) is used as the "linker" here, serving as a linker driver. It will invoke the actual linker with all the necessary flags to be able to link against the system libraries like libc. +## linker-features + +The `-Clinker-features` flag allows enabling or disabling specific features used during linking. + +These feature flags are a flexible extension mechanism that is complementary to linker flavors, +designed to avoid the combinatorial explosion of having to create a new set of flavors for each +linker feature we'd want to use. + +The flag accepts a comma-separated list of features, individually enabled (`+feature`) or disabled +(`-feature`). + +Currently only one is stable, and only on the `x86_64-unknown-linux-gnu` target: +- `lld`: to toggle using the lld linker, either the system-installed binary, or the self-contained + `rust-lld` linker (via the `-Clink-self-contained=+linker` flag). + +For example, use: +- `-Clinker-features=+lld` to opt in to using the `lld` linker +- `-Clinker-features=-lld` to opt out instead, for targets where it is configured as the default linker + ## linker-flavor This flag controls the linker flavor used by `rustc`. If a linker is given with diff --git a/src/doc/unstable-book/src/compiler-flags/codegen-options.md b/src/doc/unstable-book/src/compiler-flags/codegen-options.md index cc51554706d07..6a6e14a5c1ddc 100644 --- a/src/doc/unstable-book/src/compiler-flags/codegen-options.md +++ b/src/doc/unstable-book/src/compiler-flags/codegen-options.md @@ -51,10 +51,10 @@ instead of those in the system. The stable boolean values for this flag are coar - `mingw`: other MinGW libs and Windows import libs Out of the above self-contained linking components, `linker` is the only one currently implemented -(beyond parsing the CLI options). +(beyond parsing the CLI options) and stabilized. It refers to the LLD linker, built from the same LLVM revision used by rustc (named `rust-lld` to avoid naming conflicts), that is distributed via `rustup` with the compiler (and is used by default -for the wasm targets). One can also opt-in to use it by combining this flag with an appropriate +for the wasm targets). One can also opt in to use it by combining this flag with an appropriate linker flavor: for example, `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker` will use the toolchain's `rust-lld` as the linker. diff --git a/src/doc/unstable-book/src/compiler-flags/linker-features.md b/src/doc/unstable-book/src/compiler-flags/linker-features.md deleted file mode 100644 index 643fcf7c6d7e0..0000000000000 --- a/src/doc/unstable-book/src/compiler-flags/linker-features.md +++ /dev/null @@ -1,35 +0,0 @@ -# `linker-features` - --------------------- - -The `-Zlinker-features` compiler flag allows enabling or disabling specific features used during -linking, and is intended to be stabilized under the codegen options as `-Clinker-features`. - -These feature flags are a flexible extension mechanism that is complementary to linker flavors, -designed to avoid the combinatorial explosion of having to create a new set of flavors for each -linker feature we'd want to use. - -For example, this design allows: -- default feature sets for principal flavors, or for specific targets. -- flavor-specific features: for example, clang offers automatic cross-linking with `--target`, which - gcc-style compilers don't support. The *flavor* is still a C/C++ compiler, and we don't want to - multiply the number of flavors for this use-case. Instead, we can have a single `+target` feature. -- umbrella features: for example, if clang accumulates more features in the future than just the - `+target` above. That could be modeled as `+clang`. -- niche features for resolving specific issues: for example, on Apple targets the linker flag - implementing the `as-needed` native link modifier (#99424) is only possible on sufficiently recent - linker versions. -- still allows for discovery and automation, for example via feature detection. This can be useful - in exotic environments/build systems. - -The flag accepts a comma-separated list of features, individually enabled (`+features`) or disabled -(`-features`), though currently only one is exposed on the CLI: -- `lld`: to toggle using the lld linker, either the system-installed binary, or the self-contained - `rust-lld` linker. - -As described above, this list is intended to grow in the future. - -One of the most common uses of this flag will be to toggle self-contained linking with `rust-lld` on -and off: `-Clinker-features=+lld -Clink-self-contained=+linker` will use the toolchain's `rust-lld` -as the linker. Inversely, `-Clinker-features=-lld` would opt out of that, if the current target had -self-contained linking enabled by default. From 98d2074df6cdbcdb9382f871d2303613dfe26854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 4 Apr 2025 14:59:27 +0000 Subject: [PATCH 08/16] update `check_unstable_variants`'s handling of `-C linker-features=[-+]lld` - separate enabling and disabling the feature in the error - add both polarities to the dedicated test - update documentation and precondition --- compiler/rustc_session/src/config.rs | 51 +++++++++++-------- compiler/rustc_target/src/spec/mod.rs | 11 ++++ ...ures-lld-disallowed-target.negative.stderr | 2 + ...ures-lld-disallowed-target.positive.stderr | 2 + .../linker-features-lld-disallowed-target.rs | 15 ++++-- ...nker-features-lld-disallowed-target.stderr | 2 - 6 files changed, 55 insertions(+), 28 deletions(-) create mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.negative.stderr create mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr delete mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 4f263af28e44c..5e9ac6e76dc12 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -446,32 +446,41 @@ impl LinkerFeaturesCli { } } - /// Checks usage of unstable variants for linker features for the given `target_tuple`. - /// Returns `Ok` if no unstable variants are used. + /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are + /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used. + /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()` + /// returns false. pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> { - let mentioned_features = self.enabled.union(self.disabled); - let has_lld = mentioned_features.is_lld_enabled(); - - // Check that -Clinker-features=[-+]lld is not used anywhere else than on x64 - // without -Zunstable-options. - if has_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + // `-C linker-features=[-+]lld` is only stable on x64 linux. + let check_lld = |features: LinkerFeatures, polarity: &str| { + let has_lld = features.is_lld_enabled(); + if has_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C linker-features={polarity}lld` is unstable on the `{target_tuple}` \ + target. The `-Z unstable-options` flag must also be passed to use it on this target", + )); + } + Ok(()) + }; + check_lld(self.enabled, "+")?; + check_lld(self.disabled, "-")?; + + // Since only lld is stable, any non-lld feature used is unstable, and that's an error. + let unstable_enabled = self.enabled - LinkerFeatures::LLD; + let unstable_disabled = self.disabled - LinkerFeatures::LLD; + if !unstable_enabled.union(unstable_disabled).is_empty() { + let unstable_features: Vec<_> = unstable_enabled + .iter() + .map(|f| format!("+{}", f.as_str().unwrap())) + .chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap()))) + .collect(); return Err(format!( - "`-C linker-features` with lld are unstable for the `{target_tuple}` target, \ -the `-Z unstable-options` flag must also be passed to use it on this target", + "the requested `-C linker-features={}` are unstable, and also require the \ + `-Z unstable-options` flag to be usable", + unstable_features.join(","), )); } - for feature in LinkerFeatures::all() { - // Check that no other features were enabled without -Zunstable-options - // Note that this should currently be unreachable, because the `-Clinker-features` parser - // currently only accepts lld. - if feature != LinkerFeatures::LLD && mentioned_features.contains(feature) { - return Err("`-C linker-features` is stable only for the lld feature, \ -the`-Z unstable-options` flag must also be passed to use it with other features" - .to_string()); - } - } - Ok(()) } } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 9c7ce8b8794b7..36a11c8bcaad3 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -762,6 +762,17 @@ impl LinkerFeatures { }) } + /// Return the linker feature name, as would be passed on the CLI. + /// + /// Returns `None` if the bitflags aren't a singular component (but a mix of multiple flags). + pub fn as_str(self) -> Option<&'static str> { + Some(match self { + LinkerFeatures::CC => "cc", + LinkerFeatures::LLD => "lld", + _ => return None, + }) + } + /// Returns whether the `lld` linker feature is enabled. pub fn is_lld_enabled(self) -> bool { self.contains(LinkerFeatures::LLD) diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.negative.stderr b/tests/ui/linking/linker-features-lld-disallowed-target.negative.stderr new file mode 100644 index 0000000000000..205082b072626 --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed-target.negative.stderr @@ -0,0 +1,2 @@ +error: `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target + diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr b/tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr new file mode 100644 index 0000000000000..2b10e6c714850 --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr @@ -0,0 +1,2 @@ +error: `-C linker-features=+lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target + diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.rs b/tests/ui/linking/linker-features-lld-disallowed-target.rs index 641f95a486440..b3ae7e7ecf401 100644 --- a/tests/ui/linking/linker-features-lld-disallowed-target.rs +++ b/tests/ui/linking/linker-features-lld-disallowed-target.rs @@ -1,11 +1,16 @@ // Check that `-C linker-features=[+-]lld` is only stable on x64 linux, and needs `-Z // unstable-options` elsewhere. -// -//@ check-fail -//@ compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib -//@ needs-llvm-components: x86 + +// ignore-tidy-linelength + +//@ revisions: positive negative +//@ [negative] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib +//@ [negative] needs-llvm-components: x86 +//@ [positive] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=+lld --crate-type=rlib +//@ [positive] needs-llvm-components: x86 #![feature(no_core)] #![no_core] -//~? ERROR `-C linker-features` with lld are unstable for the `x86_64-unknown-linux-musl` target, the `-Z unstable-options` flag must also be passed to use it on this target +//[negative]~? ERROR `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target +//[positive]~? ERROR `-C linker-features=+lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.stderr b/tests/ui/linking/linker-features-lld-disallowed-target.stderr deleted file mode 100644 index 033b829e3a4c2..0000000000000 --- a/tests/ui/linking/linker-features-lld-disallowed-target.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: `-C linker-features` with lld are unstable for the `x86_64-unknown-linux-musl` target, the `-Z unstable-options` flag must also be passed to use it on this target - From b16c1ae7e8ad462e25beaadb2a2e79c8e9adb20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 25 Apr 2025 15:27:29 +0000 Subject: [PATCH 09/16] update bootstrap mcp510 handling now that it's been stabilized, beta and stage1 need to use different flags (-C vs -Z) --- src/bootstrap/src/core/build_steps/test.rs | 20 +++++++++++++---- src/bootstrap/src/core/builder/cargo.rs | 18 +++++++++++----- src/bootstrap/src/core/builder/mod.rs | 2 +- src/bootstrap/src/utils/helpers.rs | 25 ++++++++++++++++------ 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index f9f82b800419b..e5186c57f46ad 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -262,7 +262,13 @@ impl Step for Cargotest { .args(builder.config.test_args()) .env("RUSTC", builder.rustc(compiler)) .env("RUSTDOC", builder.rustdoc(compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args( + &mut cmd, + builder, + compiler.host, + LldThreads::No, + compiler.stage, + ); cmd.delay_failure().run(builder); } } @@ -857,7 +863,7 @@ impl Step for RustdocTheme { .env("CFG_RELEASE_CHANNEL", &builder.config.channel) .env("RUSTDOC_REAL", builder.rustdoc(self.compiler)) .env("RUSTC_BOOTSTRAP", "1"); - cmd.args(linker_args(builder, self.compiler.host, LldThreads::No)); + cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage)); cmd.delay_failure().run(builder); } @@ -1033,7 +1039,13 @@ impl Step for RustdocGUI { cmd.env("RUSTDOC", builder.rustdoc(self.compiler)) .env("RUSTC", builder.rustc(self.compiler)); - add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No); + add_rustdoc_cargo_linker_args( + &mut cmd, + builder, + self.compiler.host, + LldThreads::No, + self.compiler.stage, + ); for path in &builder.paths { if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) { @@ -1802,7 +1814,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the } let mut hostflags = flags.clone(); - hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No)); + hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage)); let mut targetflags = flags; diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index 0e3c3aaee0ff7..a84dca87a4455 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -115,7 +115,7 @@ impl Cargo { // No need to configure the target linker for these command types. Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {} _ => { - cargo.configure_linker(builder); + cargo.configure_linker(builder, mode); } } @@ -206,7 +206,7 @@ impl Cargo { // FIXME(onur-ozkan): Add coverage to make sure modifications to this function // doesn't cause cache invalidations (e.g., #130108). - fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo { + fn configure_linker(&mut self, builder: &Builder<'_>, mode: Mode) -> &mut Cargo { let target = self.target; let compiler = self.compiler; @@ -261,7 +261,15 @@ impl Cargo { } } - for arg in linker_args(builder, compiler.host, LldThreads::Yes) { + // When determining flags for the host (build scripts/proc macros), + // we use the snapshot compiler when building `Mode::Std` tools, and + // the current compiler when building anything else. + // We need to determine the current stage here to pass proper linker args (e.g. -C vs -Z) + // to the compiler used to compile build scripts. + // This should stay synchronized with the [cargo] function. + let host_stage = if mode == Mode::Std { 0 } else { compiler.stage }; + + for arg in linker_args(builder, compiler.host, LldThreads::Yes, host_stage) { self.hostflags.arg(&arg); } @@ -271,10 +279,10 @@ impl Cargo { } // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not // `linker_args` here. - for flag in linker_flags(builder, target, LldThreads::Yes) { + for flag in linker_flags(builder, target, LldThreads::Yes, compiler.stage) { self.rustflags.arg(&flag); } - for arg in linker_args(builder, target, LldThreads::Yes) { + for arg in linker_args(builder, target, LldThreads::Yes, compiler.stage) { self.rustdocflags.arg(&arg); } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 7433f0b0f3b44..bfbd6e5b1643e 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1496,7 +1496,7 @@ impl<'a> Builder<'a> { cmd.arg("-Dwarnings"); } cmd.arg("-Znormalize-docs"); - cmd.args(linker_args(self, compiler.host, LldThreads::Yes)); + cmd.args(linker_args(self, compiler.host, LldThreads::Yes, compiler.stage)); cmd } diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index f4be22f1e649e..872cb6c608659 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -428,8 +428,9 @@ pub fn linker_args( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) -> Vec { - let mut args = linker_flags(builder, target, lld_threads); + let mut args = linker_flags(builder, target, lld_threads, stage); if let Some(linker) = builder.linker(target) { args.push(format!("-Clinker={}", linker.display())); @@ -444,19 +445,30 @@ pub fn linker_flags( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) -> Vec { let mut args = vec![]; if !builder.is_lld_direct_linker(target) && builder.config.lld_mode.is_used() { match builder.config.lld_mode { LldMode::External => { - args.push("-Zlinker-features=+lld".to_string()); - // FIXME(kobzol): remove this flag once MCP510 gets stabilized + // cfg(bootstrap) - remove the stage 0 check after updating the bootstrap compiler: + // `-Clinker-features` has been stabilized. + if stage == 0 { + args.push("-Zlinker-features=+lld".to_string()); + } else { + args.push("-Clinker-features=+lld".to_string()); + } args.push("-Zunstable-options".to_string()); } LldMode::SelfContained => { - args.push("-Zlinker-features=+lld".to_string()); + // cfg(bootstrap) - remove the stage 0 check after updating the bootstrap compiler: + // `-Clinker-features` has been stabilized. + if stage == 0 { + args.push("-Zlinker-features=+lld".to_string()); + } else { + args.push("-Clinker-features=+lld".to_string()); + } args.push("-Clink-self-contained=+linker".to_string()); - // FIXME(kobzol): remove this flag once MCP510 gets stabilized args.push("-Zunstable-options".to_string()); } LldMode::Unused => unreachable!(), @@ -477,8 +489,9 @@ pub fn add_rustdoc_cargo_linker_args( builder: &Builder<'_>, target: TargetSelection, lld_threads: LldThreads, + stage: u32, ) { - let args = linker_args(builder, target, lld_threads); + let args = linker_args(builder, target, lld_threads, stage); let mut flags = cmd .get_envs() .find_map(|(k, v)| if k == OsStr::new("RUSTDOCFLAGS") { v } else { None }) From b242bd2bb8ebe3050ad5165d7887b200040420ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 5 May 2025 15:43:17 +0000 Subject: [PATCH 10/16] simplify test annotations --- tests/ui/linking/link-self-contained-unstable.rs | 10 +++++----- .../linking/linker-features-lld-disallowed-target.rs | 4 ++-- tests/ui/linking/linker-features-unstable-cc.rs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/ui/linking/link-self-contained-unstable.rs b/tests/ui/linking/link-self-contained-unstable.rs index ad7570374751f..73ffaeac42b18 100644 --- a/tests/ui/linking/link-self-contained-unstable.rs +++ b/tests/ui/linking/link-self-contained-unstable.rs @@ -10,8 +10,8 @@ fn main() {} -//[crto]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values -//[libc]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values -//[unwind]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values -//[sanitizers]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values -//[mingw]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +//[crto]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable +//[libc]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable +//[unwind]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable +//[sanitizers]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable +//[mingw]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.rs b/tests/ui/linking/linker-features-lld-disallowed-target.rs index b3ae7e7ecf401..9d4555c64e710 100644 --- a/tests/ui/linking/linker-features-lld-disallowed-target.rs +++ b/tests/ui/linking/linker-features-lld-disallowed-target.rs @@ -12,5 +12,5 @@ #![feature(no_core)] #![no_core] -//[negative]~? ERROR `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target -//[positive]~? ERROR `-C linker-features=+lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target +//[negative]~? ERROR `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target +//[positive]~? ERROR `-C linker-features=+lld` is unstable on the `x86_64-unknown-linux-musl` target diff --git a/tests/ui/linking/linker-features-unstable-cc.rs b/tests/ui/linking/linker-features-unstable-cc.rs index da7651699fb9a..8ea84117c10c7 100644 --- a/tests/ui/linking/linker-features-unstable-cc.rs +++ b/tests/ui/linking/linker-features-unstable-cc.rs @@ -10,4 +10,4 @@ #![feature(no_core)] #![no_core] -//~? ERROR incorrect value `+cc` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +//~? ERROR incorrect value `+cc` for codegen option `linker-features` From 1d21627fd263e52419599a19a8a1faf5a513fc31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 5 May 2025 17:09:40 +0000 Subject: [PATCH 11/16] check that `-Clink-self-contained=[-+]linker` can only be used on x64 linux without `-Zunstable-options` --- compiler/rustc_session/src/config.rs | 56 ++++++++++++------- ...d-linker-disallowed-target.negative.stderr | 2 + ...d-linker-disallowed-target.positive.stderr | 2 + ...self-contained-linker-disallowed-target.rs | 16 ++++++ 4 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 tests/ui/linking/link-self-contained-linker-disallowed-target.negative.stderr create mode 100644 tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr create mode 100644 tests/ui/linking/link-self-contained-linker-disallowed-target.rs diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5e9ac6e76dc12..74ace6887e3a8 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -368,17 +368,40 @@ impl LinkSelfContained { } /// To help checking CLI usage while some of the values are unstable: returns whether one of the - /// components was set individually. This would also require the `-Zunstable-options` flag, to - /// be allowed. - fn are_unstable_variants_set(&self) -> bool { + /// unstable components was set individually, for the given `TargetTuple`. This would also + /// require the `-Zunstable-options` flag, to be allowed. + fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> { if self.explicitly_set.is_some() { - return false; + return Ok(()); } - // Only the linker component is stable, anything else is thus unstable. - let mentioned_components = self.enabled_components.union(self.disabled_components); - let unstable_components = mentioned_components - LinkSelfContainedComponents::LINKER; - !unstable_components.is_empty() + // `-C link-self-contained=[-+]linker` is only stable on x64 linux. + let check_linker = |components: LinkSelfContainedComponents, polarity: &str| { + let has_linker = components.is_linker_enabled(); + if has_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C link-self-contained={polarity}linker` is unstable on the `{target_tuple}` \ + target. The `-Z unstable-options` flag must also be passed to use it on this target", + )); + } + Ok(()) + }; + check_linker(self.enabled_components, "+")?; + check_linker(self.disabled_components, "-")?; + + // Since only the linker component is stable, any other component used is unstable, and + // that's an error. + let unstable_enabled = self.enabled_components - LinkSelfContainedComponents::LINKER; + let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER; + if !unstable_enabled.union(unstable_disabled).is_empty() { + return Err(String::from( + "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`\ + /`+linker` are stable, the `-Z unstable-options` flag must also be passed to use \ + the unstable values", + )); + } + + Ok(()) } /// Returns whether the self-contained linker component was enabled on the CLI, using the @@ -2652,17 +2675,13 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M ) } - // For testing purposes, until we have more feedback about these options: ensure `-Z - // unstable-options` is required when using the unstable `-C link-self-contained` and `-C - // linker-flavor` options. + let target_triple = parse_target_triple(early_dcx, matches); + + // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and + // `-C linker-flavor` options. if !unstable_options_enabled { - let uses_unstable_self_contained_option = - cg.link_self_contained.are_unstable_variants_set(); - if uses_unstable_self_contained_option { - early_dcx.early_fatal( - "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, \ - the `-Z unstable-options` flag must also be passed to use the unstable values", - ); + if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) { + early_dcx.early_fatal(error); } if let Some(flavor) = cg.linker_flavor { @@ -2703,7 +2722,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let cg = cg; let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m)); - let target_triple = parse_target_triple(early_dcx, matches); let opt_level = parse_opt_level(early_dcx, matches, &cg); // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`) diff --git a/tests/ui/linking/link-self-contained-linker-disallowed-target.negative.stderr b/tests/ui/linking/link-self-contained-linker-disallowed-target.negative.stderr new file mode 100644 index 0000000000000..8bf71941c4454 --- /dev/null +++ b/tests/ui/linking/link-self-contained-linker-disallowed-target.negative.stderr @@ -0,0 +1,2 @@ +error: `-C link-self-contained=-linker` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target + diff --git a/tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr b/tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr new file mode 100644 index 0000000000000..3424ecc2f077d --- /dev/null +++ b/tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr @@ -0,0 +1,2 @@ +error: `-C link-self-contained=+linker` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target + diff --git a/tests/ui/linking/link-self-contained-linker-disallowed-target.rs b/tests/ui/linking/link-self-contained-linker-disallowed-target.rs new file mode 100644 index 0000000000000..2bf332756815b --- /dev/null +++ b/tests/ui/linking/link-self-contained-linker-disallowed-target.rs @@ -0,0 +1,16 @@ +// Check that `-C link-self-contained=[+-]linker` is only stable on x64 linux, and needs `-Z +// unstable-options` elsewhere. + +// ignore-tidy-linelength + +//@ revisions: positive negative +//@ [negative] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=-linker --crate-type=rlib +//@ [negative] needs-llvm-components: x86 +//@ [positive] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=+linker --crate-type=rlib +//@ [positive] needs-llvm-components: x86 + +#![feature(no_core)] +#![no_core] + +//[negative]~? ERROR `-C link-self-contained=-linker` is unstable on the `x86_64-unknown-linux-musl` target +//[positive]~? ERROR `-C link-self-contained=+linker` is unstable on the `x86_64-unknown-linux-musl` target From 9155f8fbcff67543d52ecfa942717f9d458550f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Wed, 21 May 2025 08:35:43 +0000 Subject: [PATCH 12/16] expand documentation with x64 linux implementation notes --- src/doc/rustc/src/codegen-options/index.md | 27 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 21be7657635c9..69b0d7b60183b 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -249,9 +249,17 @@ It is also possible to enable or disable specific self-contained components in a You can pass a comma-separated list of self-contained components, individually enabled (`+component`) or disabled (`-component`). -Currently, only the `linker` granular option is stabilized: +Currently, only the `linker` granular option is stabilized, and only on the `x86_64-unknown-linux-gnu` target: - `linker`: toggle the usage of self-contained linker binaries (linker, dlltool, and their necessary libraries) +#### Implementation notes + +On the `x86_64-unknown-linux-gnu` target, when using the default linker flavor (using `cc` as the +linker driver) and linker features (to try using `lld`), `rustc` will try to use the self-contained +linker by passing a `-B /path/to/sysroot/` link argument to the driver to find `rust-lld` in the +sysroot. For backwards-compatibility, and to limit name and `PATH` collisions, this is done using a +shim executable (the `lld-wrapper` tool) that forwards execution to the `rust-lld` executable itself. + ## linker This flag controls which linker `rustc` invokes to link your code. It takes a @@ -275,13 +283,24 @@ The flag accepts a comma-separated list of features, individually enabled (`+fea (`-feature`). Currently only one is stable, and only on the `x86_64-unknown-linux-gnu` target: -- `lld`: to toggle using the lld linker, either the system-installed binary, or the self-contained - `rust-lld` linker (via the `-Clink-self-contained=+linker` flag). +- `lld`: to toggle trying to use the lld linker, either the system-installed binary, or the self-contained + `rust-lld` linker (via the [`-Clink-self-contained=+linker`](#link-self-contained) flag). For example, use: -- `-Clinker-features=+lld` to opt in to using the `lld` linker +- `-Clinker-features=+lld` to opt into using the `lld` linker, when possible (see the Implementation notes below) - `-Clinker-features=-lld` to opt out instead, for targets where it is configured as the default linker +#### Implementation notes + +On the `x86_64-unknown-linux-gnu` target, when using the default linker flavor (using `cc` as the +linker driver), `rustc` will try to use lld by passing a `-fuse-ld=lld` link argument to the driver. +`rustc` will also try to detect if that _causes_ an error during linking (for example, if GCC is too +old to understand the flag, and returns an error) and will then retry linking without this argument, +as a fallback. + +If the user _also_ passes a `-Clink-arg=-fuse-ld=$value`, both will be given to the linker +driver but the user's will be passed last, and would generally have priority over `rustc`'s. + ## linker-flavor This flag controls the linker flavor used by `rustc`. If a linker is given with From e659bd143d409343390472a35827d8201ff9aa99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 26 May 2025 09:34:51 +0000 Subject: [PATCH 13/16] update unstable linker-features test update use of unstable `-Zlinker-features` flag that is now stabilized. --- ...features-malformed.invalid_modifier.stderr | 2 +- ...eatures-malformed.invalid_separator.stderr | 2 +- .../linker-features-malformed.no_value.stderr | 2 +- tests/ui/linking/linker-features-malformed.rs | 26 +++++++++---------- ...-features-malformed.unknown_boolean.stderr | 2 +- ...es-malformed.unknown_modifier_value.stderr | 2 +- ...er-features-malformed.unknown_value.stderr | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr b/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr index 909b277089f42..d9ed65ad3e2e4 100644 --- a/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr +++ b/tests/ui/linking/linker-features-malformed.invalid_modifier.stderr @@ -1,2 +1,2 @@ -error: incorrect value `*lld` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +error: incorrect value `*lld` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected diff --git a/tests/ui/linking/linker-features-malformed.invalid_separator.stderr b/tests/ui/linking/linker-features-malformed.invalid_separator.stderr index 0f84898a77422..e950d8f3e8fe0 100644 --- a/tests/ui/linking/linker-features-malformed.invalid_separator.stderr +++ b/tests/ui/linking/linker-features-malformed.invalid_separator.stderr @@ -1,2 +1,2 @@ -error: incorrect value `-lld@+lld` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +error: incorrect value `-lld@+lld` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected diff --git a/tests/ui/linking/linker-features-malformed.no_value.stderr b/tests/ui/linking/linker-features-malformed.no_value.stderr index e93a4e79bb1d8..e03d3b34bb19c 100644 --- a/tests/ui/linking/linker-features-malformed.no_value.stderr +++ b/tests/ui/linking/linker-features-malformed.no_value.stderr @@ -1,2 +1,2 @@ -error: incorrect value `` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +error: incorrect value `` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected diff --git a/tests/ui/linking/linker-features-malformed.rs b/tests/ui/linking/linker-features-malformed.rs index 0bdcfa39920f0..627b8e68920e9 100644 --- a/tests/ui/linking/linker-features-malformed.rs +++ b/tests/ui/linking/linker-features-malformed.rs @@ -1,27 +1,27 @@ -//! Check that malformed `-Zlinker-features` flags are properly rejected. +//! Check that malformed `-Clinker-features` flags are properly rejected. //@ revisions: no_value -//@[no_value] compile-flags: -Zlinker-features= -//[no_value]~? ERROR incorrect value `` for unstable option `linker-features` +//@[no_value] compile-flags: -Clinker-features= +//[no_value]~? ERROR incorrect value `` for codegen option `linker-features` //@ revisions: invalid_modifier -//@[invalid_modifier] compile-flags: -Zlinker-features=*lld -//[invalid_modifier]~? ERROR incorrect value `*lld` for unstable option `linker-features` +//@[invalid_modifier] compile-flags: -Clinker-features=*lld +//[invalid_modifier]~? ERROR incorrect value `*lld` for codegen option `linker-features` //@ revisions: unknown_value -//@[unknown_value] compile-flags: -Zlinker-features=unknown -//[unknown_value]~? ERROR incorrect value `unknown` for unstable option `linker-features` +//@[unknown_value] compile-flags: -Clinker-features=unknown +//[unknown_value]~? ERROR incorrect value `unknown` for codegen option `linker-features` //@ revisions: unknown_modifier_value -//@[unknown_modifier_value] compile-flags: -Zlinker-features=-unknown -//[unknown_modifier_value]~? ERROR incorrect value `-unknown` for unstable option `linker-features` +//@[unknown_modifier_value] compile-flags: -Clinker-features=-unknown +//[unknown_modifier_value]~? ERROR incorrect value `-unknown` for codegen option `linker-features` //@ revisions: unknown_boolean -//@[unknown_boolean] compile-flags: -Zlinker-features=maybe -//[unknown_boolean]~? ERROR incorrect value `maybe` for unstable option `linker-features` +//@[unknown_boolean] compile-flags: -Clinker-features=maybe +//[unknown_boolean]~? ERROR incorrect value `maybe` for codegen option `linker-features` //@ revisions: invalid_separator -//@[invalid_separator] compile-flags: -Zlinker-features=-lld@+lld -//[invalid_separator]~? ERROR incorrect value `-lld@+lld` for unstable option `linker-features` +//@[invalid_separator] compile-flags: -Clinker-features=-lld@+lld +//[invalid_separator]~? ERROR incorrect value `-lld@+lld` for codegen option `linker-features` fn main() {} diff --git a/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr b/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr index 865738d0ccc1a..d82c2ea04b404 100644 --- a/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr +++ b/tests/ui/linking/linker-features-malformed.unknown_boolean.stderr @@ -1,2 +1,2 @@ -error: incorrect value `maybe` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +error: incorrect value `maybe` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected diff --git a/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr b/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr index 03b9620ca2633..59366e28e443b 100644 --- a/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr +++ b/tests/ui/linking/linker-features-malformed.unknown_modifier_value.stderr @@ -1,2 +1,2 @@ -error: incorrect value `-unknown` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +error: incorrect value `-unknown` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected diff --git a/tests/ui/linking/linker-features-malformed.unknown_value.stderr b/tests/ui/linking/linker-features-malformed.unknown_value.stderr index 566632a3df381..e8f6d5e637cf8 100644 --- a/tests/ui/linking/linker-features-malformed.unknown_value.stderr +++ b/tests/ui/linking/linker-features-malformed.unknown_value.stderr @@ -1,2 +1,2 @@ -error: incorrect value `unknown` for unstable option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected +error: incorrect value `unknown` for codegen option `linker-features` - a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld` was expected From 50170a3886e4125c320942ff06a41919bb058a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 6 Jun 2025 12:17:55 +0000 Subject: [PATCH 14/16] remove `-znostart-stop-gc` workaround Now that `#[used(linker)]` is the default on ELF, we don't need to use the `-znostart-stop-gc` link-arg workaround to match bfd's behavior when using lld. --- compiler/rustc_codegen_ssa/src/back/link.rs | 29 --------------------- 1 file changed, 29 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 54da4af614b68..838bff13a543d 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3346,35 +3346,6 @@ fn add_lld_args( // this, `wasm-component-ld`, which is overridden if this option is passed. if !sess.target.is_like_wasm { cmd.cc_arg("-fuse-ld=lld"); - - // On ELF platforms like at least x64 linux, GNU ld and LLD have opposite defaults on some - // section garbage-collection features. For example, the somewhat popular `linkme` crate and - // its dependents rely in practice on this difference: when using lld, they need `-z - // nostart-stop-gc` to prevent encapsulation symbols and sections from being - // garbage-collected. - // - // More information about all this can be found in: - // - https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order - // - https://lld.llvm.org/ELF/start-stop-gc - // - // So when using lld, we restore, for now, the traditional behavior to help migration, but - // will remove it in the future. - // Since this only disables an optimization, it shouldn't create issues, but is in theory - // slightly suboptimal. However, it: - // - doesn't have any visible impact on our benchmarks - // - reduces the need to disable lld for the crates that depend on this - // - // Note that lld can detect some cases where this difference is relied on, and emits a - // dedicated error to add this link arg. We could make use of this error to emit an FCW. As - // of writing this, we don't do it, because lld is already enabled by default on nightly - // without this mitigation: no working project would see the FCW, so we do this to help - // stabilization. - // - // FIXME: emit an FCW if linking fails due its absence, and then remove this link-arg in the - // future. - if sess.target.llvm_target == "x86_64-unknown-linux-gnu" { - cmd.link_arg("-znostart-stop-gc"); - } } if !flavor.is_gnu() { From ef99848fa6d355aefa5a2d306cc9b462557b824a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 17 Jun 2025 08:08:46 +0000 Subject: [PATCH 15/16] only stabilize `-Clinker-features=-lld` on x64 linux Some combinations of opt-ins and other flags need more work to be stabilized, so we can only stabilize the opt-outs. --- compiler/rustc_session/src/config.rs | 27 ++++++++----------- .../rust-lld-link-script-provide/rmake.rs | 1 + ...ures-lld-disallowed-target.positive.stderr | 2 -- .../linker-features-lld-disallowed-target.rs | 16 ----------- .../linking/linker-features-lld-disallowed.rs | 20 ++++++++++++++ ...es-lld-disallowed.unstable_positive.stderr | 2 ++ ...isallowed.unstable_target_negative.stderr} | 0 ...disallowed.unstable_target_positive.stderr | 2 ++ .../ui/linking/linker-features-unstable-cc.rs | 3 +-- 9 files changed, 37 insertions(+), 36 deletions(-) delete mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr delete mode 100644 tests/ui/linking/linker-features-lld-disallowed-target.rs create mode 100644 tests/ui/linking/linker-features-lld-disallowed.rs create mode 100644 tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr rename tests/ui/linking/{linker-features-lld-disallowed-target.negative.stderr => linker-features-lld-disallowed.unstable_target_negative.stderr} (100%) create mode 100644 tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 74ace6887e3a8..918216ea592c1 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -474,22 +474,17 @@ impl LinkerFeaturesCli { /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()` /// returns false. pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> { - // `-C linker-features=[-+]lld` is only stable on x64 linux. - let check_lld = |features: LinkerFeatures, polarity: &str| { - let has_lld = features.is_lld_enabled(); - if has_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { - return Err(format!( - "`-C linker-features={polarity}lld` is unstable on the `{target_tuple}` \ + // `-C linker-features=-lld` is only stable on x64 linux. + let has_minus_lld = self.disabled.is_lld_enabled(); + if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C linker-features=-lld` is unstable on the `{target_tuple}` \ target. The `-Z unstable-options` flag must also be passed to use it on this target", - )); - } - Ok(()) - }; - check_lld(self.enabled, "+")?; - check_lld(self.disabled, "-")?; + )); + } - // Since only lld is stable, any non-lld feature used is unstable, and that's an error. - let unstable_enabled = self.enabled - LinkerFeatures::LLD; + // Any `+lld` or non-lld feature used is unstable, and that's an error. + let unstable_enabled = self.enabled; let unstable_disabled = self.disabled - LinkerFeatures::LLD; if !unstable_enabled.union(unstable_disabled).is_empty() { let unstable_features: Vec<_> = unstable_enabled @@ -498,8 +493,8 @@ impl LinkerFeaturesCli { .chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap()))) .collect(); return Err(format!( - "the requested `-C linker-features={}` are unstable, and also require the \ - `-Z unstable-options` flag to be usable", + "`-C linker-features={}` is unstable, and also requires the \ + `-Z unstable-options` flag to be used", unstable_features.join(","), )); } diff --git a/tests/run-make/rust-lld-link-script-provide/rmake.rs b/tests/run-make/rust-lld-link-script-provide/rmake.rs index 0bd8f68116d01..c637dff9038b3 100644 --- a/tests/run-make/rust-lld-link-script-provide/rmake.rs +++ b/tests/run-make/rust-lld-link-script-provide/rmake.rs @@ -12,6 +12,7 @@ fn main() { .input("main.rs") .arg("-Clinker-features=+lld") .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") .link_arg("-Tscript.t") .run(); } diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr b/tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr deleted file mode 100644 index 2b10e6c714850..0000000000000 --- a/tests/ui/linking/linker-features-lld-disallowed-target.positive.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: `-C linker-features=+lld` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target - diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.rs b/tests/ui/linking/linker-features-lld-disallowed-target.rs deleted file mode 100644 index 9d4555c64e710..0000000000000 --- a/tests/ui/linking/linker-features-lld-disallowed-target.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Check that `-C linker-features=[+-]lld` is only stable on x64 linux, and needs `-Z -// unstable-options` elsewhere. - -// ignore-tidy-linelength - -//@ revisions: positive negative -//@ [negative] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib -//@ [negative] needs-llvm-components: x86 -//@ [positive] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=+lld --crate-type=rlib -//@ [positive] needs-llvm-components: x86 - -#![feature(no_core)] -#![no_core] - -//[negative]~? ERROR `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target -//[positive]~? ERROR `-C linker-features=+lld` is unstable on the `x86_64-unknown-linux-musl` target diff --git a/tests/ui/linking/linker-features-lld-disallowed.rs b/tests/ui/linking/linker-features-lld-disallowed.rs new file mode 100644 index 0000000000000..8aaa0c553e5bf --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed.rs @@ -0,0 +1,20 @@ +// Check that only `-C linker-features=-lld` is stable on x64 linux. Any other value or target, +// needs `-Z unstable-options`. + +// ignore-tidy-linelength + +//@ revisions: unstable_target_positive unstable_target_negative unstable_positive +//@ [unstable_target_negative] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=-lld --crate-type=rlib +//@ [unstable_target_negative] needs-llvm-components: x86 +//@ [unstable_target_positive] compile-flags: --target=x86_64-unknown-linux-musl -C linker-features=+lld --crate-type=rlib +//@ [unstable_target_positive] needs-llvm-components: x86 +//@ [unstable_positive] compile-flags: --target=x86_64-unknown-linux-gnu -C linker-features=+lld --crate-type=rlib +//@ [unstable_positive] needs-llvm-components: x86 + + +#![feature(no_core)] +#![no_core] + +//[unstable_target_negative]~? ERROR `-C linker-features=-lld` is unstable on the `x86_64-unknown-linux-musl` target +//[unstable_target_positive]~? ERROR `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options` +//[unstable_positive]~? ERROR `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options` diff --git a/tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr b/tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr new file mode 100644 index 0000000000000..09e7e4975c4f2 --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed.unstable_positive.stderr @@ -0,0 +1,2 @@ +error: `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options` flag to be used + diff --git a/tests/ui/linking/linker-features-lld-disallowed-target.negative.stderr b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_negative.stderr similarity index 100% rename from tests/ui/linking/linker-features-lld-disallowed-target.negative.stderr rename to tests/ui/linking/linker-features-lld-disallowed.unstable_target_negative.stderr diff --git a/tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr new file mode 100644 index 0000000000000..09e7e4975c4f2 --- /dev/null +++ b/tests/ui/linking/linker-features-lld-disallowed.unstable_target_positive.stderr @@ -0,0 +1,2 @@ +error: `-C linker-features=+lld` is unstable, and also requires the `-Z unstable-options` flag to be used + diff --git a/tests/ui/linking/linker-features-unstable-cc.rs b/tests/ui/linking/linker-features-unstable-cc.rs index 8ea84117c10c7..0ca3a6210301d 100644 --- a/tests/ui/linking/linker-features-unstable-cc.rs +++ b/tests/ui/linking/linker-features-unstable-cc.rs @@ -1,5 +1,4 @@ -// Check that only `-C linker-features=[+-]lld` is stable on x64 linux, and that other linker -// features require using `-Z unstable-options`. +// Check that non-lld linker features require using `-Z unstable-options`. // // Note that, currently, only `lld` is parsed on the CLI, but that other linker features can exist // internally (`cc`). From 1117bc1e6ce049495b0044dfe756afafc817d2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 17 Jun 2025 08:35:16 +0000 Subject: [PATCH 16/16] only stabilize `-Clink-self-contained=-linker` on x64 linux Some combinations of opt-ins and other flags need more work to be stabilized, so we can only stabilize the opt-outs. --- compiler/rustc_session/src/config.rs | 28 ++++++++----------- tests/run-make/rust-lld/rmake.rs | 2 +- ...d-linker-disallowed-target.positive.stderr | 2 -- ...self-contained-linker-disallowed-target.rs | 16 ----------- .../link-self-contained-linker-disallowed.rs | 19 +++++++++++++ ...linker-disallowed.unstable_positive.stderr | 2 ++ ...isallowed.unstable_target_negative.stderr} | 0 ...disallowed.unstable_target_positive.stderr | 2 ++ .../link-self-contained-unstable.crto.stderr | 2 +- .../link-self-contained-unstable.libc.stderr | 2 +- .../link-self-contained-unstable.mingw.stderr | 2 +- .../linking/link-self-contained-unstable.rs | 10 +++---- ...-self-contained-unstable.sanitizers.stderr | 2 +- ...link-self-contained-unstable.unwind.stderr | 2 +- 14 files changed, 45 insertions(+), 46 deletions(-) delete mode 100644 tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr delete mode 100644 tests/ui/linking/link-self-contained-linker-disallowed-target.rs create mode 100644 tests/ui/linking/link-self-contained-linker-disallowed.rs create mode 100644 tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr rename tests/ui/linking/{link-self-contained-linker-disallowed-target.negative.stderr => link-self-contained-linker-disallowed.unstable_target_negative.stderr} (100%) create mode 100644 tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 918216ea592c1..10caca609789c 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -375,28 +375,22 @@ impl LinkSelfContained { return Ok(()); } - // `-C link-self-contained=[-+]linker` is only stable on x64 linux. - let check_linker = |components: LinkSelfContainedComponents, polarity: &str| { - let has_linker = components.is_linker_enabled(); - if has_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { - return Err(format!( - "`-C link-self-contained={polarity}linker` is unstable on the `{target_tuple}` \ + // `-C link-self-contained=-linker` is only stable on x64 linux. + let has_minus_linker = self.disabled_components.is_linker_enabled(); + if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" { + return Err(format!( + "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \ target. The `-Z unstable-options` flag must also be passed to use it on this target", - )); - } - Ok(()) - }; - check_linker(self.enabled_components, "+")?; - check_linker(self.disabled_components, "-")?; + )); + } - // Since only the linker component is stable, any other component used is unstable, and - // that's an error. - let unstable_enabled = self.enabled_components - LinkSelfContainedComponents::LINKER; + // Any `+linker` or other component used is unstable, and that's an error. + let unstable_enabled = self.enabled_components; let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER; if !unstable_enabled.union(unstable_disabled).is_empty() { return Err(String::from( - "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`\ - /`+linker` are stable, the `-Z unstable-options` flag must also be passed to use \ + "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \ + are stable, the `-Z unstable-options` flag must also be passed to use \ the unstable values", )); } diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 556580f066f3e..932c2697ba04b 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -14,7 +14,7 @@ fn main() { rustc() .arg("-Clinker-features=+lld") .arg("-Clink-self-contained=+linker") - .arg("-Zunstable-options") // needed for targets other than `x86_64-unknown-linux-gnu` + .arg("-Zunstable-options") // the opt-ins are unstable .input("main.rs"), ); diff --git a/tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr b/tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr deleted file mode 100644 index 3424ecc2f077d..0000000000000 --- a/tests/ui/linking/link-self-contained-linker-disallowed-target.positive.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: `-C link-self-contained=+linker` is unstable on the `x86_64-unknown-linux-musl` target. The `-Z unstable-options` flag must also be passed to use it on this target - diff --git a/tests/ui/linking/link-self-contained-linker-disallowed-target.rs b/tests/ui/linking/link-self-contained-linker-disallowed-target.rs deleted file mode 100644 index 2bf332756815b..0000000000000 --- a/tests/ui/linking/link-self-contained-linker-disallowed-target.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Check that `-C link-self-contained=[+-]linker` is only stable on x64 linux, and needs `-Z -// unstable-options` elsewhere. - -// ignore-tidy-linelength - -//@ revisions: positive negative -//@ [negative] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=-linker --crate-type=rlib -//@ [negative] needs-llvm-components: x86 -//@ [positive] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=+linker --crate-type=rlib -//@ [positive] needs-llvm-components: x86 - -#![feature(no_core)] -#![no_core] - -//[negative]~? ERROR `-C link-self-contained=-linker` is unstable on the `x86_64-unknown-linux-musl` target -//[positive]~? ERROR `-C link-self-contained=+linker` is unstable on the `x86_64-unknown-linux-musl` target diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.rs b/tests/ui/linking/link-self-contained-linker-disallowed.rs new file mode 100644 index 0000000000000..c78bff94cf096 --- /dev/null +++ b/tests/ui/linking/link-self-contained-linker-disallowed.rs @@ -0,0 +1,19 @@ +// Check that only `-C link-self-contained=-linker` is stable on x64 linux. Any other value or +// target, needs `-Z unstable-options`. + +// ignore-tidy-linelength + +//@ revisions: unstable_target_positive unstable_target_negative unstable_positive +//@ [unstable_target_negative] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=-linker --crate-type=rlib +//@ [unstable_target_negative] needs-llvm-components: x86 +//@ [unstable_target_positive] compile-flags: --target=x86_64-unknown-linux-musl -C link-self-contained=+linker --crate-type=rlib +//@ [unstable_target_positive] needs-llvm-components: x86 +//@ [unstable_positive] compile-flags: --target=x86_64-unknown-linux-gnu -C link-self-contained=+linker --crate-type=rlib +//@ [unstable_positive] needs-llvm-components: x86 + +#![feature(no_core)] +#![no_core] + +//[unstable_target_negative]~? ERROR `-C link-self-contained=-linker` is unstable on the `x86_64-unknown-linux-musl` target +//[unstable_target_positive]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable +//[unstable_positive]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr new file mode 100644 index 0000000000000..4eb0ff04b65fa --- /dev/null +++ b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_positive.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/link-self-contained-linker-disallowed-target.negative.stderr b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_negative.stderr similarity index 100% rename from tests/ui/linking/link-self-contained-linker-disallowed-target.negative.stderr rename to tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_negative.stderr diff --git a/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr new file mode 100644 index 0000000000000..4eb0ff04b65fa --- /dev/null +++ b/tests/ui/linking/link-self-contained-linker-disallowed.unstable_target_positive.stderr @@ -0,0 +1,2 @@ +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values + diff --git a/tests/ui/linking/link-self-contained-unstable.crto.stderr b/tests/ui/linking/link-self-contained-unstable.crto.stderr index 086b22736bb6d..4eb0ff04b65fa 100644 --- a/tests/ui/linking/link-self-contained-unstable.crto.stderr +++ b/tests/ui/linking/link-self-contained-unstable.crto.stderr @@ -1,2 +1,2 @@ -error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values diff --git a/tests/ui/linking/link-self-contained-unstable.libc.stderr b/tests/ui/linking/link-self-contained-unstable.libc.stderr index 086b22736bb6d..4eb0ff04b65fa 100644 --- a/tests/ui/linking/link-self-contained-unstable.libc.stderr +++ b/tests/ui/linking/link-self-contained-unstable.libc.stderr @@ -1,2 +1,2 @@ -error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values diff --git a/tests/ui/linking/link-self-contained-unstable.mingw.stderr b/tests/ui/linking/link-self-contained-unstable.mingw.stderr index 086b22736bb6d..4eb0ff04b65fa 100644 --- a/tests/ui/linking/link-self-contained-unstable.mingw.stderr +++ b/tests/ui/linking/link-self-contained-unstable.mingw.stderr @@ -1,2 +1,2 @@ -error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values diff --git a/tests/ui/linking/link-self-contained-unstable.rs b/tests/ui/linking/link-self-contained-unstable.rs index 73ffaeac42b18..d4d381653a527 100644 --- a/tests/ui/linking/link-self-contained-unstable.rs +++ b/tests/ui/linking/link-self-contained-unstable.rs @@ -10,8 +10,8 @@ fn main() {} -//[crto]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable -//[libc]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable -//[unwind]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable -//[sanitizers]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable -//[mingw]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable +//[crto]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable +//[libc]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable +//[unwind]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable +//[sanitizers]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable +//[mingw]~? ERROR only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable diff --git a/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr b/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr index 086b22736bb6d..4eb0ff04b65fa 100644 --- a/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr +++ b/tests/ui/linking/link-self-contained-unstable.sanitizers.stderr @@ -1,2 +1,2 @@ -error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values diff --git a/tests/ui/linking/link-self-contained-unstable.unwind.stderr b/tests/ui/linking/link-self-contained-unstable.unwind.stderr index 086b22736bb6d..4eb0ff04b65fa 100644 --- a/tests/ui/linking/link-self-contained-unstable.unwind.stderr +++ b/tests/ui/linking/link-self-contained-unstable.unwind.stderr @@ -1,2 +1,2 @@ -error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values +error: only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` are stable, the `-Z unstable-options` flag must also be passed to use the unstable values