Skip to content

Commit 07f22cc

Browse files
committed
add -Z linker-features to toggle lld on the CLI
but don't expose `+/-cc` yet
1 parent 34b7dff commit 07f22cc

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

compiler/rustc_session/src/config.rs

+43-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_feature::UnstableFeatures;
1818
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
1919
use rustc_span::source_map::FilePathMapping;
2020
use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
21-
use rustc_target::spec::LinkSelfContainedComponents;
21+
use rustc_target::spec::{LinkSelfContainedComponents, LinkerFeatures};
2222
use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple};
2323
use std::collections::btree_map::{
2424
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
@@ -292,6 +292,48 @@ impl LinkSelfContained {
292292
}
293293
}
294294

295+
/// The different values that `-Z linker-features` can take on the CLI: a list of individually
296+
/// enabled or disabled features used during linking.
297+
///
298+
/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
299+
/// used to turn `LinkerFeatures` on or off, without needing to change the linker flavor:
300+
/// - using the system lld, or the self-contained `rust-lld` linker
301+
/// - using a C/C++ compiler to drive the linker (not yet exposed on the CLI)
302+
/// - etc.
303+
#[derive(Default, Copy, Clone, PartialEq, Debug)]
304+
pub struct LinkerFeaturesCli {
305+
/// The linker features that are enabled on the CLI, using the `+feature` syntax.
306+
pub enabled: LinkerFeatures,
307+
308+
/// The linker features that are disabled on the CLI, using the `-feature` syntax.
309+
pub disabled: LinkerFeatures,
310+
}
311+
312+
impl LinkerFeaturesCli {
313+
/// Accumulates an enabled or disabled feature as specified on the CLI, if possible.
314+
/// For example: `+lld`, and `-lld`.
315+
pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
316+
// Duplicate flags are reduced as we go, the last occurrence wins:
317+
// `+feature,-feature,+feature` only enables the feature, and does not record it as both
318+
// enabled and disabled on the CLI.
319+
// We also only expose `+/-lld` at the moment, as it's currenty the only implemented linker
320+
// feature and toggling `LinkerFeatures::CC` would be a noop.
321+
match feature {
322+
"+lld" => {
323+
self.enabled.insert(LinkerFeatures::LLD);
324+
self.disabled.remove(LinkerFeatures::LLD);
325+
Some(())
326+
}
327+
"-lld" => {
328+
self.disabled.insert(LinkerFeatures::LLD);
329+
self.enabled.remove(LinkerFeatures::LLD);
330+
Some(())
331+
}
332+
_ => None,
333+
}
334+
}
335+
}
336+
295337
/// Used with `-Z assert-incr-state`.
296338
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
297339
pub enum IncrementalStateAssertion {

compiler/rustc_session/src/options.rs

+20
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ mod desc {
426426
"one of supported split dwarf modes (`split` or `single`)";
427427
pub const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
428428
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
429+
pub const parse_linker_features: &str =
430+
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
429431
pub const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
430432
pub const parse_stack_protector: &str =
431433
"one of (`none` (default), `basic`, `strong`, or `all`)";
@@ -1269,6 +1271,22 @@ mod parse {
12691271
true
12701272
}
12711273

1274+
/// Parse a comma-separated list of enabled and disabled linker features.
1275+
pub(crate) fn parse_linker_features(slot: &mut LinkerFeaturesCli, v: Option<&str>) -> bool {
1276+
match v {
1277+
Some(s) => {
1278+
for feature in s.split(',') {
1279+
if slot.handle_cli_feature(feature).is_none() {
1280+
return false;
1281+
}
1282+
}
1283+
1284+
true
1285+
}
1286+
None => false,
1287+
}
1288+
}
1289+
12721290
pub(crate) fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
12731291
match v {
12741292
Some("command") => *slot = Some(WasiExecModel::Command),
@@ -1721,6 +1739,8 @@ options! {
17211739
"link native libraries in the linker invocation (default: yes)"),
17221740
link_only: bool = (false, parse_bool, [TRACKED],
17231741
"link the `.rlink` file generated by `-Z no-link` (default: no)"),
1742+
linker_features: LinkerFeaturesCli = (LinkerFeaturesCli::default(), parse_linker_features, [UNTRACKED],
1743+
"a comma-separated list of linker features to enable (+) or disable (-): `lld`"),
17241744
lint_mir: bool = (false, parse_bool, [UNTRACKED],
17251745
"lint MIR before and after each transformation"),
17261746
llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED],

0 commit comments

Comments
 (0)