Skip to content

Commit 9365844

Browse files
committed
Auto merge of rust-lang#138645 - Kobzol:stabilize-lld-test, r=<try>
[do not merge] Preparation for LLD stabilization This PR serves for testing test changes for stabilizing LLD. CC `@lqd` r? `@ghost` try-job: dist-x86_64-linux try-job: aarch64-gnu try-job: aarch64-gnu-debug try-job: x86_64-msvc-1 try-job: x86_64-msvc-2 try-job: x86_64-gnu try-job: x86_64-gnu-stable try-job: x86_64-gnu-aux try-job: x86_64-gnu-debug try-job: x86_64-apple-1 try-job: x86_64-apple-2 try-job: aarch64-apple
2 parents 243c5a3 + b92dfd0 commit 9365844

39 files changed

+317
-129
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
14201420
}
14211421
}
14221422

1423-
let features = sess.opts.unstable_opts.linker_features;
1423+
let features = sess.opts.cg.linker_features;
14241424

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

compiler/rustc_session/src/config.rs

+88-22
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,40 @@ impl LinkSelfContained {
367367
}
368368

369369
/// To help checking CLI usage while some of the values are unstable: returns whether one of the
370-
/// components was set individually. This would also require the `-Zunstable-options` flag, to
371-
/// be allowed.
372-
fn are_unstable_variants_set(&self) -> bool {
373-
let any_component_set =
374-
!self.enabled_components.is_empty() || !self.disabled_components.is_empty();
375-
self.explicitly_set.is_none() && any_component_set
370+
/// unstable components was set individually, for the given `TargetTuple`. This would also
371+
/// require the `-Zunstable-options` flag, to be allowed.
372+
fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
373+
if self.explicitly_set.is_some() {
374+
return Ok(());
375+
}
376+
377+
// `-C link-self-contained=[-+]linker` is only stable on x64 linux.
378+
let check_linker = |components: LinkSelfContainedComponents, polarity: &str| {
379+
let has_linker = components.is_linker_enabled();
380+
if has_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
381+
return Err(format!(
382+
"`-C link-self-contained={polarity}linker` is unstable on the `{target_tuple}` \
383+
target. The `-Z unstable-options` flag must also be passed to use it on this target",
384+
));
385+
}
386+
Ok(())
387+
};
388+
check_linker(self.enabled_components, "+")?;
389+
check_linker(self.disabled_components, "-")?;
390+
391+
// Since only the linker component is stable, any other component used is unstable, and
392+
// that's an error.
393+
let unstable_enabled = self.enabled_components - LinkSelfContainedComponents::LINKER;
394+
let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
395+
if !unstable_enabled.union(unstable_disabled).is_empty() {
396+
return Err(String::from(
397+
"only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`\
398+
/`+linker` are stable, the `-Z unstable-options` flag must also be passed to use \
399+
the unstable values",
400+
));
401+
}
402+
403+
Ok(())
376404
}
377405

378406
/// Returns whether the self-contained linker component was enabled on the CLI, using the
@@ -399,7 +427,7 @@ impl LinkSelfContained {
399427
}
400428
}
401429

402-
/// The different values that `-Z linker-features` can take on the CLI: a list of individually
430+
/// The different values that `-C linker-features` can take on the CLI: a list of individually
403431
/// enabled or disabled features used during linking.
404432
///
405433
/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
@@ -439,6 +467,44 @@ impl LinkerFeaturesCli {
439467
_ => None,
440468
}
441469
}
470+
471+
/// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
472+
/// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
473+
/// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
474+
/// returns false.
475+
pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
476+
// `-C linker-features=[-+]lld` is only stable on x64 linux.
477+
let check_lld = |features: LinkerFeatures, polarity: &str| {
478+
let has_lld = features.is_lld_enabled();
479+
if has_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
480+
return Err(format!(
481+
"`-C linker-features={polarity}lld` is unstable on the `{target_tuple}` \
482+
target. The `-Z unstable-options` flag must also be passed to use it on this target",
483+
));
484+
}
485+
Ok(())
486+
};
487+
check_lld(self.enabled, "+")?;
488+
check_lld(self.disabled, "-")?;
489+
490+
// Since only lld is stable, any non-lld feature used is unstable, and that's an error.
491+
let unstable_enabled = self.enabled - LinkerFeatures::LLD;
492+
let unstable_disabled = self.disabled - LinkerFeatures::LLD;
493+
if !unstable_enabled.union(unstable_disabled).is_empty() {
494+
let unstable_features: Vec<_> = unstable_enabled
495+
.iter()
496+
.map(|f| format!("+{}", f.as_str().unwrap()))
497+
.chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap())))
498+
.collect();
499+
return Err(format!(
500+
"the requested `-C linker-features={}` are unstable, and also require the \
501+
`-Z unstable-options` flag to be usable",
502+
unstable_features.join(","),
503+
));
504+
}
505+
506+
Ok(())
507+
}
442508
}
443509

444510
/// Used with `-Z assert-incr-state`.
@@ -2595,26 +2661,21 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
25952661
}
25962662
}
25972663

2598-
if !nightly_options::is_unstable_enabled(matches)
2599-
&& cg.force_frame_pointers == FramePointer::NonLeaf
2600-
{
2664+
let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2665+
if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
26012666
early_dcx.early_fatal(
26022667
"`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
26032668
and a nightly compiler",
26042669
)
26052670
}
26062671

2607-
// For testing purposes, until we have more feedback about these options: ensure `-Z
2608-
// unstable-options` is required when using the unstable `-C link-self-contained` and `-C
2609-
// linker-flavor` options.
2610-
if !nightly_options::is_unstable_enabled(matches) {
2611-
let uses_unstable_self_contained_option =
2612-
cg.link_self_contained.are_unstable_variants_set();
2613-
if uses_unstable_self_contained_option {
2614-
early_dcx.early_fatal(
2615-
"only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \
2616-
the `-Z unstable-options` flag must also be passed to use the unstable values",
2617-
);
2672+
let target_triple = parse_target_triple(early_dcx, matches);
2673+
2674+
// Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
2675+
// `-C linker-flavor` options.
2676+
if !unstable_options_enabled {
2677+
if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
2678+
early_dcx.early_fatal(error);
26182679
}
26192680

26202681
if let Some(flavor) = cg.linker_flavor {
@@ -2646,7 +2707,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26462707
let cg = cg;
26472708

26482709
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
2649-
let target_triple = parse_target_triple(early_dcx, matches);
26502710
let opt_level = parse_opt_level(early_dcx, matches, &cg);
26512711
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
26522712
// to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
@@ -2655,6 +2715,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26552715
let debuginfo = select_debuginfo(matches, &cg);
26562716
let debuginfo_compression = unstable_opts.debuginfo_compression;
26572717

2718+
if !unstable_options_enabled {
2719+
if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2720+
early_dcx.early_fatal(error);
2721+
}
2722+
}
2723+
26582724
let crate_name = matches.opt_str("crate-name");
26592725
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
26602726
// Parse any `-l` flags, which link to native libraries.

compiler/rustc_session/src/options.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1994,6 +1994,8 @@ options! {
19941994
on a C toolchain or linker installed in the system"),
19951995
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
19961996
"system linker to link outputs with"),
1997+
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
1998+
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
19971999
linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
19982000
"linker flavor"),
19992001
linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
@@ -2284,8 +2286,6 @@ options! {
22842286
"link native libraries in the linker invocation (default: yes)"),
22852287
link_only: bool = (false, parse_bool, [TRACKED],
22862288
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
2287-
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
2288-
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
22892289
lint_llvm_ir: bool = (false, parse_bool, [TRACKED],
22902290
"lint LLVM IR (default: no)"),
22912291
lint_mir: bool = (false, parse_bool, [UNTRACKED],

compiler/rustc_target/src/spec/mod.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ impl ToJson for LinkSelfContainedComponents {
721721
}
722722

723723
bitflags::bitflags! {
724-
/// The `-Z linker-features` components that can individually be enabled or disabled.
724+
/// The `-C linker-features` components that can individually be enabled or disabled.
725725
///
726726
/// They are feature flags intended to be a more flexible mechanism than linker flavors, and
727727
/// also to prevent a combinatorial explosion of flavors whenever a new linker feature is
@@ -752,7 +752,7 @@ bitflags::bitflags! {
752752
rustc_data_structures::external_bitflags_debug! { LinkerFeatures }
753753

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

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

src/bootstrap/src/core/build_steps/compile.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1326,9 +1326,7 @@ pub fn rustc_cargo_env(
13261326
}
13271327

13281328
// Enable rustc's env var for `rust-lld` when requested.
1329-
if builder.config.lld_enabled
1330-
&& (builder.config.channel == "dev" || builder.config.channel == "nightly")
1331-
{
1329+
if builder.config.lld_enabled {
13321330
cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1");
13331331
}
13341332

src/bootstrap/src/core/build_steps/test.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,13 @@ impl Step for Cargotest {
261261
.args(builder.config.test_args())
262262
.env("RUSTC", builder.rustc(compiler))
263263
.env("RUSTDOC", builder.rustdoc(compiler));
264-
add_rustdoc_cargo_linker_args(&mut cmd, builder, compiler.host, LldThreads::No);
264+
add_rustdoc_cargo_linker_args(
265+
&mut cmd,
266+
builder,
267+
compiler.host,
268+
LldThreads::No,
269+
compiler.stage,
270+
);
265271
cmd.delay_failure().run(builder);
266272
}
267273
}
@@ -839,7 +845,7 @@ impl Step for RustdocTheme {
839845
.env("CFG_RELEASE_CHANNEL", &builder.config.channel)
840846
.env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
841847
.env("RUSTC_BOOTSTRAP", "1");
842-
cmd.args(linker_args(builder, self.compiler.host, LldThreads::No));
848+
cmd.args(linker_args(builder, self.compiler.host, LldThreads::No, self.compiler.stage));
843849

844850
cmd.delay_failure().run(builder);
845851
}
@@ -1015,7 +1021,13 @@ impl Step for RustdocGUI {
10151021
cmd.env("RUSTDOC", builder.rustdoc(self.compiler))
10161022
.env("RUSTC", builder.rustc(self.compiler));
10171023

1018-
add_rustdoc_cargo_linker_args(&mut cmd, builder, self.compiler.host, LldThreads::No);
1024+
add_rustdoc_cargo_linker_args(
1025+
&mut cmd,
1026+
builder,
1027+
self.compiler.host,
1028+
LldThreads::No,
1029+
self.compiler.stage,
1030+
);
10191031

10201032
for path in &builder.paths {
10211033
if let Some(p) = helpers::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) {
@@ -1784,7 +1796,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
17841796
}
17851797

17861798
let mut hostflags = flags.clone();
1787-
hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No));
1799+
hostflags.extend(linker_flags(builder, compiler.host, LldThreads::No, compiler.stage));
17881800

17891801
let mut targetflags = flags;
17901802

src/bootstrap/src/core/builder/cargo.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl Cargo {
116116
// as they don't invoke rustc at all.
117117
Kind::Clean | Kind::Suggest | Kind::Format | Kind::Setup => {}
118118
_ => {
119-
cargo.configure_linker(builder);
119+
cargo.configure_linker(builder, mode);
120120
}
121121
}
122122

@@ -205,7 +205,7 @@ impl Cargo {
205205
self
206206
}
207207

208-
fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
208+
fn configure_linker(&mut self, builder: &Builder<'_>, mode: Mode) -> &mut Cargo {
209209
let target = self.target;
210210
let compiler = self.compiler;
211211

@@ -260,7 +260,15 @@ impl Cargo {
260260
}
261261
}
262262

263-
for arg in linker_args(builder, compiler.host, LldThreads::Yes) {
263+
// When determining flags for the host (build scripts/proc macros),
264+
// we use the snapshot compiler when building `Mode::Std` tools, and
265+
// the current compiler when building anything else.
266+
// We need to determine the current stage here to pass proper linker args (e.g. -C vs -Z)
267+
// to the compiler used to compile build scripts.
268+
// This should stay synchronized with the [cargo] function.
269+
let host_stage = if mode == Mode::Std { 0 } else { compiler.stage };
270+
271+
for arg in linker_args(builder, compiler.host, LldThreads::Yes, host_stage) {
264272
self.hostflags.arg(&arg);
265273
}
266274

@@ -270,10 +278,10 @@ impl Cargo {
270278
}
271279
// We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
272280
// `linker_args` here.
273-
for flag in linker_flags(builder, target, LldThreads::Yes) {
281+
for flag in linker_flags(builder, target, LldThreads::Yes, compiler.stage) {
274282
self.rustflags.arg(&flag);
275283
}
276-
for arg in linker_args(builder, target, LldThreads::Yes) {
284+
for arg in linker_args(builder, target, LldThreads::Yes, compiler.stage) {
277285
self.rustdocflags.arg(&arg);
278286
}
279287

src/bootstrap/src/core/builder/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,7 @@ impl<'a> Builder<'a> {
14791479
cmd.arg("-Dwarnings");
14801480
}
14811481
cmd.arg("-Znormalize-docs");
1482-
cmd.args(linker_args(self, compiler.host, LldThreads::Yes));
1482+
cmd.args(linker_args(self, compiler.host, LldThreads::Yes, compiler.stage));
14831483
cmd
14841484
}
14851485

src/bootstrap/src/core/config/config.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -2469,7 +2469,6 @@ impl Config {
24692469
// build our internal lld and use it as the default linker, by setting the `rust.lld` config
24702470
// to true by default:
24712471
// - on the `x86_64-unknown-linux-gnu` target
2472-
// - on the `dev` and `nightly` channels
24732472
// - when building our in-tree llvm (i.e. the target has not set an `llvm-config`), so that
24742473
// we're also able to build the corresponding lld
24752474
// - or when using an external llvm that's downloaded from CI, which also contains our prebuilt
@@ -2478,10 +2477,7 @@ impl Config {
24782477
// thus, disabled
24792478
// - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
24802479
// when the config sets `rust.lld = false`
2481-
if config.build.triple == "x86_64-unknown-linux-gnu"
2482-
&& config.hosts == [config.build]
2483-
&& (config.channel == "dev" || config.channel == "nightly")
2484-
{
2480+
if config.build.triple == "x86_64-unknown-linux-gnu" && config.hosts == [config.build] {
24852481
let no_llvm_config = config
24862482
.target_config
24872483
.get(&config.build)

0 commit comments

Comments
 (0)