diff options
| author | Rémy Rakic <remy.rakic+github@gmail.com> | 2024-04-08 21:35:29 +0000 |
|---|---|---|
| committer | Rémy Rakic <remy.rakic+github@gmail.com> | 2024-04-12 09:43:05 +0000 |
| commit | 695aac2c02f7073557222083007bedbda8d685da (patch) | |
| tree | 90c5e10778e77458defc8a6267b011b5e6b29cb9 | |
| parent | c39929ce189d0246fe25380b6e5aa7e43786fd22 (diff) | |
| download | rust-695aac2c02f7073557222083007bedbda8d685da.tar.gz rust-695aac2c02f7073557222083007bedbda8d685da.zip | |
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.
| -rw-r--r-- | compiler/rustc_target/src/spec/mod.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index e94c7f3cc58..05e3c8b9641 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -698,6 +698,58 @@ impl ToJson for LinkSelfContainedComponents { } } +bitflags::bitflags! { + /// The `-Z linker-features` components that can individually be enabled or disabled. + /// + /// They are feature flags intended to be a more flexible mechanism than linker flavors, and + /// also to prevent a combinatorial explosion of flavors whenever a new linker feature is + /// required. These flags are "generic", in the sense that they can work on multiple targets on + /// the CLI. Otherwise, one would have to select different linkers flavors for each target. + /// + /// Here are some examples of the advantages they offer: + /// - default feature sets for principal flavors, or for specific targets. + /// - flavor-specific features: for example, clang offers automatic cross-linking with + /// `--target`, which gcc-style compilers don't support. The *flavor* is still a C/C++ + /// compiler, and we don't need to multiply the number of flavors for this use-case. Instead, + /// we can have a single `+target` feature. + /// - umbrella features: for example if clang accumulates more features in the future than just + /// the `+target` above. That could be modeled as `+clang`. + /// - niche features for resolving specific issues: for example, on Apple targets the linker + /// flag implementing the `as-needed` native link modifier (#99424) is only possible on + /// sufficiently recent linker versions. + /// - still allows for discovery and automation, for example via feature detection. This can be + /// useful in exotic environments/build systems. + #[derive(Clone, Copy, PartialEq, Eq, Default)] + pub struct LinkerFeatures: u8 { + /// Invoke the linker via a C/C++ compiler (e.g. on most unix targets). + const CC = 1 << 0; + /// Use the lld linker, either the system lld or the self-contained linker `rust-lld`. + const LLD = 1 << 1; + } +} +rustc_data_structures::external_bitflags_debug! { LinkerFeatures } + +impl LinkerFeatures { + /// Parses a single `-Z linker-features` well-known feature, not a set of flags. + pub fn from_str(s: &str) -> Option<LinkerFeatures> { + Some(match s { + "cc" => LinkerFeatures::CC, + "lld" => LinkerFeatures::LLD, + _ => return None, + }) + } + + /// Returns whether the `lld` linker feature is enabled. + pub fn is_lld_enabled(self) -> bool { + self.contains(LinkerFeatures::LLD) + } + + /// Returns whether the `cc` linker feature is enabled. + pub fn is_cc_enabled(self) -> bool { + self.contains(LinkerFeatures::CC) + } +} + #[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)] pub enum PanicStrategy { Unwind, |
