diff options
Diffstat (limited to 'compiler/rustc_target/src/spec/apple_base.rs')
-rw-r--r-- | compiler/rustc_target/src/spec/apple_base.rs | 356 |
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) -} |