Skip to content

Commit 53272c5

Browse files
authored
Merge pull request #662 from vladimir-ea/watch_os
Add support for Apple WatchOS
2 parents f2e1b1c + f461a55 commit 53272c5

File tree

1 file changed

+66
-18
lines changed

1 file changed

+66
-18
lines changed

src/lib.rs

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
use std::collections::HashMap;
6060
use std::env;
6161
use std::ffi::{OsStr, OsString};
62-
use std::fmt::{self, Display};
62+
use std::fmt::{self, Display, Formatter};
6363
use std::fs;
6464
use std::io::{self, BufRead, BufReader, Read, Write};
6565
use std::path::{Component, Path, PathBuf};
@@ -168,7 +168,7 @@ impl From<io::Error> for Error {
168168
}
169169

170170
impl Display for Error {
171-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172172
write!(f, "{:?}: {}", self.kind, self.message)
173173
}
174174
}
@@ -1529,7 +1529,7 @@ impl Build {
15291529
cmd.push_opt_unless_duplicate("-DANDROID".into());
15301530
}
15311531

1532-
if !target.contains("apple-ios") {
1532+
if !target.contains("apple-ios") && !target.contains("apple-watchos") {
15331533
cmd.push_cc_arg("-ffunction-sections".into());
15341534
cmd.push_cc_arg("-fdata-sections".into());
15351535
}
@@ -1597,6 +1597,20 @@ impl Build {
15971597
.into(),
15981598
);
15991599
}
1600+
} else if target.contains("watchos-sim") {
1601+
if let Some(arch) =
1602+
map_darwin_target_from_rust_to_compiler_architecture(target)
1603+
{
1604+
let deployment_target = env::var("WATCHOS_DEPLOYMENT_TARGET")
1605+
.unwrap_or_else(|_| "5.0".into());
1606+
cmd.args.push(
1607+
format!(
1608+
"--target={}-apple-watchos{}-simulator",
1609+
arch, deployment_target
1610+
)
1611+
.into(),
1612+
);
1613+
}
16001614
} else if target.starts_with("riscv64gc-") {
16011615
cmd.args.push(
16021616
format!("--target={}", target.replace("riscv64gc", "riscv64")).into(),
@@ -1856,8 +1870,8 @@ impl Build {
18561870
}
18571871
}
18581872

1859-
if target.contains("apple-ios") {
1860-
self.ios_flags(cmd)?;
1873+
if target.contains("apple-ios") || target.contains("apple-watchos") {
1874+
self.ios_watchos_flags(cmd)?;
18611875
}
18621876

18631877
if self.static_flag.unwrap_or(false) {
@@ -2050,18 +2064,37 @@ impl Build {
20502064
Ok(())
20512065
}
20522066

2053-
fn ios_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
2067+
fn ios_watchos_flags(&self, cmd: &mut Tool) -> Result<(), Error> {
20542068
enum ArchSpec {
20552069
Device(&'static str),
20562070
Simulator(&'static str),
20572071
Catalyst(&'static str),
20582072
}
20592073

2074+
enum Os {
2075+
Ios,
2076+
WatchOs,
2077+
}
2078+
impl Display for Os {
2079+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
2080+
match self {
2081+
Os::Ios => f.write_str("iOS"),
2082+
Os::WatchOs => f.write_str("WatchOS"),
2083+
}
2084+
}
2085+
}
2086+
20602087
let target = self.get_target()?;
2088+
let os = if target.contains("-watchos") {
2089+
Os::WatchOs
2090+
} else {
2091+
Os::Ios
2092+
};
2093+
20612094
let arch = target.split('-').nth(0).ok_or_else(|| {
20622095
Error::new(
20632096
ErrorKind::ArchitectureInvalid,
2064-
"Unknown architecture for iOS target.",
2097+
format!("Unknown architecture for {} target.", os).as_str(),
20652098
)
20662099
})?;
20672100

@@ -2090,6 +2123,7 @@ impl Build {
20902123
} else if is_sim {
20912124
match arch {
20922125
"arm64" | "aarch64" => ArchSpec::Simulator("-arch arm64"),
2126+
"x86_64" => ArchSpec::Simulator("-m64"),
20932127
_ => {
20942128
return Err(Error::new(
20952129
ErrorKind::ArchitectureInvalid,
@@ -2100,42 +2134,54 @@ impl Build {
21002134
} else {
21012135
match arch {
21022136
"arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"),
2137+
"armv7k" => ArchSpec::Device("armv7k"),
21032138
"armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"),
21042139
"arm64e" => ArchSpec::Device("arm64e"),
21052140
"arm64" | "aarch64" => ArchSpec::Device("arm64"),
2141+
"arm64_32" => ArchSpec::Device("arm64_32"),
21062142
"i386" | "i686" => ArchSpec::Simulator("-m32"),
21072143
"x86_64" => ArchSpec::Simulator("-m64"),
21082144
_ => {
21092145
return Err(Error::new(
21102146
ErrorKind::ArchitectureInvalid,
2111-
"Unknown architecture for iOS target.",
2147+
format!("Unknown architecture for {} target.", os).as_str(),
21122148
));
21132149
}
21142150
}
21152151
};
21162152

2117-
let min_version =
2118-
std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into());
2153+
let (sdk_prefix, sim_prefix, min_version) = match os {
2154+
Os::Ios => (
2155+
"iphone",
2156+
"ios-",
2157+
std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()),
2158+
),
2159+
Os::WatchOs => (
2160+
"watch",
2161+
"watch",
2162+
std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()),
2163+
),
2164+
};
21192165

21202166
let sdk = match arch {
21212167
ArchSpec::Device(arch) => {
21222168
cmd.args.push("-arch".into());
21232169
cmd.args.push(arch.into());
21242170
cmd.args
2125-
.push(format!("-miphoneos-version-min={}", min_version).into());
2126-
"iphoneos"
2171+
.push(format!("-m{}os-version-min={}", sdk_prefix, min_version).into());
2172+
format!("{}os", sdk_prefix)
21272173
}
21282174
ArchSpec::Simulator(arch) => {
21292175
cmd.args.push(arch.into());
21302176
cmd.args
2131-
.push(format!("-mios-simulator-version-min={}", min_version).into());
2132-
"iphonesimulator"
2177+
.push(format!("-m{}simulator-version-min={}", sim_prefix, min_version).into());
2178+
format!("{}simulator", sdk_prefix)
21332179
}
2134-
ArchSpec::Catalyst(_) => "macosx",
2180+
ArchSpec::Catalyst(_) => "macosx".to_owned(),
21352181
};
21362182

2137-
self.print(&format!("Detecting iOS SDK path for {}", sdk));
2138-
let sdk_path = self.apple_sdk_root(sdk)?;
2183+
self.print(&format!("Detecting {} SDK path for {}", os, sdk));
2184+
let sdk_path = self.apple_sdk_root(sdk.as_str())?;
21392185
cmd.args.push("-isysroot".into());
21402186
cmd.args.push(sdk_path);
21412187
cmd.args.push("-fembed-bitcode".into());
@@ -2237,6 +2283,8 @@ impl Build {
22372283
}
22382284
} else if target.contains("apple-ios") {
22392285
clang.to_string()
2286+
} else if target.contains("apple-watchos") {
2287+
clang.to_string()
22402288
} else if target.contains("android") {
22412289
autodetect_android_compiler(&target, &host, gnu, clang)
22422290
} else if target.contains("cloudabi") {
@@ -2813,7 +2861,7 @@ impl Build {
28132861
Err(_) => {
28142862
return Err(Error::new(
28152863
ErrorKind::IOError,
2816-
"Unable to determine iOS SDK path.",
2864+
"Unable to determine Apple SDK path.",
28172865
));
28182866
}
28192867
};

0 commit comments

Comments
 (0)