From dddc9e580a599b603f64c0db411dafc549addfc2 Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Thu, 17 Jun 2021 15:18:45 +0100 Subject: [PATCH 1/7] [watchos] Add support for watchOS --- src/lib.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b62a1da0..cedeec75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1416,7 +1416,7 @@ impl Build { cmd.push_opt_unless_duplicate("-DANDROID".into()); } - if !target.contains("apple-ios") { + if !target.contains("apple-ios") && !target.contains("apple-watchos") { cmd.push_cc_arg("-ffunction-sections".into()); cmd.push_cc_arg("-fdata-sections".into()); } @@ -1484,6 +1484,19 @@ impl Build { .into(), ); } + } else if target.contains("watchos-sim") { + if let Some(arch) = + map_darwin_target_from_rust_to_compiler_architecture(target) + { + let deployment_target = env::var("WATCHOS_DEPLOYMENT_TARGET") + .unwrap_or_else(|_| "5.0".into()); + cmd.args.push( + format!( + "--target={}-apple-watchos{}-simulator", + arch, deployment_target + ).into(), + ); + } } else if target.starts_with("riscv64gc-") { cmd.args.push( format!("--target={}", target.replace("riscv64gc", "riscv64")).into(), @@ -1720,6 +1733,10 @@ impl Build { self.ios_flags(cmd)?; } + if target.contains("apple-watchos") { + self.watchos_flags(cmd)?; + } + if self.static_flag.unwrap_or(false) { cmd.args.push("-static".into()); } @@ -1984,6 +2001,74 @@ impl Build { Ok(()) } + fn watchos_flags(&self, cmd: &mut Tool) -> Result<(), Error> { + enum ArchSpec { + Device(&'static str), + Simulator(&'static str), + } + + let target = self.get_target()?; + let arch = target.split('-').nth(0).ok_or_else(|| { + Error::new( + ErrorKind::ArchitectureInvalid, + "Unknown architecture for watchOS target.", + ) + })?; + + let arch = match arch { + "armv7k" => ArchSpec::Device("armv7k"), + "arm64_32" => ArchSpec::Device("arm64_32"), + "i386" | "i686" => ArchSpec::Simulator("-m32"), + "x86_64" => ArchSpec::Simulator("-m64"), + _ => { + return Err(Error::new( + ErrorKind::ArchitectureInvalid, + "Unknown architecture for watchOS target.", + )); + } + + }; + + let min_version = + std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()); + + + let sdk = match arch { + ArchSpec::Device(arch) => { + cmd.args.push("-arch".into()); + cmd.args.push(arch.into()); + cmd.args + .push(format!("-mwatchos-version-min={}", min_version).into()); + "watchos" + } + ArchSpec::Simulator(arch) => { + cmd.args.push(arch.into()); + cmd.args + .push(format!("-mwatch-simulator-version-min={}", min_version).into()); + "watchsimulator" + } + }; + + self.print(&format!("Detecting watchOS SDK path for {}", sdk)); + let sdk_path = self.apple_sdk_root(sdk)?; + cmd.args.push("-isysroot".into()); + cmd.args.push(sdk_path); + cmd.args.push("-fembed-bitcode".into()); + /* + * TODO we probably ultimately want the -fembed-bitcode-marker flag + * but can't have it now because of an issue in LLVM: + * https://github.com/alexcrichton/cc-rs/issues/301 + * https://github.com/rust-lang/rust/pull/48896#comment-372192660 + */ + /* + if self.get_opt_level()? == "0" { + cmd.args.push("-fembed-bitcode-marker".into()); + } + */ + + Ok(()) + } + fn cmd>(&self, prog: P) -> Command { let mut cmd = Command::new(prog); for &(ref a, ref b) in self.env.iter() { @@ -2067,6 +2152,8 @@ impl Build { } } else if target.contains("apple-ios") { clang.to_string() + } else if target.contains("apple-watchos") { + clang.to_string() } else if target.contains("android") { autodetect_android_compiler(&target, &host, gnu, clang) } else if target.contains("cloudabi") { @@ -2630,7 +2717,7 @@ impl Build { Err(_) => { return Err(Error::new( ErrorKind::IOError, - "Unable to determine iOS SDK path.", + "Unable to determine Apple SDK path.", )); } }; From 2a22393362530b9591bbfc55a726bb8403e2a828 Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Thu, 17 Jun 2021 17:33:30 +0100 Subject: [PATCH 2/7] [watch_os] lifetime fix --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cedeec75..8ace735d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -165,7 +165,7 @@ impl From for Error { } impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", self.kind, self.message) } } @@ -2044,7 +2044,7 @@ impl Build { ArchSpec::Simulator(arch) => { cmd.args.push(arch.into()); cmd.args - .push(format!("-mwatch-simulator-version-min={}", min_version).into()); + .push(format!("-mwatchsimulator-version-min={}", min_version).into()); "watchsimulator" } }; From 19525e20db749a6e51f56869d1bfda4743da9942 Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Thu, 17 Jun 2021 17:33:30 +0100 Subject: [PATCH 3/7] [watch_os] lifetime fix --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fee2c0f4..4112c741 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -168,7 +168,7 @@ impl From for Error { } impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{:?}: {}", self.kind, self.message) } } @@ -2207,7 +2207,7 @@ impl Build { ArchSpec::Simulator(arch) => { cmd.args.push(arch.into()); cmd.args - .push(format!("-mwatch-simulator-version-min={}", min_version).into()); + .push(format!("-mwatchsimulator-version-min={}", min_version).into()); "watchsimulator" } }; From 73f8fe4b5c0024d855398e4fa4ae68b5b82221f2 Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Tue, 8 Mar 2022 11:50:04 +0000 Subject: [PATCH 4/7] [watch_os] fix formatting --- src/lib.rs | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4112c741..f7605320 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1592,7 +1592,7 @@ impl Build { } } else if target.contains("watchos-sim") { if let Some(arch) = - map_darwin_target_from_rust_to_compiler_architecture(target) + map_darwin_target_from_rust_to_compiler_architecture(target) { let deployment_target = env::var("WATCHOS_DEPLOYMENT_TARGET") .unwrap_or_else(|_| "5.0".into()); @@ -1600,7 +1600,8 @@ impl Build { format!( "--target={}-apple-watchos{}-simulator", arch, deployment_target - ).into(), + ) + .into(), ); } } else if target.starts_with("riscv64gc-") { @@ -2179,23 +2180,21 @@ impl Build { })?; let arch = match arch { - "armv7k" => ArchSpec::Device("armv7k"), - "arm64_32" => ArchSpec::Device("arm64_32"), - "i386" | "i686" => ArchSpec::Simulator("-m32"), - "x86_64" => ArchSpec::Simulator("-m64"), - _ => { - return Err(Error::new( - ErrorKind::ArchitectureInvalid, - "Unknown architecture for watchOS target.", - )); - } - + "armv7k" => ArchSpec::Device("armv7k"), + "arm64_32" => ArchSpec::Device("arm64_32"), + "i386" | "i686" => ArchSpec::Simulator("-m32"), + "x86_64" => ArchSpec::Simulator("-m64"), + _ => { + return Err(Error::new( + ErrorKind::ArchitectureInvalid, + "Unknown architecture for watchOS target.", + )); + } }; let min_version = std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()); - let sdk = match arch { ArchSpec::Device(arch) => { cmd.args.push("-arch".into()); From d5a711e72ecc71cc932e9e9a27a004f7a72a3ce3 Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Tue, 8 Mar 2022 17:56:33 +0000 Subject: [PATCH 5/7] [watchos] Make a single flags function for ios and watchos --- src/lib.rs | 118 +++++++++++++++++------------------------------------ 1 file changed, 38 insertions(+), 80 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f7605320..d19c4a7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -59,7 +59,7 @@ use std::collections::HashMap; use std::env; use std::ffi::{OsStr, OsString}; -use std::fmt::{self, Display}; +use std::fmt::{self, Display, Formatter}; use std::fs; use std::io::{self, BufRead, BufReader, Read, Write}; use std::path::{Component, Path, PathBuf}; @@ -1864,11 +1864,11 @@ impl Build { } if target.contains("apple-ios") { - self.ios_flags(cmd)?; + self.ios_watchos_flags(cmd)?; } if target.contains("apple-watchos") { - self.watchos_flags(cmd)?; + self.ios_watchos_flags(cmd)?; } if self.static_flag.unwrap_or(false) { @@ -2061,18 +2061,37 @@ impl Build { Ok(()) } - fn ios_flags(&self, cmd: &mut Tool) -> Result<(), Error> { + fn ios_watchos_flags(&self, cmd: &mut Tool) -> Result<(), Error> { enum ArchSpec { Device(&'static str), Simulator(&'static str), Catalyst(&'static str), } + enum Os { + Ios, + WatchOs, + } + impl Display for Os { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Os::Ios => f.write_str("iOS"), + Os::WatchOs => f.write_str("WatchOS"), + } + } + } + let target = self.get_target()?; + let os = if target.contains("-watchos") { + Os::WatchOs + } else { + Os::Ios + }; + let arch = target.split('-').nth(0).ok_or_else(|| { Error::new( ErrorKind::ArchitectureInvalid, - "Unknown architecture for iOS target.", + format!("Unknown architecture for {} target.", os).as_str(), ) })?; @@ -2101,6 +2120,7 @@ impl Build { } else if is_sim { match arch { "arm64" | "aarch64" => ArchSpec::Simulator("-arch arm64"), + "x86_64" => ArchSpec::Simulator("-m64"), _ => { return Err(Error::new( ErrorKind::ArchitectureInvalid, @@ -2111,108 +2131,46 @@ impl Build { } else { match arch { "arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"), + "armv7k" => ArchSpec::Device("armv7k"), "armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"), "arm64e" => ArchSpec::Device("arm64e"), "arm64" | "aarch64" => ArchSpec::Device("arm64"), + "arm64_32" => ArchSpec::Device("arm64_32"), "i386" | "i686" => ArchSpec::Simulator("-m32"), "x86_64" => ArchSpec::Simulator("-m64"), _ => { return Err(Error::new( ErrorKind::ArchitectureInvalid, - "Unknown architecture for iOS target.", + format!("Unknown architecture for {} target.", os).as_str(), )); } } }; - let min_version = - std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()); - - let sdk = match arch { - ArchSpec::Device(arch) => { - cmd.args.push("-arch".into()); - cmd.args.push(arch.into()); - cmd.args - .push(format!("-miphoneos-version-min={}", min_version).into()); - "iphoneos" - } - ArchSpec::Simulator(arch) => { - cmd.args.push(arch.into()); - cmd.args - .push(format!("-mios-simulator-version-min={}", min_version).into()); - "iphonesimulator" - } - ArchSpec::Catalyst(_) => "macosx", - }; - - self.print(&format!("Detecting iOS SDK path for {}", sdk)); - let sdk_path = self.apple_sdk_root(sdk)?; - cmd.args.push("-isysroot".into()); - cmd.args.push(sdk_path); - cmd.args.push("-fembed-bitcode".into()); - /* - * TODO we probably ultimately want the -fembed-bitcode-marker flag - * but can't have it now because of an issue in LLVM: - * https://github.com/alexcrichton/cc-rs/issues/301 - * https://github.com/rust-lang/rust/pull/48896#comment-372192660 - */ - /* - if self.get_opt_level()? == "0" { - cmd.args.push("-fembed-bitcode-marker".into()); - } - */ - - Ok(()) - } - - fn watchos_flags(&self, cmd: &mut Tool) -> Result<(), Error> { - enum ArchSpec { - Device(&'static str), - Simulator(&'static str), - } - - let target = self.get_target()?; - let arch = target.split('-').nth(0).ok_or_else(|| { - Error::new( - ErrorKind::ArchitectureInvalid, - "Unknown architecture for watchOS target.", - ) - })?; - - let arch = match arch { - "armv7k" => ArchSpec::Device("armv7k"), - "arm64_32" => ArchSpec::Device("arm64_32"), - "i386" | "i686" => ArchSpec::Simulator("-m32"), - "x86_64" => ArchSpec::Simulator("-m64"), - _ => { - return Err(Error::new( - ErrorKind::ArchitectureInvalid, - "Unknown architecture for watchOS target.", - )); - } + let (sdk_prefix, sim_prefix, min_version) = match os { + Os::Ios => ("iphone", "ios-", std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into())), + Os::WatchOs => ("watch", "watch", std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into())), }; - let min_version = - std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()); - let sdk = match arch { ArchSpec::Device(arch) => { cmd.args.push("-arch".into()); cmd.args.push(arch.into()); cmd.args - .push(format!("-mwatchos-version-min={}", min_version).into()); - "watchos" + .push(format!("-m{}os-version-min={}", sdk_prefix, min_version).into()); + format!("{}os", sdk_prefix) } ArchSpec::Simulator(arch) => { cmd.args.push(arch.into()); cmd.args - .push(format!("-mwatchsimulator-version-min={}", min_version).into()); - "watchsimulator" + .push(format!("-m{}simulator-version-min={}", sim_prefix, min_version).into()); + format!("{}simulator", sdk_prefix) } + ArchSpec::Catalyst(_) => "macosx".to_owned(), }; - self.print(&format!("Detecting watchOS SDK path for {}", sdk)); - let sdk_path = self.apple_sdk_root(sdk)?; + self.print(&format!("Detecting {} SDK path for {}", os, sdk)); + let sdk_path = self.apple_sdk_root(sdk.as_str())?; cmd.args.push("-isysroot".into()); cmd.args.push(sdk_path); cmd.args.push("-fembed-bitcode".into()); From ceb03741e2973651ce8ada26a0250ac32f64eb6a Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Tue, 8 Mar 2022 17:59:36 +0000 Subject: [PATCH 6/7] [watchos] fix format --- src/lib.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d19c4a7b..97d27373 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2148,8 +2148,16 @@ impl Build { }; let (sdk_prefix, sim_prefix, min_version) = match os { - Os::Ios => ("iphone", "ios-", std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into())), - Os::WatchOs => ("watch", "watch", std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into())), + Os::Ios => ( + "iphone", + "ios-", + std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()), + ), + Os::WatchOs => ( + "watch", + "watch", + std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()), + ), }; let sdk = match arch { From f461a550c3dd0c94a308a47720989650d75db0ff Mon Sep 17 00:00:00 2001 From: Vladimir Michael Eatwell Date: Tue, 8 Mar 2022 18:27:29 +0000 Subject: [PATCH 7/7] [watchos] remove redundant if statement --- src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 97d27373..7101cf50 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1863,11 +1863,7 @@ impl Build { } } - if target.contains("apple-ios") { - self.ios_watchos_flags(cmd)?; - } - - if target.contains("apple-watchos") { + if target.contains("apple-ios") || target.contains("apple-watchos") { self.ios_watchos_flags(cmd)?; }