1 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
5 use std::process::Command;
9 #[allow(non_camel_case_types)]
10 #[derive(Copy, Clone)]
21 pub fn to_string(self) -> &'static str {
28 X86_64_macabi => "x86_64",
33 pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
34 // Following what clang does
35 // (https://github.com/llvm/llvm-project/blob/
36 // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
37 // to allow the SDK path to be set. (For clang, xcrun sets
38 // SDKROOT; for rustc, the user or build system can set it, or we
39 // can fall back to checking for xcrun on PATH.)
40 if let Some(sdkroot) = env::var("SDKROOT").ok() {
41 let p = Path::new(&sdkroot);
43 // Ignore `SDKROOT` if it's clearly set for the wrong platform.
45 if sdkroot.contains("iPhoneSimulator.platform")
46 || sdkroot.contains("MacOSX.platform") =>
51 if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") =>
56 if sdkroot.contains("iPhoneOS.platform")
57 || sdkroot.contains("iPhoneSimulator.platform") =>
61 // Ignore `SDKROOT` if it's not a valid path.
62 _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => (),
63 _ => return Ok(sdkroot),
67 Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
69 if output.status.success() {
70 Ok(String::from_utf8(output.stdout).unwrap())
72 let error = String::from_utf8(output.stderr);
73 let error = format!("process exit with error: {}", error.unwrap());
74 Err(io::Error::new(io::ErrorKind::Other, &error[..]))
80 Ok(output) => Ok(output.trim().to_string()),
81 Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
85 fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
86 let sdk_name = match arch {
87 Armv7 | Armv7s | Arm64 => "iphoneos",
88 I386 | X86_64 => "iphonesimulator",
89 X86_64_macabi => "macosx10.15",
92 let arch_name = arch.to_string();
94 let sdk_root = get_sdk_root(sdk_name)?;
96 let mut args = LinkArgs::new();
101 arch_name.to_string(),
102 "-isysroot".to_string(),
104 "-Wl,-syslibroot".to_string(),
112 fn target_cpu(arch: Arch) -> String {
114 Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
115 Armv7s => "cortex-a9",
119 X86_64_macabi => "core2",
124 fn link_env_remove(arch: Arch) -> Vec<String> {
126 Armv7 | Armv7s | Arm64 | I386 | X86_64 => vec!["MACOSX_DEPLOYMENT_TARGET".to_string()],
127 X86_64_macabi => vec!["IPHONEOS_DEPLOYMENT_TARGET".to_string()],
131 pub fn opts(arch: Arch) -> Result<TargetOptions, String> {
132 let pre_link_args = build_pre_link_args(arch)?;
134 cpu: target_cpu(arch),
135 dynamic_linking: false,
138 link_env_remove: link_env_remove(arch),
140 eliminate_frame_pointer: false,
141 ..super::apple_base::opts()