Skip to content

Commit 1f95eba

Browse files
authored
fix(apple): build with iOS 26 SDK on macOS with Intel chip (#491)
closes tauri-apps/tauri#14233
1 parent 87d1bdb commit 1f95eba

File tree

3 files changed

+105
-6
lines changed

3 files changed

+105
-6
lines changed

.changes/fix-ios-26-intel.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"cargo-mobile2": patch
3+
---
4+
5+
Fix build with iOS 26 SDK on macOS with Intel chip.

src/apple/project.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use once_cell_regex::regex;
2+
13
use super::{
24
config::{Config, Metadata},
35
deps, rust_version_check,
@@ -20,6 +22,10 @@ pub static TEMPLATE_PACK: &str = "xcode";
2022

2123
#[derive(Debug)]
2224
pub enum Error {
25+
CommandFailed {
26+
command: String,
27+
error: std::io::Error,
28+
},
2329
RustupFailed(std::io::Error),
2430
RustVersionCheckFailed(util::RustVersionError),
2531
DepsInstallFailed(deps::Error),
@@ -37,6 +43,9 @@ pub enum Error {
3743
impl Reportable for Error {
3844
fn report(&self) -> Report {
3945
match self {
46+
Self::CommandFailed { command, error } => {
47+
Report::error(format!("Failed to run {command}"), error)
48+
}
4049
Self::RustupFailed(err) => {
4150
Report::error("Failed to install Apple toolchains with rustup", err)
4251
}
@@ -219,3 +228,66 @@ pub fn gen(
219228
}
220229
Ok(())
221230
}
231+
232+
#[derive(Debug)]
233+
pub struct Destination {
234+
pub name: Option<String>,
235+
pub platform: Option<String>,
236+
pub arch: Option<String>,
237+
pub id: Option<String>,
238+
pub os: Option<String>,
239+
}
240+
241+
pub fn list_destinations(workspace_path: &Path, scheme: &str) -> Result<Vec<Destination>, Error> {
242+
let kv_re = regex!(r"(\w+):([^,}]+)");
243+
244+
let workspace_path = workspace_path.to_path_buf();
245+
246+
let output = duct::cmd("xcodebuild", ["-scheme", scheme, "-showdestinations"])
247+
.before_spawn(move |cmd| {
248+
cmd.arg("-workspace");
249+
cmd.arg(&workspace_path);
250+
Ok(())
251+
})
252+
.stdout_capture()
253+
.run()
254+
.map_err(|error| Error::CommandFailed {
255+
command: "xcodebuild -showdestinations".to_string(),
256+
error,
257+
})?;
258+
let stdout = String::from_utf8_lossy(&output.stdout);
259+
260+
let mut destinations = Vec::new();
261+
262+
for line in stdout.lines() {
263+
let line = line.trim();
264+
if !line.starts_with("{") {
265+
continue;
266+
}
267+
268+
let mut dest = Destination {
269+
platform: None,
270+
arch: None,
271+
id: None,
272+
name: None,
273+
os: None,
274+
};
275+
276+
for kv in kv_re.captures_iter(line) {
277+
let key = kv.get(1).unwrap().as_str();
278+
let value = kv.get(2).unwrap().as_str();
279+
match key {
280+
"platform" => dest.platform = Some(value.trim().to_string()),
281+
"arch" => dest.arch = Some(value.trim().to_string()),
282+
"id" => dest.id = Some(value.trim().to_string()),
283+
"name" => dest.name = Some(value.trim().to_string()),
284+
"OS" => dest.os = Some(value.trim().to_string()),
285+
_ => {}
286+
}
287+
}
288+
289+
destinations.push(dest);
290+
}
291+
292+
Ok(destinations)
293+
}

src/apple/target.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::{
66
AuthCredentials,
77
};
88
use crate::{
9+
apple::project::list_destinations,
910
env::{Env, ExplicitEnv as _},
1011
opts::{self, NoiseLevel, Profile},
1112
target::TargetTrait,
@@ -543,10 +544,19 @@ impl<'a> Target<'a> {
543544
.map(|device| format!("id={}", device.id()))
544545
.or_else(|| {
545546
if cfg!(target_arch = "x86_64") && self.sdk == "iphonesimulator" {
546-
// on Intel we must force the destination when targeting the simulator
547+
let destinations = list_destinations(&workspace_path, &scheme).unwrap();
548+
let destination = destinations
549+
.iter()
550+
.filter(|d| d.platform == Some("iOS Simulator".to_string()))
551+
.max_by_key(|d| d.os.as_deref().unwrap_or(""));
552+
// on Intel we must force the ARCHS and destination when targeting the simulator
547553
// otherwise xcodebuild tries to build arm64
548-
// iPhone 13 seems like a good default target, old enough for every Xcode out there to have it?
549-
Some("platform=iOS Simulator,name=iPhone 13".to_string())
554+
Some(format!(
555+
"platform=iOS Simulator,name={}",
556+
destination
557+
.and_then(|d| d.name.as_deref())
558+
.unwrap_or("iPhone 13")
559+
))
550560
} else {
551561
None
552562
}
@@ -643,11 +653,23 @@ impl<'a> Target<'a> {
643653
}
644654

645655
if cfg!(target_arch = "x86_64") && sdk == "iphonesimulator" {
656+
let destinations = list_destinations(&workspace_path, &scheme).unwrap();
657+
let destination = destinations
658+
.iter()
659+
.filter(|d| d.platform == Some("iOS Simulator".to_string()))
660+
.max_by_key(|d| d.os.as_deref().unwrap_or(""));
646661
// on Intel we must force the ARCHS and destination when targeting the simulator
647662
// otherwise xcodebuild tries to build arm64
648-
// iPhone 13 seems like a good default target, old enough for every Xcode out there to have it?
649-
cmd.args(["-destination", "platform=iOS Simulator,name=iPhone 13"])
650-
.arg("ARCHS=x86_64");
663+
cmd.args([
664+
"-destination",
665+
&format!(
666+
"platform=iOS Simulator,name={}",
667+
destination
668+
.and_then(|d| d.name.as_deref())
669+
.unwrap_or("iPhone 13")
670+
),
671+
])
672+
.arg("ARCHS=x86_64");
651673
}
652674

653675
cmd.args(["-scheme", &scheme])

0 commit comments

Comments
 (0)