diff options
| author | Rémy Rakic <remy.rakic+github@gmail.com> | 2025-07-08 09:01:25 +0000 |
|---|---|---|
| committer | Rémy Rakic <remy.rakic+github@gmail.com> | 2025-07-08 09:04:21 +0000 |
| commit | 2e6d82c9c96348a2f7dafd1a3337287408fc9751 (patch) | |
| tree | 407f868c43b74b5fcdca88329434e8125561934b | |
| parent | aa527115432df082f3c9e4d2459acb7bb02ed5a6 (diff) | |
| download | rust-2e6d82c9c96348a2f7dafd1a3337287408fc9751.tar.gz rust-2e6d82c9c96348a2f7dafd1a3337287408fc9751.zip | |
stabilize `-Clinker-features=-lld` on x64 linux
This stabilizes a subset of the `-Clinker-features` components on x64 linux: the lld opt-out. The opt-in is not stabilized, as interactions with other stable flags require more internal work, but are not needed for stabilizing using rust-lld by default. Similarly, since we only switch to rust-lld on x64 linux, the opt-out is only stabilized there. Other targets still require `-Zunstable-options` to use it.
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 48 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mod.rs | 15 | ||||
| -rw-r--r-- | tests/run-make/compressed-debuginfo-zstd/rmake.rs | 2 | ||||
| -rw-r--r-- | tests/run-make/rust-lld-custom-target/rmake.rs | 3 | ||||
| -rw-r--r-- | tests/run-make/rust-lld-link-script-provide/rmake.rs | 2 | ||||
| -rw-r--r-- | tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs | 2 | ||||
| -rw-r--r-- | tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs | 2 | ||||
| -rw-r--r-- | tests/run-make/rust-lld/rmake.rs | 10 |
10 files changed, 70 insertions, 20 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 343cb0eeca9..34328687e3f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1379,7 +1379,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 4627c2978fc..76969a0c409 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -402,7 +402,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 @@ -442,6 +442,39 @@ impl LinkerFeaturesCli { _ => None, } } + + /// 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> { + // `-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", + )); + } + + // 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 + .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={}` is unstable, and also requires the \ + `-Z unstable-options` flag to be used", + unstable_features.join(","), + )); + } + + Ok(()) + } } /// Used with `-Z assert-incr-state`. @@ -2638,9 +2671,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", @@ -2650,7 +2682,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 { @@ -2706,6 +2738,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/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ecd82c0cc01..626262c8442 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2015,6 +2015,8 @@ options! { on a C toolchain or linker installed in the system"), linker: Option<PathBuf> = (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<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED], "linker flavor"), linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled, @@ -2307,8 +2309,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 5346b206a17..4bc0d88a910 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -725,7 +725,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 @@ -756,7 +756,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<LinkerFeatures> { Some(match s { "cc" => LinkerFeatures::CC, @@ -765,6 +765,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/run-make/compressed-debuginfo-zstd/rmake.rs b/tests/run-make/compressed-debuginfo-zstd/rmake.rs index cd8cf223047..8d7e5c089da 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<F: FnOnce(&mut Rustc) -> &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 e2b065a10b1..90ba424ffe9 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -23,7 +23,8 @@ fn main() { rustc() .crate_type("cdylib") .target("custom-target.json") - .arg("-Zlinker-features=-lld") + .arg("-Clinker-features=-lld") + .arg("-Zunstable-options") .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 e78a411bc15..c637dff9038 100644 --- a/tests/run-make/rust-lld-link-script-provide/rmake.rs +++ b/tests/run-make/rust-lld-link-script-provide/rmake.rs @@ -10,7 +10,7 @@ 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") 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 c26f82b7d37..c315d36a39d 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 e71a47f11e2..00415d27aaf 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 9470f5d0be1..2b914f19ac0 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"), ); } |
