From eccbc7bd6a878b579d94915319d773abcfd2b89e Mon Sep 17 00:00:00 2001 From: dorianzheng Date: Tue, 13 Jan 2026 16:48:02 +0800 Subject: [PATCH] fix(cli): use ditto instead of fs::copy to preserve macOS code signing Replace Rust's fs::copy() with macOS ditto command in build.rs to preserve code signing metadata when copying runtime files. Problem: CLI and shim binaries were killed with SIGKILL (exit 137) on macOS because fs::copy() creates new files that lose code signing extended attributes, causing "Invalid Page" code signature validation failures at dyld load time. Solution: Use ditto on macOS which preserves extended attributes, resource forks, and code signing metadata. Use cp -R -T on Linux. --- boxlite-cli/build.rs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/boxlite-cli/build.rs b/boxlite-cli/build.rs index 6fc596ae..4c485f7a 100644 --- a/boxlite-cli/build.rs +++ b/boxlite-cli/build.rs @@ -76,15 +76,27 @@ fn set_rpath(dest: &Path) { } fn copy_dir_all(src: &Path, dst: &Path) -> std::io::Result<()> { + use std::process::Command; + fs::create_dir_all(dst)?; - for entry in fs::read_dir(src)? { - let entry = entry?; - let dst_path = dst.join(entry.file_name()); - if entry.file_type()?.is_dir() { - copy_dir_all(&entry.path(), &dst_path)?; - } else { - fs::copy(entry.path(), &dst_path)?; - } + + // Use ditto on macOS to preserve code signing metadata and extended attributes. + // Use cp -R on Linux. + #[cfg(target_os = "macos")] + let status = Command::new("ditto").arg(src).arg(dst).status()?; + + #[cfg(not(target_os = "macos"))] + let status = Command::new("cp") + .args(["-R", "-T"]) // -T treats dst as file, not directory (copies contents, not src into dst) + .arg(src) + .arg(dst) + .status()?; + + if !status.success() { + return Err(std::io::Error::other(format!( + "copy command failed with exit code: {:?}", + status.code() + ))); } Ok(()) }