summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_target/src/spec/apple_base.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src/spec/apple_base.rs')
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs356
1 files changed, 0 insertions, 356 deletions
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
deleted file mode 100644
index 7a666eea4..000000000
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ /dev/null
@@ -1,356 +0,0 @@
-use std::{borrow::Cow, env};
-
-use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs};
-use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, Target, TargetOptions};
-
-#[cfg(test)]
-#[path = "apple/tests.rs"]
-mod tests;
-
-use Arch::*;
-#[allow(non_camel_case_types)]
-#[derive(Copy, Clone)]
-pub enum Arch {
- Armv7k,
- Armv7s,
- Arm64,
- Arm64_32,
- I386,
- I686,
- X86_64,
- X86_64h,
- X86_64_sim,
- X86_64_macabi,
- Arm64_macabi,
- Arm64_sim,
-}
-
-impl Arch {
- pub fn target_name(self) -> &'static str {
- match self {
- Armv7k => "armv7k",
- Armv7s => "armv7s",
- Arm64 | Arm64_macabi | Arm64_sim => "arm64",
- Arm64_32 => "arm64_32",
- I386 => "i386",
- I686 => "i686",
- X86_64 | X86_64_sim | X86_64_macabi => "x86_64",
- X86_64h => "x86_64h",
- }
- }
-
- pub fn target_arch(self) -> Cow<'static, str> {
- Cow::Borrowed(match self {
- Armv7k | Armv7s => "arm",
- Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64",
- I386 | I686 => "x86",
- X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64",
- })
- }
-
- fn target_abi(self) -> &'static str {
- match self {
- Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
- X86_64_macabi | Arm64_macabi => "macabi",
- // x86_64-apple-ios is a simulator target, even though it isn't
- // declared that way in the target like the other ones...
- Arm64_sim | X86_64_sim => "sim",
- }
- }
-
- fn target_cpu(self) -> &'static str {
- match self {
- Armv7k => "cortex-a8",
- Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher.
- Arm64 => "apple-a7",
- Arm64_32 => "apple-s4",
- // Only macOS 10.12+ is supported, which means
- // all x86_64/x86 CPUs must be running at least penryn
- // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82
- I386 | I686 => "penryn",
- X86_64 | X86_64_sim => "penryn",
- X86_64_macabi => "penryn",
- // Note: `core-avx2` is slightly more advanced than `x86_64h`, see
- // comments (and disabled features) in `x86_64h_apple_darwin` for
- // details. It is a higher baseline then `penryn` however.
- X86_64h => "core-avx2",
- Arm64_macabi => "apple-a12",
- Arm64_sim => "apple-a12",
- }
- }
-}
-
-fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
- let platform_name: StaticCow<str> = match abi {
- "sim" => format!("{os}-simulator").into(),
- "macabi" => "mac-catalyst".into(),
- _ => os.into(),
- };
-
- let platform_version: StaticCow<str> = match os {
- "ios" => ios_lld_platform_version(),
- "tvos" => tvos_lld_platform_version(),
- "watchos" => watchos_lld_platform_version(),
- "macos" => macos_lld_platform_version(arch),
- _ => unreachable!(),
- }
- .into();
-
- let arch = arch.target_name();
-
- let mut args = TargetOptions::link_args(
- LinkerFlavor::Darwin(Cc::No, Lld::No),
- &["-arch", arch, "-platform_version"],
- );
- super::add_link_args_iter(
- &mut args,
- LinkerFlavor::Darwin(Cc::No, Lld::No),
- [platform_name, platform_version.clone(), platform_version].into_iter(),
- );
- if abi != "macabi" {
- super::add_link_args(&mut args, LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-arch", arch]);
- }
-
- args
-}
-
-pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
- let abi = arch.target_abi();
-
- TargetOptions {
- abi: abi.into(),
- os: os.into(),
- cpu: arch.target_cpu().into(),
- link_env_remove: link_env_remove(arch, os),
- vendor: "apple".into(),
- linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No),
- // macOS has -dead_strip, which doesn't rely on function_sections
- function_sections: false,
- dynamic_linking: true,
- pre_link_args: pre_link_args(os, arch, abi),
- families: cvs!["unix"],
- is_like_osx: true,
- // LLVM notes that macOS 10.11+ and iOS 9+ default
- // to v4, so we do the same.
- // https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203
- default_dwarf_version: 4,
- frame_pointer: FramePointer::Always,
- has_rpath: true,
- dll_suffix: ".dylib".into(),
- archive_format: "darwin".into(),
- // Thread locals became available with iOS 8 and macOS 10.7,
- // and both are far below our minimum.
- has_thread_local: true,
- abi_return_struct_as_int: true,
- emit_debug_gdb_scripts: false,
- eh_frame_header: false,
-
- debuginfo_kind: DebuginfoKind::DwarfDsym,
- // The historical default for macOS targets is to run `dsymutil` which
- // generates a packed version of debuginfo split from the main file.
- split_debuginfo: SplitDebuginfo::Packed,
- supported_split_debuginfo: Cow::Borrowed(&[
- SplitDebuginfo::Packed,
- SplitDebuginfo::Unpacked,
- SplitDebuginfo::Off,
- ]),
-
- // This environment variable is pretty magical but is intended for
- // producing deterministic builds. This was first discovered to be used
- // by the `ar` tool as a way to control whether or not mtime entries in
- // the archive headers were set to zero or not. It appears that
- // eventually the linker got updated to do the same thing and now reads
- // this environment variable too in recent versions.
- //
- // For some more info see the commentary on #47086
- link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
-
- ..Default::default()
- }
-}
-
-pub fn sdk_version(platform: u32) -> Option<(u32, u32)> {
- // NOTE: These values are from an arbitrary point in time but shouldn't make it into the final
- // binary since the final link command will have the current SDK version passed to it.
- match platform {
- object::macho::PLATFORM_MACOS => Some((13, 1)),
- object::macho::PLATFORM_IOS
- | object::macho::PLATFORM_IOSSIMULATOR
- | object::macho::PLATFORM_TVOS
- | object::macho::PLATFORM_TVOSSIMULATOR
- | object::macho::PLATFORM_MACCATALYST => Some((16, 2)),
- object::macho::PLATFORM_WATCHOS | object::macho::PLATFORM_WATCHOSSIMULATOR => Some((9, 1)),
- _ => None,
- }
-}
-
-pub fn platform(target: &Target) -> Option<u32> {
- Some(match (&*target.os, &*target.abi) {
- ("macos", _) => object::macho::PLATFORM_MACOS,
- ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST,
- ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR,
- ("ios", _) => object::macho::PLATFORM_IOS,
- ("watchos", "sim") => object::macho::PLATFORM_WATCHOSSIMULATOR,
- ("watchos", _) => object::macho::PLATFORM_WATCHOS,
- ("tvos", "sim") => object::macho::PLATFORM_TVOSSIMULATOR,
- ("tvos", _) => object::macho::PLATFORM_TVOS,
- _ => return None,
- })
-}
-
-pub fn deployment_target(target: &Target) -> Option<(u32, u32)> {
- let (major, minor) = match &*target.os {
- "macos" => {
- // This does not need to be specific. It just needs to handle x86 vs M1.
- let arch = if target.arch == "x86" || target.arch == "x86_64" { X86_64 } else { Arm64 };
- macos_deployment_target(arch)
- }
- "ios" => match &*target.abi {
- "macabi" => mac_catalyst_deployment_target(),
- _ => ios_deployment_target(),
- },
- "watchos" => watchos_deployment_target(),
- "tvos" => tvos_deployment_target(),
- _ => return None,
- };
-
- Some((major, minor))
-}
-
-fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> {
- let deployment_target = env::var(var_name).ok()?;
- let (unparsed_major, unparsed_minor) = deployment_target.split_once('.')?;
- let (major, minor) = (unparsed_major.parse().ok()?, unparsed_minor.parse().ok()?);
-
- Some((major, minor))
-}
-
-fn macos_default_deployment_target(arch: Arch) -> (u32, u32) {
- match arch {
- // Note: Arm64_sim is not included since macOS has no simulator.
- Arm64 | Arm64_macabi => (11, 0),
- _ => (10, 12),
- }
-}
-
-fn macos_deployment_target(arch: Arch) -> (u32, u32) {
- // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
- from_set_deployment_target("MACOSX_DEPLOYMENT_TARGET")
- .unwrap_or_else(|| macos_default_deployment_target(arch))
-}
-
-fn macos_lld_platform_version(arch: Arch) -> String {
- let (major, minor) = macos_deployment_target(arch);
- format!("{major}.{minor}")
-}
-
-pub fn macos_llvm_target(arch: Arch) -> String {
- let (major, minor) = macos_deployment_target(arch);
- format!("{}-apple-macosx{}.{}.0", arch.target_name(), major, minor)
-}
-
-fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]> {
- // Apple platforms only officially support macOS as a host for any compilation.
- //
- // If building for macOS, we go ahead and remove any erroneous environment state
- // that's only applicable to cross-OS compilation. Always leave anything for the
- // host OS alone though.
- if os == "macos" {
- let mut env_remove = Vec::with_capacity(2);
- // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
- // may occur when we're linking a custom build script while targeting iOS for example.
- if let Ok(sdkroot) = env::var("SDKROOT") {
- if sdkroot.contains("iPhoneOS.platform")
- || sdkroot.contains("iPhoneSimulator.platform")
- || sdkroot.contains("AppleTVOS.platform")
- || sdkroot.contains("AppleTVSimulator.platform")
- || sdkroot.contains("WatchOS.platform")
- || sdkroot.contains("WatchSimulator.platform")
- {
- env_remove.push("SDKROOT".into())
- }
- }
- // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
- // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
- // although this is apparently ignored when using the linker at "/usr/bin/ld".
- env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".into());
- env_remove.push("TVOS_DEPLOYMENT_TARGET".into());
- env_remove.into()
- } else {
- // Otherwise if cross-compiling for a different OS/SDK, remove any part
- // of the linking environment that's wrong and reversed.
- match arch {
- Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim | X86_64h
- | Arm64_sim => {
- cvs!["MACOSX_DEPLOYMENT_TARGET"]
- }
- X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
- }
- }
-}
-
-fn ios_deployment_target() -> (u32, u32) {
- // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
- from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
-}
-
-fn mac_catalyst_deployment_target() -> (u32, u32) {
- // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
- from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((14, 0))
-}
-
-pub fn ios_llvm_target(arch: Arch) -> String {
- // Modern iOS tooling extracts information about deployment target
- // from LC_BUILD_VERSION. This load command will only be emitted when
- // we build with a version specific `llvm_target`, with the version
- // set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode
- // to pick it up (since std and core are still built with the fallback
- // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION).
- let (major, minor) = ios_deployment_target();
- format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor)
-}
-
-fn ios_lld_platform_version() -> String {
- let (major, minor) = ios_deployment_target();
- format!("{major}.{minor}")
-}
-
-pub fn ios_sim_llvm_target(arch: Arch) -> String {
- let (major, minor) = ios_deployment_target();
- format!("{}-apple-ios{}.{}.0-simulator", arch.target_name(), major, minor)
-}
-
-fn tvos_deployment_target() -> (u32, u32) {
- // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
- from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
-}
-
-fn tvos_lld_platform_version() -> String {
- let (major, minor) = tvos_deployment_target();
- format!("{major}.{minor}")
-}
-
-pub fn tvos_llvm_target(arch: Arch) -> String {
- let (major, minor) = tvos_deployment_target();
- format!("{}-apple-tvos{}.{}.0", arch.target_name(), major, minor)
-}
-
-pub fn tvos_sim_llvm_target(arch: Arch) -> String {
- let (major, minor) = tvos_deployment_target();
- format!("{}-apple-tvos{}.{}.0-simulator", arch.target_name(), major, minor)
-}
-
-fn watchos_deployment_target() -> (u32, u32) {
- // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
- from_set_deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
-}
-
-fn watchos_lld_platform_version() -> String {
- let (major, minor) = watchos_deployment_target();
- format!("{major}.{minor}")
-}
-
-pub fn watchos_sim_llvm_target(arch: Arch) -> String {
- let (major, minor) = watchos_deployment_target();
- format!("{}-apple-watchos{}.{}.0-simulator", arch.target_name(), major, minor)
-}