From 9c9644d155818d9efcad65b60aa985a59e767922 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Mon, 2 Sep 2024 13:13:34 -0300 Subject: [PATCH] feat(cli): always validate iOS lib (#10845) --- .changes/enhance-ios-lib-validation.md | 6 +++ Cargo.lock | 2 + crates/tauri-cli/Cargo.toml | 6 +++ .../tauri-cli/src/mobile/ios/xcode_script.rs | 39 ++++++++++++------- 4 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 .changes/enhance-ios-lib-validation.md diff --git a/.changes/enhance-ios-lib-validation.md b/.changes/enhance-ios-lib-validation.md new file mode 100644 index 000000000..a088a1545 --- /dev/null +++ b/.changes/enhance-ios-lib-validation.md @@ -0,0 +1,6 @@ +--- +'tauri-cli': 'patch:enhance' +'@tauri-apps/cli': 'patch:enhance' +--- + +Enhance iOS library validation, checking libs built with link time optimization. diff --git a/Cargo.lock b/Cargo.lock index 873f2bec8..ef1c83e6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7145,6 +7145,7 @@ name = "tauri-cli" version = "2.0.0-rc.9" dependencies = [ "anyhow", + "ar", "axum", "base64 0.22.1", "cargo-mobile2", @@ -7183,6 +7184,7 @@ dependencies = [ "minisign", "notify", "notify-debouncer-mini", + "object", "os_info", "os_pipe", "oxc_allocator", diff --git a/crates/tauri-cli/Cargo.toml b/crates/tauri-cli/Cargo.toml index 9ff1d32a8..1d8dbd75e 100644 --- a/crates/tauri-cli/Cargo.toml +++ b/crates/tauri-cli/Cargo.toml @@ -130,6 +130,12 @@ libc = "0.2" [target."cfg(target_os = \"macos\")".dependencies] plist = "1" tauri-macos-sign = { version = "0.1.1-rc.0", path = "../tauri-macos-sign" } +object = { version = "0.36", default-features = false, features = [ + "macho", + "read_core", + "std", +] } +ar = "0.9" [features] default = ["rustls"] diff --git a/crates/tauri-cli/src/mobile/ios/xcode_script.rs b/crates/tauri-cli/src/mobile/ios/xcode_script.rs index 4bff5fa0d..fb566861e 100644 --- a/crates/tauri-cli/src/mobile/ios/xcode_script.rs +++ b/crates/tauri-cli/src/mobile/ios/xcode_script.rs @@ -13,14 +13,15 @@ use crate::{ use anyhow::Context; use cargo_mobile2::{apple::target::Target, opts::Profile}; use clap::Parser; +use object::{Object, ObjectSymbol}; use std::{ collections::HashMap, env::{current_dir, set_current_dir, var, var_os}, ffi::OsStr, fs::read_to_string, + io::Read, path::{Path, PathBuf}, - process::Command, }; #[derive(Debug, Parser)] @@ -228,10 +229,7 @@ pub fn command(options: Options) -> Result<()> { 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())); } - // for some reason the app works on release, but `nm ` does not print the start_app symbol - if profile == Profile::Debug { - validate_lib(&lib_path)?; - } + validate_lib(&lib_path)?; let project_dir = config.project_dir(); let externals_lib_dir = project_dir.join(format!("Externals/{arch}/{}", profile.as_str())); @@ -261,15 +259,28 @@ pub fn command(options: Options) -> Result<()> { } fn validate_lib(path: &Path) -> Result<()> { - // we ignore `nm` errors - if let Ok(output) = Command::new("nm").arg(path).output() { - let symbols = String::from_utf8_lossy(&output.stdout); - if !symbols.contains("start_app") { - anyhow::bail!( - "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", - path.display() - ); + let mut archive = ar::Archive::new(std::fs::File::open(path)?); + // Iterate over all entries in the archive: + while let Some(entry) = archive.next_entry() { + let Ok(mut entry) = entry else { + continue; + }; + let mut obj_bytes = Vec::new(); + entry.read_to_end(&mut obj_bytes)?; + + let file = object::File::parse(&*obj_bytes)?; + for symbol in file.symbols() { + let Ok(name) = symbol.name() else { + continue; + }; + if name.contains("start_app") { + return Ok(()); + } } } - Ok(()) + + anyhow::bail!( + "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", + path.display() + ) }