Skip to content

Commit 34b7dff

Browse files
committed
introduce LinkerFeatures
They are a flexible complementary mechanism to linker flavors, that also avoid the combinatorial explosion of mapping linking features to actual linker flavors.
1 parent 995263e commit 34b7dff

File tree

1 file changed

+52
-0
lines changed
  • compiler/rustc_target/src/spec

1 file changed

+52
-0
lines changed

compiler/rustc_target/src/spec/mod.rs

+52
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,58 @@ impl ToJson for LinkSelfContainedComponents {
698698
}
699699
}
700700

701+
bitflags::bitflags! {
702+
/// The `-Z linker-features` components that can individually be enabled or disabled.
703+
///
704+
/// They are feature flags intended to be a more flexible mechanism than linker flavors, and
705+
/// also to prevent a combinatorial explosion of flavors whenever a new linker feature is
706+
/// required. These flags are "generic", in the sense that they can work on multiple targets on
707+
/// the CLI. Otherwise, one would have to select different linkers flavors for each target.
708+
///
709+
/// Here are some examples of the advantages they offer:
710+
/// - default feature sets for principal flavors, or for specific targets.
711+
/// - flavor-specific features: for example, clang offers automatic cross-linking with
712+
/// `--target`, which gcc-style compilers don't support. The *flavor* is still a C/C++
713+
/// compiler, and we don't need to multiply the number of flavors for this use-case. Instead,
714+
/// we can have a single `+target` feature.
715+
/// - umbrella features: for example if clang accumulates more features in the future than just
716+
/// the `+target` above. That could be modeled as `+clang`.
717+
/// - niche features for resolving specific issues: for example, on Apple targets the linker
718+
/// flag implementing the `as-needed` native link modifier (#99424) is only possible on
719+
/// sufficiently recent linker versions.
720+
/// - still allows for discovery and automation, for example via feature detection. This can be
721+
/// useful in exotic environments/build systems.
722+
#[derive(Clone, Copy, PartialEq, Eq, Default)]
723+
pub struct LinkerFeatures: u8 {
724+
/// Invoke the linker via a C/C++ compiler (e.g. on most unix targets).
725+
const CC = 1 << 0;
726+
/// Use the lld linker, either the system lld or the self-contained linker `rust-lld`.
727+
const LLD = 1 << 1;
728+
}
729+
}
730+
rustc_data_structures::external_bitflags_debug! { LinkerFeatures }
731+
732+
impl LinkerFeatures {
733+
/// Parses a single `-Z linker-features` well-known feature, not a set of flags.
734+
pub fn from_str(s: &str) -> Option<LinkerFeatures> {
735+
Some(match s {
736+
"cc" => LinkerFeatures::CC,
737+
"lld" => LinkerFeatures::LLD,
738+
_ => return None,
739+
})
740+
}
741+
742+
/// Returns whether the `lld` linker feature is enabled.
743+
pub fn is_lld_enabled(self) -> bool {
744+
self.contains(LinkerFeatures::LLD)
745+
}
746+
747+
/// Returns whether the `cc` linker feature is enabled.
748+
pub fn is_cc_enabled(self) -> bool {
749+
self.contains(LinkerFeatures::CC)
750+
}
751+
}
752+
701753
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
702754
pub enum PanicStrategy {
703755
Unwind,

0 commit comments

Comments
 (0)