Skip to content

Commit 0c623eb

Browse files
committed
Auto merge of #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
2 parents 5337252 + 49cabaa commit 0c623eb

File tree

32 files changed

+214
-104
lines changed

32 files changed

+214
-104
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1414,7 +1414,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
14141414
}
14151415
}
14161416

1417-
let features = sess.opts.unstable_opts.linker_features;
1417+
let features = sess.opts.cg.linker_features;
14181418

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

compiler/rustc_session/src/config.rs

+57-9
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,14 @@ impl LinkSelfContained {
362362
/// components was set individually. This would also require the `-Zunstable-options` flag, to
363363
/// be allowed.
364364
fn are_unstable_variants_set(&self) -> bool {
365-
let any_component_set =
366-
!self.enabled_components.is_empty() || !self.disabled_components.is_empty();
367-
self.explicitly_set.is_none() && any_component_set
365+
if self.explicitly_set.is_some() {
366+
return false;
367+
}
368+
369+
// Only the linker component is stable, anything else is thus unstable.
370+
let mentioned_components = self.enabled_components.union(self.disabled_components);
371+
let unstable_components = mentioned_components - LinkSelfContainedComponents::LINKER;
372+
!unstable_components.is_empty()
368373
}
369374

370375
/// Returns whether the self-contained linker component was enabled on the CLI, using the
@@ -391,7 +396,7 @@ impl LinkSelfContained {
391396
}
392397
}
393398

394-
/// The different values that `-Z linker-features` can take on the CLI: a list of individually
399+
/// The different values that `-C linker-features` can take on the CLI: a list of individually
395400
/// enabled or disabled features used during linking.
396401
///
397402
/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
@@ -431,6 +436,44 @@ impl LinkerFeaturesCli {
431436
_ => None,
432437
}
433438
}
439+
440+
/// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
441+
/// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
442+
/// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
443+
/// returns false.
444+
pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
445+
// `-C linker-features=[-+]lld` is only stable on x64 linux.
446+
let check_lld = |features: LinkerFeatures, polarity: &str| {
447+
let has_lld = features.is_lld_enabled();
448+
if has_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
449+
return Err(format!(
450+
"`-C linker-features={polarity}lld` is unstable on the `{target_tuple}` \
451+
target. The `-Z unstable-options` flag must also be passed to use it on this target",
452+
));
453+
}
454+
Ok(())
455+
};
456+
check_lld(self.enabled, "+")?;
457+
check_lld(self.disabled, "-")?;
458+
459+
// Since only lld is stable, any non-lld feature used is unstable, and that's an error.
460+
let unstable_enabled = self.enabled - LinkerFeatures::LLD;
461+
let unstable_disabled = self.disabled - LinkerFeatures::LLD;
462+
if !unstable_enabled.union(unstable_disabled).is_empty() {
463+
let unstable_features: Vec<_> = unstable_enabled
464+
.iter()
465+
.map(|f| format!("+{}", f.as_str().unwrap()))
466+
.chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap())))
467+
.collect();
468+
return Err(format!(
469+
"the requested `-C linker-features={}` are unstable, and also require the \
470+
`-Z unstable-options` flag to be usable",
471+
unstable_features.join(","),
472+
));
473+
}
474+
475+
Ok(())
476+
}
434477
}
435478

436479
/// Used with `-Z assert-incr-state`.
@@ -2486,9 +2529,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
24862529
}
24872530
}
24882531

2489-
if !nightly_options::is_unstable_enabled(matches)
2490-
&& cg.force_frame_pointers == FramePointer::NonLeaf
2491-
{
2532+
let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2533+
if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
24922534
early_dcx.early_fatal(
24932535
"`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
24942536
and a nightly compiler",
@@ -2498,12 +2540,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
24982540
// For testing purposes, until we have more feedback about these options: ensure `-Z
24992541
// unstable-options` is required when using the unstable `-C link-self-contained` and `-C
25002542
// linker-flavor` options.
2501-
if !nightly_options::is_unstable_enabled(matches) {
2543+
if !unstable_options_enabled {
25022544
let uses_unstable_self_contained_option =
25032545
cg.link_self_contained.are_unstable_variants_set();
25042546
if uses_unstable_self_contained_option {
25052547
early_dcx.early_fatal(
2506-
"only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \
2548+
"only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker`/`+linker` are stable, \
25072549
the `-Z unstable-options` flag must also be passed to use the unstable values",
25082550
);
25092551
}
@@ -2546,6 +2588,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
25462588
let debuginfo = select_debuginfo(matches, &cg);
25472589
let debuginfo_compression = unstable_opts.debuginfo_compression;
25482590

2591+
if !unstable_options_enabled {
2592+
if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2593+
early_dcx.early_fatal(error);
2594+
}
2595+
}
2596+
25492597
let crate_name = matches.opt_str("crate-name");
25502598
let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
25512599
// 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
@@ -1988,6 +1988,8 @@ options! {
19881988
on a C toolchain or linker installed in the system"),
19891989
linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
19901990
"system linker to link outputs with"),
1991+
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
1992+
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
19911993
linker_flavor: Option<LinkerFlavorCli> = (None, parse_linker_flavor, [UNTRACKED],
19921994
"linker flavor"),
19931995
linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
@@ -2273,8 +2275,6 @@ options! {
22732275
"link native libraries in the linker invocation (default: yes)"),
22742276
link_only: bool = (false, parse_bool, [TRACKED],
22752277
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
2276-
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
2277-
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
22782278
lint_llvm_ir: bool = (false, parse_bool, [TRACKED],
22792279
"lint LLVM IR (default: no)"),
22802280
lint_mir: bool = (false, parse_bool, [UNTRACKED],

compiler/rustc_target/src/spec/mod.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ impl ToJson for LinkSelfContainedComponents {
718718
}
719719

720720
bitflags::bitflags! {
721-
/// The `-Z linker-features` components that can individually be enabled or disabled.
721+
/// The `-C linker-features` components that can individually be enabled or disabled.
722722
///
723723
/// They are feature flags intended to be a more flexible mechanism than linker flavors, and
724724
/// also to prevent a combinatorial explosion of flavors whenever a new linker feature is
@@ -749,7 +749,7 @@ bitflags::bitflags! {
749749
rustc_data_structures::external_bitflags_debug! { LinkerFeatures }
750750

751751
impl LinkerFeatures {
752-
/// Parses a single `-Z linker-features` well-known feature, not a set of flags.
752+
/// Parses a single `-C linker-features` well-known feature, not a set of flags.
753753
pub fn from_str(s: &str) -> Option<LinkerFeatures> {
754754
Some(match s {
755755
"cc" => LinkerFeatures::CC,
@@ -758,6 +758,17 @@ impl LinkerFeatures {
758758
})
759759
}
760760

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

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -1331,9 +1331,7 @@ pub fn rustc_cargo_env(
13311331
}
13321332

13331333
// Enable rustc's env var for `rust-lld` when requested.
1334-
if builder.config.lld_enabled
1335-
&& (builder.config.channel == "dev" || builder.config.channel == "nightly")
1336-
{
1334+
if builder.config.lld_enabled {
13371335
cargo.env("CFG_USE_SELF_CONTAINED_LINKER", "1");
13381336
}
13391337

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

+1-5
Original file line numberDiff line numberDiff line change
@@ -2356,7 +2356,6 @@ impl Config {
23562356
// build our internal lld and use it as the default linker, by setting the `rust.lld` config
23572357
// to true by default:
23582358
// - on the `x86_64-unknown-linux-gnu` target
2359-
// - on the `dev` and `nightly` channels
23602359
// - when building our in-tree llvm (i.e. the target has not set an `llvm-config`), so that
23612360
// we're also able to build the corresponding lld
23622361
// - or when using an external llvm that's downloaded from CI, which also contains our prebuilt
@@ -2365,10 +2364,7 @@ impl Config {
23652364
// thus, disabled
23662365
// - similarly, lld will not be built nor used by default when explicitly asked not to, e.g.
23672366
// when the config sets `rust.lld = false`
2368-
if config.build.triple == "x86_64-unknown-linux-gnu"
2369-
&& config.hosts == [config.build]
2370-
&& (config.channel == "dev" || config.channel == "nightly")
2371-
{
2367+
if config.build.triple == "x86_64-unknown-linux-gnu" && config.hosts == [config.build] {
23722368
let no_llvm_config = config
23732369
.target_config
23742370
.get(&config.build)

src/doc/rustc/src/codegen-options/index.md

+30-4
Original file line numberDiff line numberDiff line change
@@ -218,15 +218,22 @@ coverage measurement. Its use is not recommended.
218218

219219
## link-self-contained
220220

221-
On `windows-gnu`, `linux-musl`, and `wasi` targets, this flag controls whether the
222-
linker will use libraries and objects shipped with Rust instead of those in the system.
223-
It takes one of the following values:
221+
This flag controls whether the linker will use libraries and objects shipped with Rust instead
222+
of those in the system. This allows overriding cases when detection fails or user wants to use shipped
223+
libraries.
224+
225+
You can enable or disable the usage of any self-contained objects using one of the following values:
224226

225227
* no value: rustc will use heuristic to disable self-contained mode if system has necessary tools.
226228
* `y`, `yes`, `on`, `true`: use only libraries/objects shipped with Rust.
227229
* `n`, `no`, `off` or `false`: rely on the user or the linker to provide non-Rust libraries/objects.
228230

229-
This allows overriding cases when detection fails or user wants to use shipped libraries.
231+
It is also possible to enable or disable specific self-contained objects in a more granular way.
232+
You can pass a comma-separated list of self-contained objects, individually enabled (`+object`) or
233+
disabled (`-object`).
234+
235+
Currently, only the `linker` granular option is stabilized:
236+
- `linker`: toggle the usage of self-contained linker objects (linker, dlltool, and their necessary libraries)
230237

231238
## linker
232239

@@ -235,6 +242,25 @@ path to the linker executable. If this flag is not specified, the linker will
235242
be inferred based on the target. See also the [linker-flavor](#linker-flavor)
236243
flag for another way to specify the linker.
237244

245+
## linker-features
246+
247+
The `-Clinker-features` flag allows enabling or disabling specific features used during linking.
248+
249+
These feature flags are a flexible extension mechanism that is complementary to linker flavors,
250+
designed to avoid the combinatorial explosion of having to create a new set of flavors for each
251+
linker feature we'd want to use.
252+
253+
The flag accepts a comma-separated list of features, individually enabled (`+feature`) or disabled
254+
(`-feature`).
255+
256+
Currently only one is stable, and only on the `x86_64-unknown-linux-gnu` target:
257+
- `lld`: to toggle using the lld linker, either the system-installed binary, or the self-contained
258+
`rust-lld` linker (via the `-Clink-self-contained=+linker` flag).
259+
260+
For example, use:
261+
- `-Clinker-features=+lld` to opt in to using the `lld` linker
262+
- `-Clinker-features=-lld` to opt out instead, for targets where it is configured as the default linker
263+
238264
## linker-flavor
239265

240266
This flag controls the linker flavor used by `rustc`. If a linker is given with

src/doc/unstable-book/src/compiler-flags/codegen-options.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ instead of those in the system. The stable boolean values for this flag are coar
5151
- `mingw`: other MinGW libs and Windows import libs
5252

5353
Out of the above self-contained linking components, `linker` is the only one currently implemented
54-
(beyond parsing the CLI options).
54+
(beyond parsing the CLI options) and stabilized.
5555

5656
It refers to the LLD linker, built from the same LLVM revision used by rustc (named `rust-lld` to
5757
avoid naming conflicts), that is distributed via `rustup` with the compiler (and is used by default
58-
for the wasm targets). One can also opt-in to use it by combining this flag with an appropriate
58+
for the wasm targets). One can also opt in to use it by combining this flag with an appropriate
5959
linker flavor: for example, `-Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker` will use the
6060
toolchain's `rust-lld` as the linker.

src/doc/unstable-book/src/compiler-flags/linker-features.md

-35
This file was deleted.

src/tools/opt-dist/src/tests.rs

+3
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,10 @@ llvm-config = "{llvm_config}"
104104
"tests/incremental",
105105
"tests/mir-opt",
106106
"tests/pretty",
107+
// Make sure that we don't use too new GLIBC symbols on x64
107108
"tests/run-make/glibc-symbols-x86_64-unknown-linux-gnu",
109+
// Make sure that we use LLD by default on x64
110+
"tests/run-make/rust-lld-x86_64-unknown-linux-gnu-dist",
108111
"tests/ui",
109112
"tests/crashes",
110113
];

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ 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")
31-
.arg("-Zunstable-options")
3231
.arg("-Cdebuginfo=full")
3332
.input("main.rs");
3433
prepare_rustc(&mut rustc).run();

tests/run-make/rust-lld-by-default-beta-stable/main.rs

-1
This file was deleted.

tests/run-make/rust-lld-by-default-beta-stable/rmake.rs

-14
This file was deleted.

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

+2-1
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

+1-1
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")
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
1-
// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu` on the nightly
2-
// channel, and that it can also be turned off with a CLI flag.
1+
// Ensure that rust-lld is used as the default linker on `x86_64-unknown-linux-gnu`
2+
// dist artifacts and that it can also be turned off with a CLI flag.
33

4-
//@ needs-rust-lld
5-
//@ ignore-beta
6-
//@ ignore-stable
4+
//@ only-dist
75
//@ only-x86_64-unknown-linux-gnu
86

97
use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
108
use run_make_support::rustc;
119

1210
fn main() {
13-
// A regular compilation should use rust-lld by default. We'll check that by asking the linker
14-
// to display its version number with a link-arg.
11+
// A regular compilation should use rust-lld by default.
1512
assert_rustc_uses_lld(rustc().input("main.rs"));
1613

1714
// But it can still be disabled by turning the linker feature off.
18-
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"));
1916
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Test linking using `cc` with `rust-lld`, which is on by default on the x86_64-unknown-linux-gnu
2+
// target.
3+
// See https://github.com/rust-lang/compiler-team/issues/510 for more info
4+
5+
fn main() {}

0 commit comments

Comments
 (0)