Skip to content

Commit c29a29c

Browse files
committed
Defer Apple SDKROOT detection to link time.
1 parent b984ef6 commit c29a29c

10 files changed

+104
-128
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor)
12891289
cmd.args(args);
12901290
}
12911291
cmd.args(&sess.opts.debugging_opts.pre_link_args);
1292+
add_apple_sdk(cmd, sess, flavor);
12921293
}
12931294

12941295
/// Add a link script embedded in the target, if applicable.
@@ -2083,3 +2084,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
20832084
config::Lto::No | config::Lto::ThinLocal => false,
20842085
}
20852086
}
2087+
2088+
fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2089+
let arch = &sess.target.target.arch;
2090+
let os = &sess.target.target.target_os;
2091+
let llvm_target = &sess.target.target.llvm_target;
2092+
if sess.target.target.target_vendor != "apple"
2093+
|| !matches!(os.as_str(), "ios" | "tvos")
2094+
|| flavor != LinkerFlavor::Gcc
2095+
{
2096+
return;
2097+
}
2098+
let sdk_name = match (arch.as_str(), os.as_str()) {
2099+
("aarch64", "tvos") => "appletvos",
2100+
("x86_64", "tvos") => "appletvsimulator",
2101+
("arm", "ios") => "iphoneos",
2102+
("aarch64", "ios") => "iphoneos",
2103+
("x86", "ios") => "iphonesimulator",
2104+
("x86_64", "ios") if llvm_target.contains("macabi") => "macosx10.15",
2105+
("x86_64", "ios") => "iphonesimulator",
2106+
_ => {
2107+
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
2108+
return;
2109+
}
2110+
};
2111+
let sdk_root = match get_apple_sdk_root(sdk_name) {
2112+
Ok(s) => s,
2113+
Err(e) => {
2114+
sess.err(&e);
2115+
return;
2116+
}
2117+
};
2118+
let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
2119+
cmd.args(&["-arch", arch_name, "-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
2120+
}
2121+
2122+
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
2123+
// Following what clang does
2124+
// (https://github.com/llvm/llvm-project/blob/
2125+
// 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
2126+
// to allow the SDK path to be set. (For clang, xcrun sets
2127+
// SDKROOT; for rustc, the user or build system can set it, or we
2128+
// can fall back to checking for xcrun on PATH.)
2129+
if let Ok(sdkroot) = env::var("SDKROOT") {
2130+
let p = Path::new(&sdkroot);
2131+
match sdk_name {
2132+
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
2133+
"appletvos"
2134+
if sdkroot.contains("TVSimulator.platform")
2135+
|| sdkroot.contains("MacOSX.platform") => {}
2136+
"appletvsimulator"
2137+
if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => {}
2138+
"iphoneos"
2139+
if sdkroot.contains("iPhoneSimulator.platform")
2140+
|| sdkroot.contains("MacOSX.platform") => {}
2141+
"iphonesimulator"
2142+
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") => {
2143+
}
2144+
"macosx10.15"
2145+
if sdkroot.contains("iPhoneOS.platform")
2146+
|| sdkroot.contains("iPhoneSimulator.platform") => {}
2147+
// Ignore `SDKROOT` if it's not a valid path.
2148+
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
2149+
_ => return Ok(sdkroot),
2150+
}
2151+
}
2152+
let res =
2153+
Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
2154+
|output| {
2155+
if output.status.success() {
2156+
Ok(String::from_utf8(output.stdout).unwrap())
2157+
} else {
2158+
let error = String::from_utf8(output.stderr);
2159+
let error = format!("process exit with error: {}", error.unwrap());
2160+
Err(io::Error::new(io::ErrorKind::Other, &error[..]))
2161+
}
2162+
},
2163+
);
2164+
2165+
match res {
2166+
Ok(output) => Ok(output.trim().to_string()),
2167+
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
2168+
}
2169+
}

compiler/rustc_target/src/spec/aarch64_apple_ios.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::Arm64, AppleOS::iOS)?;
5+
let base = opts(Arch::Arm64);
66
Ok(Target {
77
llvm_target: "arm64-apple-ios".to_string(),
88
target_endian: "little".to_string(),

compiler/rustc_target/src/spec/aarch64_apple_tvos.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::Arm64, AppleOS::tvOS)?;
5+
let base = opts(Arch::Arm64);
66
Ok(Target {
77
llvm_target: "arm64-apple-tvos".to_string(),
88
target_endian: "little".to_string(),
Lines changed: 4 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
2-
use std::env;
3-
use std::io;
4-
use std::path::Path;
5-
use std::process::Command;
1+
use crate::spec::TargetOptions;
62

73
use Arch::*;
84
#[allow(non_camel_case_types)]
@@ -16,108 +12,6 @@ pub enum Arch {
1612
X86_64_macabi,
1713
}
1814

19-
#[allow(non_camel_case_types)]
20-
#[derive(Copy, Clone)]
21-
pub enum AppleOS {
22-
tvOS,
23-
iOS,
24-
}
25-
26-
impl Arch {
27-
pub fn to_string(self) -> &'static str {
28-
match self {
29-
Armv7 => "armv7",
30-
Armv7s => "armv7s",
31-
Arm64 => "arm64",
32-
I386 => "i386",
33-
X86_64 => "x86_64",
34-
X86_64_macabi => "x86_64",
35-
}
36-
}
37-
}
38-
39-
pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
40-
// Following what clang does
41-
// (https://github.com/llvm/llvm-project/blob/
42-
// 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
43-
// to allow the SDK path to be set. (For clang, xcrun sets
44-
// SDKROOT; for rustc, the user or build system can set it, or we
45-
// can fall back to checking for xcrun on PATH.)
46-
if let Ok(sdkroot) = env::var("SDKROOT") {
47-
let p = Path::new(&sdkroot);
48-
match sdk_name {
49-
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
50-
"appletvos"
51-
if sdkroot.contains("TVSimulator.platform")
52-
|| sdkroot.contains("MacOSX.platform") => {}
53-
"appletvsimulator"
54-
if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => {}
55-
"iphoneos"
56-
if sdkroot.contains("iPhoneSimulator.platform")
57-
|| sdkroot.contains("MacOSX.platform") => {}
58-
"iphonesimulator"
59-
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("MacOSX.platform") => {
60-
}
61-
"macosx10.15"
62-
if sdkroot.contains("iPhoneOS.platform")
63-
|| sdkroot.contains("iPhoneSimulator.platform") => {}
64-
// Ignore `SDKROOT` if it's not a valid path.
65-
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
66-
_ => return Ok(sdkroot),
67-
}
68-
}
69-
let res =
70-
Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
71-
|output| {
72-
if output.status.success() {
73-
Ok(String::from_utf8(output.stdout).unwrap())
74-
} else {
75-
let error = String::from_utf8(output.stderr);
76-
let error = format!("process exit with error: {}", error.unwrap());
77-
Err(io::Error::new(io::ErrorKind::Other, &error[..]))
78-
}
79-
},
80-
);
81-
82-
match res {
83-
Ok(output) => Ok(output.trim().to_string()),
84-
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
85-
}
86-
}
87-
88-
fn build_pre_link_args(arch: Arch, os: AppleOS) -> Result<LinkArgs, String> {
89-
let sdk_name = match (arch, os) {
90-
(Arm64, AppleOS::tvOS) => "appletvos",
91-
(X86_64, AppleOS::tvOS) => "appletvsimulator",
92-
(Armv7, AppleOS::iOS) => "iphoneos",
93-
(Armv7s, AppleOS::iOS) => "iphoneos",
94-
(Arm64, AppleOS::iOS) => "iphoneos",
95-
(I386, AppleOS::iOS) => "iphonesimulator",
96-
(X86_64, AppleOS::iOS) => "iphonesimulator",
97-
(X86_64_macabi, AppleOS::iOS) => "macosx10.15",
98-
_ => unreachable!(),
99-
};
100-
101-
let arch_name = arch.to_string();
102-
103-
let sdk_root = get_sdk_root(sdk_name)?;
104-
105-
let mut args = LinkArgs::new();
106-
args.insert(
107-
LinkerFlavor::Gcc,
108-
vec![
109-
"-arch".to_string(),
110-
arch_name.to_string(),
111-
"-isysroot".to_string(),
112-
sdk_root.clone(),
113-
"-Wl,-syslibroot".to_string(),
114-
sdk_root,
115-
],
116-
);
117-
118-
Ok(args)
119-
}
120-
12115
fn target_cpu(arch: Arch) -> String {
12216
match arch {
12317
Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
@@ -137,15 +31,13 @@ fn link_env_remove(arch: Arch) -> Vec<String> {
13731
}
13832
}
13933

140-
pub fn opts(arch: Arch, os: AppleOS) -> Result<TargetOptions, String> {
141-
let pre_link_args = build_pre_link_args(arch, os)?;
142-
Ok(TargetOptions {
34+
pub fn opts(arch: Arch) -> TargetOptions {
35+
TargetOptions {
14336
cpu: target_cpu(arch),
14437
executables: true,
145-
pre_link_args,
14638
link_env_remove: link_env_remove(arch),
14739
has_elf_tls: false,
14840
eliminate_frame_pointer: false,
14941
..super::apple_base::opts()
150-
})
42+
}
15143
}

compiler/rustc_target/src/spec/armv7_apple_ios.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::Armv7, AppleOS::iOS)?;
5+
let base = opts(Arch::Armv7);
66
Ok(Target {
77
llvm_target: "armv7-apple-ios".to_string(),
88
target_endian: "little".to_string(),

compiler/rustc_target/src/spec/armv7s_apple_ios.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::Armv7s, AppleOS::iOS)?;
5+
let base = opts(Arch::Armv7s);
66
Ok(Target {
77
llvm_target: "armv7s-apple-ios".to_string(),
88
target_endian: "little".to_string(),

compiler/rustc_target/src/spec/i386_apple_ios.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::I386, AppleOS::iOS)?;
5+
let base = opts(Arch::I386);
66
Ok(Target {
77
llvm_target: "i386-apple-ios".to_string(),
88
target_endian: "little".to_string(),

compiler/rustc_target/src/spec/x86_64_apple_ios.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::X86_64, AppleOS::iOS)?;
5+
let base = opts(Arch::X86_64);
66
Ok(Target {
77
llvm_target: "x86_64-apple-ios".to_string(),
88
target_endian: "little".to_string(),

compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::X86_64_macabi, AppleOS::iOS)?;
5+
let base = opts(Arch::X86_64_macabi);
66
Ok(Target {
77
llvm_target: "x86_64-apple-ios13.0-macabi".to_string(),
88
target_endian: "little".to_string(),

compiler/rustc_target/src/spec/x86_64_apple_tvos.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use super::apple_sdk_base::{opts, AppleOS, Arch};
1+
use super::apple_sdk_base::{opts, Arch};
22
use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
33

44
pub fn target() -> TargetResult {
5-
let base = opts(Arch::X86_64, AppleOS::iOS)?;
5+
let base = opts(Arch::X86_64);
66
Ok(Target {
77
llvm_target: "x86_64-apple-tvos".to_string(),
88
target_endian: "little".to_string(),

0 commit comments

Comments
 (0)