瀏覽代碼

feat(cli): always validate iOS lib (#10845)

Lucas Fernandes Nogueira 11 月之前
父節點
當前提交
9c9644d155
共有 4 個文件被更改,包括 39 次插入14 次删除
  1. 6 0
      .changes/enhance-ios-lib-validation.md
  2. 2 0
      Cargo.lock
  3. 6 0
      crates/tauri-cli/Cargo.toml
  4. 25 14
      crates/tauri-cli/src/mobile/ios/xcode_script.rs

+ 6 - 0
.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.

+ 2 - 0
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",

+ 6 - 0
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"]

+ 25 - 14
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 <path>` 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()
+  )
 }