summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_target/src/spec/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src/spec/mod.rs')
-rw-r--r--compiler/rustc_target/src/spec/mod.rs359
1 files changed, 290 insertions, 69 deletions
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 1bcb1f353..f04799482 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -38,7 +38,7 @@ use crate::abi::call::Conv;
use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors};
use crate::json::{Json, ToJson};
use crate::spec::abi::{lookup as lookup_abi, Abi};
-use crate::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
+use crate::spec::crt_objects::CrtObjects;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_fs_util::try_canonicalize;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -57,47 +57,11 @@ use rustc_macros::HashStable_Generic;
pub mod abi;
pub mod crt_objects;
-mod aix_base;
-mod android_base;
-mod apple_base;
-pub use apple_base::deployment_target as current_apple_deployment_target;
-pub use apple_base::platform as current_apple_platform;
-pub use apple_base::sdk_version as current_apple_sdk_version;
-mod avr_gnu_base;
-pub use avr_gnu_base::ef_avr_arch;
-mod bpf_base;
-mod dragonfly_base;
-mod freebsd_base;
-mod fuchsia_base;
-mod haiku_base;
-mod hermit_base;
-mod hurd_base;
-mod hurd_gnu_base;
-mod illumos_base;
-mod l4re_base;
-mod linux_base;
-mod linux_gnu_base;
-mod linux_musl_base;
-mod linux_ohos_base;
-mod linux_uclibc_base;
-mod msvc_base;
-mod netbsd_base;
-mod nto_qnx_base;
-mod openbsd_base;
-mod redox_base;
-mod solaris_base;
-mod solid_base;
-mod teeos_base;
-mod thumb_base;
-mod uefi_msvc_base;
-mod unikraft_linux_musl_base;
-mod vxworks_base;
-mod wasm_base;
-mod windows_gnu_base;
-mod windows_gnullvm_base;
-mod windows_msvc_base;
-mod windows_uwp_gnu_base;
-mod windows_uwp_msvc_base;
+mod base;
+pub use base::apple::deployment_target as current_apple_deployment_target;
+pub use base::apple::platform as current_apple_platform;
+pub use base::apple::sdk_version as current_apple_sdk_version;
+pub use base::avr_gnu::ef_avr_arch;
/// Linker is called through a C/C++ compiler.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
@@ -164,11 +128,11 @@ pub enum LinkerFlavor {
/// Linker flavors available externally through command line (`-Clinker-flavor`)
/// or json target specifications.
-/// FIXME: This set has accumulated historically, bring it more in line with the internal
-/// linker flavors (`LinkerFlavor`).
+/// This set has accumulated historically, and contains both (stable and unstable) legacy values, as
+/// well as modern ones matching the internal linker flavors (`LinkerFlavor`).
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LinkerFlavorCli {
- // New (unstable) flavors, with direct counterparts in `LinkerFlavor`.
+ // Modern (unstable) flavors, with direct counterparts in `LinkerFlavor`.
Gnu(Cc, Lld),
Darwin(Cc, Lld),
WasmLld(Cc),
@@ -179,13 +143,11 @@ pub enum LinkerFlavorCli {
Bpf,
Ptx,
- // Below: the legacy stable values.
+ // Legacy stable values
Gcc,
Ld,
Lld(LldFlavor),
Em,
- BpfLinker,
- PtxLinker,
}
impl LinkerFlavorCli {
@@ -199,9 +161,7 @@ impl LinkerFlavorCli {
| LinkerFlavorCli::Msvc(Lld::Yes)
| LinkerFlavorCli::EmCc
| LinkerFlavorCli::Bpf
- | LinkerFlavorCli::Ptx
- | LinkerFlavorCli::BpfLinker
- | LinkerFlavorCli::PtxLinker => true,
+ | LinkerFlavorCli::Ptx => true,
LinkerFlavorCli::Gcc
| LinkerFlavorCli::Ld
| LinkerFlavorCli::Lld(..)
@@ -279,11 +239,10 @@ impl LinkerFlavor {
LinkerFlavorCli::Lld(LldFlavor::Wasm) => LinkerFlavor::WasmLld(Cc::No),
LinkerFlavorCli::Lld(LldFlavor::Link) => LinkerFlavor::Msvc(Lld::Yes),
LinkerFlavorCli::Em => LinkerFlavor::EmCc,
- LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf,
- LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx,
}
}
+ /// Returns the corresponding backwards-compatible CLI flavor.
fn to_cli(self) -> LinkerFlavorCli {
match self {
LinkerFlavor::Gnu(Cc::Yes, _)
@@ -299,8 +258,22 @@ impl LinkerFlavor {
LinkerFlavor::Msvc(Lld::Yes) => LinkerFlavorCli::Lld(LldFlavor::Link),
LinkerFlavor::Msvc(..) => LinkerFlavorCli::Msvc(Lld::No),
LinkerFlavor::EmCc => LinkerFlavorCli::Em,
- LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker,
- LinkerFlavor::Ptx => LinkerFlavorCli::PtxLinker,
+ LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
+ LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
+ }
+ }
+
+ /// Returns the modern CLI flavor that is the counterpart of this flavor.
+ fn to_cli_counterpart(self) -> LinkerFlavorCli {
+ match self {
+ LinkerFlavor::Gnu(cc, lld) => LinkerFlavorCli::Gnu(cc, lld),
+ LinkerFlavor::Darwin(cc, lld) => LinkerFlavorCli::Darwin(cc, lld),
+ LinkerFlavor::WasmLld(cc) => LinkerFlavorCli::WasmLld(cc),
+ LinkerFlavor::Unix(cc) => LinkerFlavorCli::Unix(cc),
+ LinkerFlavor::Msvc(lld) => LinkerFlavorCli::Msvc(lld),
+ LinkerFlavor::EmCc => LinkerFlavorCli::EmCc,
+ LinkerFlavor::Bpf => LinkerFlavorCli::Bpf,
+ LinkerFlavor::Ptx => LinkerFlavorCli::Ptx,
}
}
@@ -320,7 +293,6 @@ impl LinkerFlavor {
LinkerFlavorCli::Ld => (Some(Cc::No), Some(Lld::No)),
LinkerFlavorCli::Lld(_) => (Some(Cc::No), Some(Lld::Yes)),
LinkerFlavorCli::Em => (Some(Cc::Yes), Some(Lld::Yes)),
- LinkerFlavorCli::BpfLinker | LinkerFlavorCli::PtxLinker => (None, None),
}
}
@@ -511,7 +483,7 @@ linker_flavor_cli_impls! {
(LinkerFlavorCli::Bpf) "bpf"
(LinkerFlavorCli::Ptx) "ptx"
- // Below: legacy stable values
+ // Legacy stable flavors
(LinkerFlavorCli::Gcc) "gcc"
(LinkerFlavorCli::Ld) "ld"
(LinkerFlavorCli::Lld(LldFlavor::Ld)) "ld.lld"
@@ -519,8 +491,6 @@ linker_flavor_cli_impls! {
(LinkerFlavorCli::Lld(LldFlavor::Link)) "lld-link"
(LinkerFlavorCli::Lld(LldFlavor::Wasm)) "wasm-ld"
(LinkerFlavorCli::Em) "em"
- (LinkerFlavorCli::BpfLinker) "bpf-linker"
- (LinkerFlavorCli::PtxLinker) "ptx-linker"
}
impl ToJson for LinkerFlavorCli {
@@ -529,6 +499,203 @@ impl ToJson for LinkerFlavorCli {
}
}
+/// The different `-Clink-self-contained` options that can be specified in a target spec:
+/// - enabling or disabling in bulk
+/// - some target-specific pieces of inference to determine whether to use self-contained linking
+/// if `-Clink-self-contained` is not specified explicitly (e.g. on musl/mingw)
+/// - explicitly enabling some of the self-contained linking components, e.g. the linker component
+/// to use `rust-lld`
+#[derive(Clone, Copy, PartialEq, Debug)]
+pub enum LinkSelfContainedDefault {
+ /// The target spec explicitly enables self-contained linking.
+ True,
+
+ /// The target spec explicitly disables self-contained linking.
+ False,
+
+ /// The target spec requests that the self-contained mode is inferred, in the context of musl.
+ InferredForMusl,
+
+ /// The target spec requests that the self-contained mode is inferred, in the context of mingw.
+ InferredForMingw,
+
+ /// The target spec explicitly enables a list of self-contained linking components: e.g. for
+ /// targets opting into a subset of components like the CLI's `-C link-self-contained=+linker`.
+ WithComponents(LinkSelfContainedComponents),
+}
+
+/// Parses a backwards-compatible `-Clink-self-contained` option string, without components.
+impl FromStr for LinkSelfContainedDefault {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<LinkSelfContainedDefault, ()> {
+ Ok(match s {
+ "false" => LinkSelfContainedDefault::False,
+ "true" | "wasm" => LinkSelfContainedDefault::True,
+ "musl" => LinkSelfContainedDefault::InferredForMusl,
+ "mingw" => LinkSelfContainedDefault::InferredForMingw,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl ToJson for LinkSelfContainedDefault {
+ fn to_json(&self) -> Json {
+ match *self {
+ LinkSelfContainedDefault::WithComponents(components) => {
+ // Serialize the components in a json object's `components` field, to prepare for a
+ // future where `crt-objects-fallback` is removed from the json specs and
+ // incorporated as a field here.
+ let mut map = BTreeMap::new();
+ map.insert("components", components);
+ map.to_json()
+ }
+
+ // Stable backwards-compatible values
+ LinkSelfContainedDefault::True => "true".to_json(),
+ LinkSelfContainedDefault::False => "false".to_json(),
+ LinkSelfContainedDefault::InferredForMusl => "musl".to_json(),
+ LinkSelfContainedDefault::InferredForMingw => "mingw".to_json(),
+ }
+ }
+}
+
+impl LinkSelfContainedDefault {
+ /// Returns whether the target spec has self-contained linking explicitly disabled. Used to emit
+ /// errors if the user then enables it on the CLI.
+ pub fn is_disabled(self) -> bool {
+ self == LinkSelfContainedDefault::False
+ }
+
+ /// Returns whether the target spec explictly requests self-contained linking, i.e. not via
+ /// inference.
+ pub fn is_linker_enabled(self) -> bool {
+ match self {
+ LinkSelfContainedDefault::True => true,
+ LinkSelfContainedDefault::False => false,
+ LinkSelfContainedDefault::WithComponents(c) => {
+ c.contains(LinkSelfContainedComponents::LINKER)
+ }
+ _ => false,
+ }
+ }
+
+ /// Returns the key to use when serializing the setting to json:
+ /// - individual components in a `link-self-contained` object value
+ /// - the other variants as a backwards-compatible `crt-objects-fallback` string
+ fn json_key(self) -> &'static str {
+ match self {
+ LinkSelfContainedDefault::WithComponents(_) => "link-self-contained",
+ _ => "crt-objects-fallback",
+ }
+ }
+}
+
+bitflags::bitflags! {
+ #[derive(Default)]
+ /// The `-C link-self-contained` components that can individually be enabled or disabled.
+ pub struct LinkSelfContainedComponents: u8 {
+ /// CRT objects (e.g. on `windows-gnu`, `musl`, `wasi` targets)
+ const CRT_OBJECTS = 1 << 0;
+ /// libc static library (e.g. on `musl`, `wasi` targets)
+ const LIBC = 1 << 1;
+ /// libgcc/libunwind (e.g. on `windows-gnu`, `fuchsia`, `fortanix`, `gnullvm` targets)
+ const UNWIND = 1 << 2;
+ /// Linker, dlltool, and their necessary libraries (e.g. on `windows-gnu` and for `rust-lld`)
+ const LINKER = 1 << 3;
+ /// Sanitizer runtime libraries
+ const SANITIZERS = 1 << 4;
+ /// Other MinGW libs and Windows import libs
+ const MINGW = 1 << 5;
+ }
+}
+
+impl LinkSelfContainedComponents {
+ /// Parses a single `-Clink-self-contained` well-known component, not a set of flags.
+ pub fn from_str(s: &str) -> Option<LinkSelfContainedComponents> {
+ Some(match s {
+ "crto" => LinkSelfContainedComponents::CRT_OBJECTS,
+ "libc" => LinkSelfContainedComponents::LIBC,
+ "unwind" => LinkSelfContainedComponents::UNWIND,
+ "linker" => LinkSelfContainedComponents::LINKER,
+ "sanitizers" => LinkSelfContainedComponents::SANITIZERS,
+ "mingw" => LinkSelfContainedComponents::MINGW,
+ _ => return None,
+ })
+ }
+
+ /// Return the component's name.
+ ///
+ /// Returns `None` if the bitflags aren't a singular component (but a mix of multiple flags).
+ pub fn as_str(self) -> Option<&'static str> {
+ Some(match self {
+ LinkSelfContainedComponents::CRT_OBJECTS => "crto",
+ LinkSelfContainedComponents::LIBC => "libc",
+ LinkSelfContainedComponents::UNWIND => "unwind",
+ LinkSelfContainedComponents::LINKER => "linker",
+ LinkSelfContainedComponents::SANITIZERS => "sanitizers",
+ LinkSelfContainedComponents::MINGW => "mingw",
+ _ => return None,
+ })
+ }
+
+ /// Returns an array of all the components.
+ fn all_components() -> [LinkSelfContainedComponents; 6] {
+ [
+ LinkSelfContainedComponents::CRT_OBJECTS,
+ LinkSelfContainedComponents::LIBC,
+ LinkSelfContainedComponents::UNWIND,
+ LinkSelfContainedComponents::LINKER,
+ LinkSelfContainedComponents::SANITIZERS,
+ LinkSelfContainedComponents::MINGW,
+ ]
+ }
+
+ /// Returns whether at least a component is enabled.
+ pub fn are_any_components_enabled(self) -> bool {
+ !self.is_empty()
+ }
+
+ /// Returns whether `LinkSelfContainedComponents::LINKER` is enabled.
+ pub fn is_linker_enabled(self) -> bool {
+ self.contains(LinkSelfContainedComponents::LINKER)
+ }
+
+ /// Returns whether `LinkSelfContainedComponents::CRT_OBJECTS` is enabled.
+ pub fn is_crt_objects_enabled(self) -> bool {
+ self.contains(LinkSelfContainedComponents::CRT_OBJECTS)
+ }
+}
+
+impl IntoIterator for LinkSelfContainedComponents {
+ type Item = LinkSelfContainedComponents;
+ type IntoIter = std::vec::IntoIter<LinkSelfContainedComponents>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ LinkSelfContainedComponents::all_components()
+ .into_iter()
+ .filter(|&s| self.contains(s))
+ .collect::<Vec<_>>()
+ .into_iter()
+ }
+}
+
+impl ToJson for LinkSelfContainedComponents {
+ fn to_json(&self) -> Json {
+ let components: Vec<_> = Self::all_components()
+ .into_iter()
+ .filter(|c| self.contains(*c))
+ .map(|c| {
+ // We can unwrap because we're iterating over all the known singular components,
+ // not an actual set of flags where `as_str` can fail.
+ c.as_str().unwrap().to_owned()
+ })
+ .collect();
+
+ components.to_json()
+ }
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
pub enum PanicStrategy {
Unwind,
@@ -1241,14 +1408,16 @@ impl fmt::Display for StackProtector {
macro_rules! supported_targets {
( $(($triple:literal, $module:ident),)+ ) => {
- $(mod $module;)+
+ mod targets {
+ $(pub(crate) mod $module;)+
+ }
/// List of supported targets
pub const TARGETS: &[&str] = &[$($triple),+];
fn load_builtin(target: &str) -> Option<Target> {
let mut t = match target {
- $( $triple => $module::target(), )+
+ $( $triple => targets::$module::target(), )+
_ => return None,
};
t.is_builtin = true;
@@ -1264,7 +1433,7 @@ macro_rules! supported_targets {
$(
#[test] // `#[test]`
fn $module() {
- tests_impl::test_target(super::$module::target());
+ tests_impl::test_target(crate::spec::targets::$module::target());
}
)+
}
@@ -1279,6 +1448,7 @@ supported_targets! {
("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu),
("m68k-unknown-linux-gnu", m68k_unknown_linux_gnu),
("csky-unknown-linux-gnuabiv2", csky_unknown_linux_gnuabiv2),
+ ("csky-unknown-linux-gnuabiv2hf", csky_unknown_linux_gnuabiv2hf),
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),
("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64),
@@ -1360,7 +1530,9 @@ supported_targets! {
("aarch64_be-unknown-netbsd", aarch64_be_unknown_netbsd),
("armv6-unknown-netbsd-eabihf", armv6_unknown_netbsd_eabihf),
("armv7-unknown-netbsd-eabihf", armv7_unknown_netbsd_eabihf),
+ ("i586-unknown-netbsd", i586_unknown_netbsd),
("i686-unknown-netbsd", i686_unknown_netbsd),
+ ("mipsel-unknown-netbsd", mipsel_unknown_netbsd),
("powerpc-unknown-netbsd", powerpc_unknown_netbsd),
("riscv64gc-unknown-netbsd", riscv64gc_unknown_netbsd),
("sparc64-unknown-netbsd", sparc64_unknown_netbsd),
@@ -1399,6 +1571,7 @@ supported_targets! {
("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
("aarch64-apple-tvos", aarch64_apple_tvos),
+ ("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim),
("x86_64-apple-tvos", x86_64_apple_tvos),
("armv7k-apple-watchos", armv7k_apple_watchos),
@@ -1704,6 +1877,8 @@ pub struct TargetOptions {
/// Same as `(pre|post)_link_objects`, but when self-contained linking mode is enabled.
pub pre_link_objects_self_contained: CrtObjects,
pub post_link_objects_self_contained: CrtObjects,
+ /// Behavior for the self-contained linking mode: inferred for some targets, or explicitly
+ /// enabled (in bulk, or with individual components).
pub link_self_contained: LinkSelfContainedDefault,
/// Linker arguments that are passed *before* any user-defined libraries.
@@ -2104,7 +2279,7 @@ impl TargetOptions {
}
fn update_to_cli(&mut self) {
- self.linker_flavor_json = self.linker_flavor.to_cli();
+ self.linker_flavor_json = self.linker_flavor.to_cli_counterpart();
self.lld_flavor_json = self.linker_flavor.lld_flavor();
self.linker_is_gnu_json = self.linker_flavor.is_gnu();
for (args, args_json) in [
@@ -2114,8 +2289,10 @@ impl TargetOptions {
(&self.late_link_args_static, &mut self.late_link_args_static_json),
(&self.post_link_args, &mut self.post_link_args_json),
] {
- *args_json =
- args.iter().map(|(flavor, args)| (flavor.to_cli(), args.clone())).collect();
+ *args_json = args
+ .iter()
+ .map(|(flavor, args)| (flavor.to_cli_counterpart(), args.clone()))
+ .collect();
}
}
}
@@ -2658,8 +2835,43 @@ impl Target {
}
Ok::<(), String>(())
} );
-
- ($key_name:ident = $json_name:expr, link_self_contained) => ( {
+ ($key_name:ident, link_self_contained_components) => ( {
+ // Skeleton of what needs to be parsed:
+ //
+ // ```
+ // $name: {
+ // "components": [
+ // <array of strings>
+ // ]
+ // }
+ // ```
+ let name = (stringify!($key_name)).replace("_", "-");
+ if let Some(o) = obj.remove(&name) {
+ if let Some(o) = o.as_object() {
+ let component_array = o.get("components")
+ .ok_or_else(|| format!("{name}: expected a \
+ JSON object with a `components` field."))?;
+ let component_array = component_array.as_array()
+ .ok_or_else(|| format!("{name}.components: expected a JSON array"))?;
+ let mut components = LinkSelfContainedComponents::empty();
+ for s in component_array {
+ components |= match s.as_str() {
+ Some(s) => {
+ LinkSelfContainedComponents::from_str(s)
+ .ok_or_else(|| format!("unknown \
+ `-Clink-self-contained` component: {s}"))?
+ },
+ _ => return Err(format!("not a string: {:?}", s)),
+ };
+ }
+ base.$key_name = LinkSelfContainedDefault::WithComponents(components);
+ } else {
+ incorrect_type.push(name)
+ }
+ }
+ Ok::<(), String>(())
+ } );
+ ($key_name:ident = $json_name:expr, link_self_contained_backwards_compatible) => ( {
let name = $json_name;
obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
match s.parse::<LinkSelfContainedDefault>() {
@@ -2812,7 +3024,13 @@ impl Target {
key!(post_link_objects = "post-link-objects", link_objects);
key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects);
key!(post_link_objects_self_contained = "post-link-objects-fallback", link_objects);
- key!(link_self_contained = "crt-objects-fallback", link_self_contained)?;
+ // Deserializes the backwards-compatible variants of `-Clink-self-contained`
+ key!(
+ link_self_contained = "crt-objects-fallback",
+ link_self_contained_backwards_compatible
+ )?;
+ // Deserializes the components variant of `-Clink-self-contained`
+ key!(link_self_contained, link_self_contained_components)?;
key!(pre_link_args_json = "pre-link-args", link_args);
key!(late_link_args_json = "late-link-args", link_args);
key!(late_link_args_dynamic_json = "late-link-args-dynamic", link_args);
@@ -3068,7 +3286,6 @@ impl ToJson for Target {
target_option_val!(post_link_objects);
target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback");
target_option_val!(post_link_objects_self_contained, "post-link-objects-fallback");
- target_option_val!(link_self_contained, "crt-objects-fallback");
target_option_val!(link_args - pre_link_args_json, "pre-link-args");
target_option_val!(link_args - late_link_args_json, "late-link-args");
target_option_val!(link_args - late_link_args_dynamic_json, "late-link-args-dynamic");
@@ -3165,6 +3382,10 @@ impl ToJson for Target {
d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());
}
+ // Serializing `-Clink-self-contained` needs a dynamic key to support the
+ // backwards-compatible variants.
+ d.insert(self.link_self_contained.json_key().into(), self.link_self_contained.to_json());
+
Json::Object(d)
}
}