1use std::borrow::Cow;
2use std::fmt::{Display, from_fn};
3use std::num::ParseIntError;
4use std::str::FromStr;
5
6use crate::spec::{
7 BinaryFormat, Cc, CfgAbi, DebuginfoKind, Env, FloatAbi, FramePointer, LinkerFlavor, Lld, Os,
8 RustcAbi, SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions, cvs,
9};
10
11#[cfg(test)]
12mod tests;
13
14#[allow(non_camel_case_types)]
15#[derive(#[automatically_derived]
#[allow(non_camel_case_types)]
impl ::core::marker::Copy for Arch { }Copy, #[automatically_derived]
#[allow(non_camel_case_types)]
impl ::core::clone::Clone for Arch {
#[inline]
fn clone(&self) -> Arch { *self }
}Clone, #[automatically_derived]
#[allow(non_camel_case_types)]
impl ::core::cmp::PartialEq for Arch {
#[inline]
fn eq(&self, other: &Arch) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
16pub(crate) enum Arch {
17 Armv7k,
18 Armv7s,
19 Arm64,
20 Arm64e,
21 Arm64_32,
22 I386,
23 I686,
24 X86_64,
25 X86_64h,
26}
27
28impl Arch {
29 fn target_name(self) -> &'static str {
30 match self {
31 Self::Armv7k => "armv7k",
32 Self::Armv7s => "armv7s",
33 Self::Arm64 => "arm64",
34 Self::Arm64e => "arm64e",
35 Self::Arm64_32 => "arm64_32",
36 Self::I386 => "i386",
37 Self::I686 => "i686",
38 Self::X86_64 => "x86_64",
39 Self::X86_64h => "x86_64h",
40 }
41 }
42
43 pub(crate) fn target_arch(self) -> crate::spec::Arch {
44 match self {
45 Self::Armv7k | Self::Armv7s => crate::spec::Arch::Arm,
46 Self::Arm64 | Self::Arm64e | Self::Arm64_32 => crate::spec::Arch::AArch64,
47 Self::I386 | Self::I686 => crate::spec::Arch::X86,
48 Self::X86_64 | Self::X86_64h => crate::spec::Arch::X86_64,
49 }
50 }
51
52 fn target_cpu(self, env: TargetEnv) -> &'static str {
53 match self {
54 Self::Armv7k => "cortex-a8",
55 Self::Armv7s => "swift", Self::Arm64 => match env {
57 TargetEnv::Normal => "apple-a7",
58 TargetEnv::Simulator => "apple-a12",
59 TargetEnv::MacCatalyst => "apple-a12",
60 },
61 Self::Arm64e => "apple-a12",
62 Self::Arm64_32 => "apple-s4",
63 Self::I386 | Self::I686 => "penryn",
67 Self::X86_64 => "penryn",
68 Self::X86_64h => "core-avx2",
72 }
73 }
74
75 fn stack_probes(self) -> StackProbeType {
76 match self {
77 Self::Armv7k | Self::Armv7s => StackProbeType::None,
78 Self::Arm64
79 | Self::Arm64e
80 | Self::Arm64_32
81 | Self::I386
82 | Self::I686
83 | Self::X86_64
84 | Self::X86_64h => StackProbeType::Inline,
85 }
86 }
87}
88
89#[derive(#[automatically_derived]
impl ::core::marker::Copy for TargetEnv { }Copy, #[automatically_derived]
impl ::core::clone::Clone for TargetEnv {
#[inline]
fn clone(&self) -> TargetEnv { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for TargetEnv {
#[inline]
fn eq(&self, other: &TargetEnv) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
90pub(crate) enum TargetEnv {
91 Normal,
92 Simulator,
93 MacCatalyst,
94}
95
96impl TargetEnv {
97 fn target_env(self) -> Env {
98 match self {
99 Self::Normal => Env::Unspecified,
100 Self::MacCatalyst => Env::MacAbi,
101 Self::Simulator => Env::Sim,
102 }
103 }
104
105 fn target_abi(self) -> CfgAbi {
112 match self {
113 Self::Normal => CfgAbi::Unspecified,
114 Self::MacCatalyst => CfgAbi::MacAbi,
115 Self::Simulator => CfgAbi::Sim,
116 }
117 }
118}
119
120pub(crate) fn base(
123 os: Os,
124 arch: Arch,
125 env: TargetEnv,
126) -> (TargetOptions, StaticCow<str>, crate::spec::Arch) {
127 let link_env_remove = link_env_remove(&os);
128 let unversioned_llvm_target = unversioned_llvm_target(&os, arch, env);
129 let mut opts = TargetOptions {
130 llvm_floatabi: if arch.target_arch() == crate::spec::Arch::Arm {
131 Some(FloatAbi::Hard)
132 } else {
133 None
135 },
136 os,
137 env: env.target_env(),
138 cfg_abi: env.target_abi(),
139 cpu: arch.target_cpu(env).into(),
140 link_env_remove,
141 vendor: "apple".into(),
142 linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No),
143 function_sections: false,
145 dynamic_linking: true,
146 families: ::std::borrow::Cow::Borrowed(&[::std::borrow::Cow::Borrowed("unix")])cvs!["unix"],
147 is_like_darwin: true,
148 binary_format: BinaryFormat::MachO,
149 default_dwarf_version: 4,
153 frame_pointer: match arch {
154 Arch::Armv7k | Arch::Armv7s => FramePointer::Always,
156 Arch::Arm64 | Arch::Arm64e | Arch::Arm64_32 => FramePointer::NonLeaf,
158 Arch::I386 | Arch::I686 | Arch::X86_64 | Arch::X86_64h => FramePointer::Always,
159 },
160 has_rpath: true,
161 dll_suffix: ".dylib".into(),
162 archive_format: "darwin".into(),
163 has_thread_local: true,
166 abi_return_struct_as_int: true,
167 emit_debug_gdb_scripts: false,
168 eh_frame_header: false,
169 stack_probes: arch.stack_probes(),
170
171 debuginfo_kind: DebuginfoKind::DwarfDsym,
172 split_debuginfo: SplitDebuginfo::Packed,
175 supported_split_debuginfo: Cow::Borrowed(&[
176 SplitDebuginfo::Packed,
177 SplitDebuginfo::Unpacked,
178 SplitDebuginfo::Off,
179 ]),
180
181 link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
200
201 ..Default::default()
202 };
203 if #[allow(non_exhaustive_omitted_patterns)] match arch {
Arch::I386 | Arch::I686 => true,
_ => false,
}matches!(arch, Arch::I386 | Arch::I686) {
204 opts.rustc_abi = Some(RustcAbi::X86Sse2);
206 }
207 (opts, unversioned_llvm_target, arch.target_arch())
208}
209
210fn unversioned_llvm_target(os: &Os, arch: Arch, env: TargetEnv) -> StaticCow<str> {
215 let arch = arch.target_name();
216 let os = match os {
219 Os::MacOs => "macosx",
220 Os::IOs => "ios",
221 Os::WatchOs => "watchos",
222 Os::TvOs => "tvos",
223 Os::VisionOs => "xros",
224 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("tried to get LLVM target OS for non-Apple platform")));
}unreachable!("tried to get LLVM target OS for non-Apple platform"),
225 };
226 let environment = match env {
227 TargetEnv::Normal => "",
228 TargetEnv::MacCatalyst => "-macabi",
229 TargetEnv::Simulator => "-simulator",
230 };
231 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}-apple-{1}{2}", arch, os,
environment))
})format!("{arch}-apple-{os}{environment}").into()
232}
233
234fn link_env_remove(os: &Os) -> StaticCow<[StaticCow<str>]> {
235 if *os == Os::MacOs {
241 ::std::borrow::Cow::Borrowed(&[::std::borrow::Cow::Borrowed("IPHONEOS_DEPLOYMENT_TARGET"),
::std::borrow::Cow::Borrowed("TVOS_DEPLOYMENT_TARGET"),
::std::borrow::Cow::Borrowed("XROS_DEPLOYMENT_TARGET")])cvs!["IPHONEOS_DEPLOYMENT_TARGET", "TVOS_DEPLOYMENT_TARGET", "XROS_DEPLOYMENT_TARGET"]
245 } else {
246 ::std::borrow::Cow::Borrowed(&[::std::borrow::Cow::Borrowed("MACOSX_DEPLOYMENT_TARGET")])cvs!["MACOSX_DEPLOYMENT_TARGET"]
249 }
250}
251
252#[derive(#[automatically_derived]
impl ::core::fmt::Debug for OSVersion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "OSVersion",
"major", &self.major, "minor", &self.minor, "patch", &&self.patch)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for OSVersion {
#[inline]
fn clone(&self) -> OSVersion {
let _: ::core::clone::AssertParamIsClone<u16>;
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OSVersion { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for OSVersion {
#[inline]
fn eq(&self, other: &OSVersion) -> bool {
self.major == other.major && self.minor == other.minor &&
self.patch == other.patch
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OSVersion {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<u16>;
let _: ::core::cmp::AssertParamIsEq<u8>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for OSVersion {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.major, state);
::core::hash::Hash::hash(&self.minor, state);
::core::hash::Hash::hash(&self.patch, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialOrd for OSVersion {
#[inline]
fn partial_cmp(&self, other: &OSVersion)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.major, &other.major)
{
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
match ::core::cmp::PartialOrd::partial_cmp(&self.minor,
&other.minor) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
::core::cmp::PartialOrd::partial_cmp(&self.patch,
&other.patch),
cmp => cmp,
},
cmp => cmp,
}
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for OSVersion {
#[inline]
fn cmp(&self, other: &OSVersion) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.major, &other.major) {
::core::cmp::Ordering::Equal =>
match ::core::cmp::Ord::cmp(&self.minor, &other.minor) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.patch, &other.patch),
cmp => cmp,
},
cmp => cmp,
}
}
}Ord)]
256pub struct OSVersion {
257 pub major: u16,
258 pub minor: u8,
259 pub patch: u8,
260}
261
262impl FromStr for OSVersion {
263 type Err = ParseIntError;
264
265 fn from_str(version: &str) -> Result<Self, ParseIntError> {
267 if let Some((major, minor)) = version.split_once('.') {
268 let major = major.parse()?;
269 if let Some((minor, patch)) = minor.split_once('.') {
270 Ok(Self { major, minor: minor.parse()?, patch: patch.parse()? })
271 } else {
272 Ok(Self { major, minor: minor.parse()?, patch: 0 })
273 }
274 } else {
275 Ok(Self { major: version.parse()?, minor: 0, patch: 0 })
276 }
277 }
278}
279
280impl OSVersion {
281 pub fn new(major: u16, minor: u8, patch: u8) -> Self {
282 Self { major, minor, patch }
283 }
284
285 pub fn fmt_pretty(self) -> impl Display {
286 let Self { major, minor, patch } = self;
287 from_fn(move |f| {
288 f.write_fmt(format_args!("{0}.{1}", major, minor))write!(f, "{major}.{minor}")?;
289 if patch != 0 {
290 f.write_fmt(format_args!(".{0}", patch))write!(f, ".{patch}")?;
291 }
292 Ok(())
293 })
294 }
295
296 pub fn fmt_full(self) -> impl Display {
297 let Self { major, minor, patch } = self;
298 from_fn(move |f| f.write_fmt(format_args!("{0}.{1}.{2}", major, minor, patch))write!(f, "{major}.{minor}.{patch}"))
299 }
300
301 pub fn os_minimum_deployment_target(os: &Os) -> Self {
303 let (major, minor, patch) = match os {
311 Os::MacOs => (10, 12, 0),
312 Os::IOs => (10, 0, 0),
313 Os::TvOs => (10, 0, 0),
314 Os::WatchOs => (5, 0, 0),
315 Os::VisionOs => (1, 0, 0),
316 other => {
317 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("tried to get deployment target for non-Apple platform: {0:?}",
other)));
}unreachable!("tried to get deployment target for non-Apple platform: {:?}", other)
318 }
319 };
320 Self { major, minor, patch }
321 }
322
323 pub fn minimum_deployment_target(target: &Target) -> Self {
331 let (major, minor, patch) = match (&target.os, &target.arch, &target.env) {
332 (Os::MacOs, crate::spec::Arch::AArch64, _) => (11, 0, 0),
333 (Os::IOs, crate::spec::Arch::AArch64, Env::MacAbi) => (14, 0, 0),
334 (Os::IOs, crate::spec::Arch::AArch64, Env::Sim) => (14, 0, 0),
335 (Os::IOs, _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0),
336 (Os::IOs, _, Env::MacAbi) => (13, 1, 0),
338 (Os::TvOs, crate::spec::Arch::AArch64, Env::Sim) => (14, 0, 0),
339 (Os::WatchOs, crate::spec::Arch::AArch64, Env::Sim) => (7, 0, 0),
340 (Os::WatchOs, crate::spec::Arch::AArch64, Env::Unspecified)
343 if !target.llvm_target.starts_with("arm64_32") =>
344 {
345 (26, 0, 0)
346 }
347 _ => return Self::os_minimum_deployment_target(&target.os),
348 };
349 Self { major, minor, patch }
350 }
351}
352
353pub fn deployment_target_env_var(os: &Os) -> &'static str {
355 match os {
356 Os::MacOs => "MACOSX_DEPLOYMENT_TARGET",
357 Os::IOs => "IPHONEOS_DEPLOYMENT_TARGET",
358 Os::WatchOs => "WATCHOS_DEPLOYMENT_TARGET",
359 Os::TvOs => "TVOS_DEPLOYMENT_TARGET",
360 Os::VisionOs => "XROS_DEPLOYMENT_TARGET",
361 _ => {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("tried to get deployment target env var for non-Apple platform")));
}unreachable!("tried to get deployment target env var for non-Apple platform"),
362 }
363}