Skip to content

Commit 9c9644d

Browse files
authored
feat(cli): always validate iOS lib (#10845)
1 parent b426835 commit 9c9644d

File tree

4 files changed

+39
-14
lines changed

4 files changed

+39
-14
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'tauri-cli': 'patch:enhance'
3+
'@tauri-apps/cli': 'patch:enhance'
4+
---
5+
6+
Enhance iOS library validation, checking libs built with link time optimization.

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri-cli/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ libc = "0.2"
130130
[target."cfg(target_os = \"macos\")".dependencies]
131131
plist = "1"
132132
tauri-macos-sign = { version = "0.1.1-rc.0", path = "../tauri-macos-sign" }
133+
object = { version = "0.36", default-features = false, features = [
134+
"macho",
135+
"read_core",
136+
"std",
137+
] }
138+
ar = "0.9"
133139

134140
[features]
135141
default = ["rustls"]

crates/tauri-cli/src/mobile/ios/xcode_script.rs

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@ use crate::{
1313
use anyhow::Context;
1414
use cargo_mobile2::{apple::target::Target, opts::Profile};
1515
use clap::Parser;
16+
use object::{Object, ObjectSymbol};
1617

1718
use std::{
1819
collections::HashMap,
1920
env::{current_dir, set_current_dir, var, var_os},
2021
ffi::OsStr,
2122
fs::read_to_string,
23+
io::Read,
2224
path::{Path, PathBuf},
23-
process::Command,
2425
};
2526

2627
#[derive(Debug, Parser)]
@@ -228,10 +229,7 @@ pub fn command(options: Options) -> Result<()> {
228229
return Err(anyhow::anyhow!("Library not found at {}. Make sure your Cargo.toml file has a [lib] block with `crate-type = [\"staticlib\", \"cdylib\", \"lib\"]`", lib_path.display()));
229230
}
230231

231-
// for some reason the app works on release, but `nm <path>` does not print the start_app symbol
232-
if profile == Profile::Debug {
233-
validate_lib(&lib_path)?;
234-
}
232+
validate_lib(&lib_path)?;
235233

236234
let project_dir = config.project_dir();
237235
let externals_lib_dir = project_dir.join(format!("Externals/{arch}/{}", profile.as_str()));
@@ -261,15 +259,28 @@ pub fn command(options: Options) -> Result<()> {
261259
}
262260

263261
fn validate_lib(path: &Path) -> Result<()> {
264-
// we ignore `nm` errors
265-
if let Ok(output) = Command::new("nm").arg(path).output() {
266-
let symbols = String::from_utf8_lossy(&output.stdout);
267-
if !symbols.contains("start_app") {
268-
anyhow::bail!(
269-
"Library from {} does not include required runtime symbols. This means you are likely missing the tauri::mobile_entry_point macro usage, see the documentation for more information: https://v2.tauri.app/start/migrate/from-tauri-1",
270-
path.display()
271-
);
262+
let mut archive = ar::Archive::new(std::fs::File::open(path)?);
263+
// Iterate over all entries in the archive:
264+
while let Some(entry) = archive.next_entry() {
265+
let Ok(mut entry) = entry else {
266+
continue;
267+
};
268+
let mut obj_bytes = Vec::new();
269+
entry.read_to_end(&mut obj_bytes)?;
270+
271+
let file = object::File::parse(&*obj_bytes)?;
272+
for symbol in file.symbols() {
273+
let Ok(name) = symbol.name() else {
274+
continue;
275+
};
276+
if name.contains("start_app") {
277+
return Ok(());
278+
}
272279
}
273280
}
274-
Ok(())
281+
282+
anyhow::bail!(
283+
"Library from {} does not include required runtime symbols. This means you are likely missing the tauri::mobile_entry_point macro usage, see the documentation for more information: https://v2.tauri.app/start/migrate/from-tauri-1",
284+
path.display()
285+
)
275286
}

0 commit comments

Comments
 (0)