Skip to content

Commit 2e6d82c

Browse files
committed
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.
1 parent aa52711 commit 2e6d82c

File tree

10 files changed

+70
-20
lines changed

10 files changed

+70
-20
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1379,7 +1379,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
13791379
}
13801380
}
13811381

1382-
let features = sess.opts.unstable_opts.linker_features;
1382+
let features = sess.opts.cg.linker_features;
13831383

13841384
// linker and linker flavor specified via command line have precedence over what the target
13851385
// specification specifies

compiler/rustc_session/src/config.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ impl LinkSelfContained {
402402
}
403403
}
404404

405-
/// The different values that `-Z linker-features` can take on the CLI: a list of individually
405+
/// The different values that `-C linker-features` can take on the CLI: a list of individually
406406
/// enabled or disabled features used during linking.
407407
///
408408
/// 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 {
442442
_ => None,
443443
}
444444
}
445+
446+
/// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
447+
/// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
448+
/// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
449+
/// returns false.
450+
pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
451+
// `-C linker-features=-lld` is only stable on x64 linux.
452+
let has_minus_lld = self.disabled.is_lld_enabled();
453+
if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
454+
return Err(format!(
455+
"`-C linker-features=-lld` is unstable on the `{target_tuple}` \
456+
target. The `-Z unstable-options` flag must also be passed to use it on this target",
457+
));
458+
}
459+
460+
// Any `+lld` or non-lld feature used is unstable, and that's an error.
461+
let unstable_enabled = self.enabled;
462+
let unstable_disabled = self.disabled - LinkerFeatures::LLD;
463+
if !unstable_enabled.union(unstable_disabled).is_empty() {
464+
let unstable_features: Vec<_> = unstable_enabled
465+
.iter()
466+
.map(|f| format!("+{}", f.as_str().unwrap()))
467+
.chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap())))
468+
.collect();
469+
return Err(format!(
470+
"`-C linker-features={}` is unstable, and also requires the \
471+
`-Z unstable-options` flag to be used",
472+
unstable_features.join(","),
473+
));
474+
}
475+
476+
Ok(())
477+
}
445478
}
446479

447480
/// Used with `-Z assert-incr-state`.
@@ -2638,9 +2671,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26382671
}
26392672
}
26402673

2641-
if !nightly_options::is_unstable_enabled(matches)
2642-
&& cg.force_frame_pointers == FramePointer::NonLeaf
2643-
{
2674+
let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2675+
if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
26442676
early_dcx.early_fatal(
26452677
"`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
26462678
and a nightly compiler",
@@ -2650,7 +2682,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26502682
// For testing purposes, until we have more feedback about these options: ensure `-Z
26512683
// unstable-options` is required when using the unstable `-C link-self-contained` and `-C
26522684
// linker-flavor` options.
2653-
if !nightly_options::is_unstable_enabled(matches) {
2685+
if !unstable_options_enabled {
26542686
let uses_unstable_self_contained_option =
26552687
cg.link_self_contained.are_unstable_variants_set();
26562688
if uses_unstable_self_contained_option {
@@ -2706,6 +2738,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
27062738
let debuginfo = select_debuginfo(matches, &cg);
27072739
let debuginfo_compression = unstable_opts.debuginfo_compression;
27082740

2741+
if !unstable_options_enabled {
2742+
if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2743+
early_dcx.early_fatal(error);
2744+
}
2745+
}
2746+
27092747
let crate_name = matches.opt_str("crate-name");
27102748
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
27112749
// Parse any `-l` flags, which link to native libraries.

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,6 +2015,8 @@ options! {
20152015
on a C toolchain or linker installed in the system"),
20162016
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
20172017
"system linker to link outputs with"),
2018+
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
2019+
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
20182020
linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
20192021
"linker flavor"),
20202022
linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
@@ -2307,8 +2309,6 @@ options! {
23072309
"link native libraries in the linker invocation (default: yes)"),
23082310
link_only: bool = (false, parse_bool, [TRACKED],
23092311
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
2310-
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
2311-
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
23122312
lint_llvm_ir: bool = (false, parse_bool, [TRACKED],
23132313
"lint LLVM IR (default: no)"),
23142314
lint_mir: bool = (false, parse_bool, [UNTRACKED],

compiler/rustc_target/src/spec/mod.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ impl ToJson for LinkSelfContainedComponents {
725725
}
726726

727727
bitflags::bitflags! {
728-
/// The `-Z linker-features` components that can individually be enabled or disabled.
728+
/// The `-C linker-features` components that can individually be enabled or disabled.
729729
///
730730
/// They are feature flags intended to be a more flexible mechanism than linker flavors, and
731731
/// also to prevent a combinatorial explosion of flavors whenever a new linker feature is
@@ -756,7 +756,7 @@ bitflags::bitflags! {
756756
rustc_data_structures::external_bitflags_debug! { LinkerFeatures }
757757

758758
impl LinkerFeatures {
759-
/// Parses a single `-Z linker-features` well-known feature, not a set of flags.
759+
/// Parses a single `-C linker-features` well-known feature, not a set of flags.
760760
pub fn from_str(s: &str) -> Option<LinkerFeatures> {
761761
Some(match s {
762762
"cc" => LinkerFeatures::CC,
@@ -765,6 +765,17 @@ impl LinkerFeatures {
765765
})
766766
}
767767

768+
/// Return the linker feature name, as would be passed on the CLI.
769+
///
770+
/// Returns `None` if the bitflags aren't a singular component (but a mix of multiple flags).
771+
pub fn as_str(self) -> Option<&'static str> {
772+
Some(match self {
773+
LinkerFeatures::CC => "cc",
774+
LinkerFeatures::LLD => "lld",
775+
_ => return None,
776+
})
777+
}
778+
768779
/// Returns whether the `lld` linker feature is enabled.
769780
pub fn is_lld_enabled(self) -> bool {
770781
self.contains(LinkerFeatures::LLD)

tests/run-make/compressed-debuginfo-zstd/rmake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn prepare_and_check<F: FnOnce(&mut Rustc) -> &mut Rustc>(to_find: &str, prepare
2626
run_in_tmpdir(|| {
2727
let mut rustc = Rustc::new();
2828
rustc
29-
.arg("-Zlinker-features=+lld")
29+
.arg("-Clinker-features=+lld")
3030
.arg("-Clink-self-contained=+linker")
3131
.arg("-Zunstable-options")
3232
.arg("-Cdebuginfo=full")

tests/run-make/rust-lld-custom-target/rmake.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ fn main() {
2323
rustc()
2424
.crate_type("cdylib")
2525
.target("custom-target.json")
26-
.arg("-Zlinker-features=-lld")
26+
.arg("-Clinker-features=-lld")
27+
.arg("-Zunstable-options")
2728
.input("lib.rs"),
2829
);
2930
}

tests/run-make/rust-lld-link-script-provide/rmake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use run_make_support::rustc;
1010
fn main() {
1111
rustc()
1212
.input("main.rs")
13-
.arg("-Zlinker-features=+lld")
13+
.arg("-Clinker-features=+lld")
1414
.arg("-Clink-self-contained=+linker")
1515
.arg("-Zunstable-options")
1616
.link_arg("-Tscript.t")

tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist/rmake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ fn main() {
1212
assert_rustc_uses_lld(rustc().input("main.rs"));
1313

1414
// But it can still be disabled by turning the linker feature off.
15-
assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
15+
assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs"));
1616
}

tests/run-make/rust-lld-x86_64-unknown-linux-gnu/rmake.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ fn main() {
1616
assert_rustc_uses_lld(rustc().input("main.rs"));
1717

1818
// But it can still be disabled by turning the linker feature off.
19-
assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
19+
assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs"));
2020
}

tests/run-make/rust-lld/rmake.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,24 @@ fn main() {
1212
// asking the linker to display its version number with a link-arg.
1313
assert_rustc_uses_lld(
1414
rustc()
15-
.arg("-Zlinker-features=+lld")
15+
.arg("-Clinker-features=+lld")
1616
.arg("-Clink-self-contained=+linker")
1717
.arg("-Zunstable-options")
1818
.input("main.rs"),
1919
);
2020

2121
// It should not be used when we explicitly opt out of lld.
22-
assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
22+
assert_rustc_doesnt_use_lld(rustc().arg("-Clinker-features=-lld").input("main.rs"));
2323

2424
// While we're here, also check that the last linker feature flag "wins" when passed multiple
2525
// times to rustc.
2626
assert_rustc_uses_lld(
2727
rustc()
2828
.arg("-Clink-self-contained=+linker")
2929
.arg("-Zunstable-options")
30-
.arg("-Zlinker-features=-lld")
31-
.arg("-Zlinker-features=+lld")
32-
.arg("-Zlinker-features=-lld,+lld")
30+
.arg("-Clinker-features=-lld")
31+
.arg("-Clinker-features=+lld")
32+
.arg("-Clinker-features=-lld,+lld")
3333
.input("main.rs"),
3434
);
3535
}

0 commit comments

Comments
 (0)