Skip to content

Commit 6498d9c

Browse files
committed
Fix AppleClang darwin build & AppleTVOS support
- Fix AppleClang build for -apple-darwin to add -isysroot for MacOSX sdk correctly - Add AppleTVOS support - Respect MACOSX_DEPLOYMENT_TARGET
1 parent 53fb72c commit 6498d9c

File tree

1 file changed

+91
-13
lines changed

1 file changed

+91
-13
lines changed

src/lib.rs

+91-13
Original file line numberDiff line numberDiff line change
@@ -1611,6 +1611,20 @@ impl Build {
16111611
.into(),
16121612
);
16131613
}
1614+
} else if target.contains("tvos-sim") {
1615+
if let Some(arch) =
1616+
map_darwin_target_from_rust_to_compiler_architecture(target)
1617+
{
1618+
let deployment_target =
1619+
env::var("TVOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "9.0".into());
1620+
cmd.args.push(
1621+
format!(
1622+
"--target={}-apple-tvos{}-simulator",
1623+
arch, deployment_target
1624+
)
1625+
.into(),
1626+
);
1627+
}
16141628
} else if target.starts_with("riscv64gc-") {
16151629
cmd.args.push(
16161630
format!("--target={}", target.replace("riscv64gc", "riscv64")).into(),
@@ -1870,8 +1884,8 @@ impl Build {
18701884
}
18711885
}
18721886

1873-
if target.contains("apple-ios") || target.contains("apple-watchos") {
1874-
self.ios_watchos_flags(cmd)?;
1887+
if target.contains("-apple-") {
1888+
self.apple_flags(cmd)?;
18751889
}
18761890

18771891
if self.static_flag.unwrap_or(false) {
@@ -2064,32 +2078,44 @@ impl Build {
20642078
Ok(())
20652079
}
20662080

2067-
fn ios_watchos_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
2081+
fn apple_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
20682082
enum ArchSpec {
20692083
Device(&'static str),
20702084
Simulator(&'static str),
20712085
Catalyst(&'static str),
20722086
}
20732087

20742088
enum Os {
2089+
MacOs,
20752090
Ios,
20762091
WatchOs,
2092+
TvOs,
20772093
}
20782094
impl Display for Os {
20792095
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
20802096
match self {
2097+
Os::MacOs => f.write_str("macOS"),
20812098
Os::Ios => f.write_str("iOS"),
20822099
Os::WatchOs => f.write_str("WatchOS"),
2100+
Os::TvOs => f.write_str("tvOS"),
20832101
}
20842102
}
20852103
}
20862104

20872105
let target = self.get_target()?;
2088-
let os = if target.contains("-watchos") {
2106+
let os = if target.contains("-darwin") {
2107+
Os::MacOs
2108+
} else if target.contains("-watchos") {
20892109
Os::WatchOs
2110+
} else if target.contains("-tvos") {
2111+
Os::TvOs
20902112
} else {
20912113
Os::Ios
20922114
};
2115+
let is_mac = match os {
2116+
Os::MacOs => true,
2117+
_ => false,
2118+
};
20932119

20942120
let arch = target.split('-').nth(0).ok_or_else(|| {
20952121
Error::new(
@@ -2103,12 +2129,23 @@ impl Build {
21032129
None => false,
21042130
};
21052131

2106-
let is_sim = match target.split('-').nth(3) {
2132+
let is_arm_sim = match target.split('-').nth(3) {
21072133
Some(v) => v == "sim",
21082134
None => false,
21092135
};
21102136

2111-
let arch = if is_catalyst {
2137+
let arch = if is_mac {
2138+
match arch {
2139+
"i686" => ArchSpec::Device("-m32"),
2140+
"x86_64" | "aarch64" => ArchSpec::Device("-m64"),
2141+
_ => {
2142+
return Err(Error::new(
2143+
ErrorKind::ArchitectureInvalid,
2144+
"Unknown architecture for macOS target.",
2145+
));
2146+
}
2147+
}
2148+
} else if is_catalyst {
21122149
match arch {
21132150
"arm64e" => ArchSpec::Catalyst("arm64e"),
21142151
"arm64" | "aarch64" => ArchSpec::Catalyst("arm64"),
@@ -2120,14 +2157,14 @@ impl Build {
21202157
));
21212158
}
21222159
}
2123-
} else if is_sim {
2160+
} else if is_arm_sim {
21242161
match arch {
21252162
"arm64" | "aarch64" => ArchSpec::Simulator("-arch arm64"),
21262163
"x86_64" => ArchSpec::Simulator("-m64"),
21272164
_ => {
21282165
return Err(Error::new(
21292166
ErrorKind::ArchitectureInvalid,
2130-
"Unknown architecture for iOS simulator target.",
2167+
"Unknown architecture for simulator target.",
21312168
));
21322169
}
21332170
}
@@ -2151,6 +2188,11 @@ impl Build {
21512188
};
21522189

21532190
let (sdk_prefix, sim_prefix, min_version) = match os {
2191+
Os::MacOs => (
2192+
"macosx",
2193+
"",
2194+
std::env::var("MACOSX_DEPLOYMENT_TARGET").unwrap_or_else(|_| "10.0".into()),
2195+
),
21542196
Os::Ios => (
21552197
"iphone",
21562198
"ios-",
@@ -2161,9 +2203,20 @@ impl Build {
21612203
"watch",
21622204
std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()),
21632205
),
2206+
Os::TvOs => (
2207+
"tv",
2208+
"tv",
2209+
std::env::var("TVOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "9.0".into()),
2210+
),
21642211
};
21652212

21662213
let sdk = match arch {
2214+
ArchSpec::Device(arch) if is_mac => {
2215+
cmd.args.push(arch.into());
2216+
cmd.args
2217+
.push(format!("-mmacosx-version-min={}", min_version).into());
2218+
"macosx".to_owned()
2219+
}
21672220
ArchSpec::Device(arch) => {
21682221
cmd.args.push("-arch".into());
21692222
cmd.args.push(arch.into());
@@ -2180,11 +2233,17 @@ impl Build {
21802233
ArchSpec::Catalyst(_) => "macosx".to_owned(),
21812234
};
21822235

2183-
self.print(&format!("Detecting {} SDK path for {}", os, sdk));
2184-
let sdk_path = self.apple_sdk_root(sdk.as_str())?;
2185-
cmd.args.push("-isysroot".into());
2186-
cmd.args.push(sdk_path);
2187-
cmd.args.push("-fembed-bitcode".into());
2236+
// AppleClang sometimes needs sysroot even for darwin
2237+
if cmd.check_apple_clang() || !target.ends_with("-darwin") {
2238+
self.print(&format!("Detecting {} SDK path for {}", os, sdk));
2239+
let sdk_path = self.apple_sdk_root(sdk.as_str())?;
2240+
cmd.args.push("-isysroot".into());
2241+
cmd.args.push(sdk_path);
2242+
}
2243+
2244+
if !is_mac {
2245+
cmd.args.push("-fembed-bitcode".into());
2246+
}
21882247
/*
21892248
* TODO we probably ultimately want the -fembed-bitcode-marker flag
21902249
* but can't have it now because of an issue in LLVM:
@@ -3080,6 +3139,25 @@ impl Tool {
30803139
self.family == ToolFamily::Clang
30813140
}
30823141

3142+
/// Whether the tool is AppleClang.
3143+
#[cfg(target_os = "macos")]
3144+
fn check_apple_clang(&self) -> bool {
3145+
if self.family != ToolFamily::Clang {
3146+
return false;
3147+
}
3148+
let output = std::process::Command::new(&self.path)
3149+
.arg("--version")
3150+
.output();
3151+
match output {
3152+
Ok(output) => String::from_utf8_lossy(&output.stdout).contains("Apple clang"),
3153+
Err(_) => false,
3154+
}
3155+
}
3156+
#[cfg(not(target_os = "macos"))]
3157+
fn check_apple_clang(&self) -> bool {
3158+
false
3159+
}
3160+
30833161
/// Whether the tool is MSVC-like.
30843162
pub fn is_like_msvc(&self) -> bool {
30853163
match self.family {

0 commit comments

Comments
 (0)