add -Z linker-features to toggle lld on the CLI

but don't expose `+/-cc` yet
This commit is contained in:
Rémy Rakic 2024-04-08 21:40:44 +00:00
parent 695aac2c02
commit 2398d8cf08
2 changed files with 63 additions and 1 deletions

View File

@ -18,7 +18,7 @@ use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
use rustc_span::source_map::FilePathMapping;
use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
use rustc_target::spec::LinkSelfContainedComponents;
use rustc_target::spec::{LinkSelfContainedComponents, LinkerFeatures};
use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple};
use std::collections::btree_map::{
Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
@ -292,6 +292,48 @@ impl LinkSelfContained {
}
}
/// The different values that `-Z 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
/// used to turn `LinkerFeatures` on or off, without needing to change the linker flavor:
/// - using the system lld, or the self-contained `rust-lld` linker
/// - using a C/C++ compiler to drive the linker (not yet exposed on the CLI)
/// - etc.
#[derive(Default, Copy, Clone, PartialEq, Debug)]
pub struct LinkerFeaturesCli {
/// The linker features that are enabled on the CLI, using the `+feature` syntax.
pub enabled: LinkerFeatures,
/// The linker features that are disabled on the CLI, using the `-feature` syntax.
pub disabled: LinkerFeatures,
}
impl LinkerFeaturesCli {
/// Accumulates an enabled or disabled feature as specified on the CLI, if possible.
/// For example: `+lld`, and `-lld`.
pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
// Duplicate flags are reduced as we go, the last occurrence wins:
// `+feature,-feature,+feature` only enables the feature, and does not record it as both
// enabled and disabled on the CLI.
// We also only expose `+/-lld` at the moment, as it's currenty the only implemented linker
// feature and toggling `LinkerFeatures::CC` would be a noop.
match feature {
"+lld" => {
self.enabled.insert(LinkerFeatures::LLD);
self.disabled.remove(LinkerFeatures::LLD);
Some(())
}
"-lld" => {
self.disabled.insert(LinkerFeatures::LLD);
self.enabled.remove(LinkerFeatures::LLD);
Some(())
}
_ => None,
}
}
}
/// Used with `-Z assert-incr-state`.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum IncrementalStateAssertion {

View File

@ -426,6 +426,8 @@ mod desc {
"one of supported split dwarf modes (`split` or `single`)";
pub const parse_link_self_contained: &str = "one of: `y`, `yes`, `on`, `n`, `no`, `off`, or a list of enabled (`+` prefix) and disabled (`-` prefix) \
components: `crto`, `libc`, `unwind`, `linker`, `sanitizers`, `mingw`";
pub const parse_linker_features: &str =
"a list of enabled (`+` prefix) and disabled (`-` prefix) features: `lld`";
pub const parse_polonius: &str = "either no value or `legacy` (the default), or `next`";
pub const parse_stack_protector: &str =
"one of (`none` (default), `basic`, `strong`, or `all`)";
@ -1269,6 +1271,22 @@ mod parse {
true
}
/// Parse a comma-separated list of enabled and disabled linker features.
pub(crate) fn parse_linker_features(slot: &mut LinkerFeaturesCli, v: Option<&str>) -> bool {
match v {
Some(s) => {
for feature in s.split(',') {
if slot.handle_cli_feature(feature).is_none() {
return false;
}
}
true
}
None => false,
}
}
pub(crate) fn parse_wasi_exec_model(slot: &mut Option<WasiExecModel>, v: Option<&str>) -> bool {
match v {
Some("command") => *slot = Some(WasiExecModel::Command),
@ -1721,6 +1739,8 @@ 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_mir: bool = (false, parse_bool, [UNTRACKED],
"lint MIR before and after each transformation"),
llvm_module_flag: Vec<(String, u32, String)> = (Vec::new(), parse_llvm_module_flag, [TRACKED],