From d3bfc13e6717bae133e3f567fe8038e58ac929ec Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 15 Aug 2026 03:42:22 +0000 Subject: [PATCH] Support Intel macOS with the last upstream runtime. --- .cargo/config.toml | 1 + .gitea/workflows/release.yml | 17 ++- Cargo.lock | 107 ++++++------- Cargo.toml | 4 +- README.md | 4 +- crates/bds-release/src/main.rs | 5 +- crates/bds-release/src/packaging.rs | 191 ++++++++++++++++++++++-- crates/bds-ui/tests/packaging_assets.rs | 5 + 8 files changed, 264 insertions(+), 70 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 375ed4f..515ecdf 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -7,6 +7,7 @@ bundle-linux = "packager --release --packages bds-ui --formats deb --formats app rustflags = [ "-C", "prefer-dynamic", "-C", "link-arg=-mmacosx-version-min=26.0", + "-C", "link-arg=-Wl,-rpath,@executable_path", "-C", "link-arg=-Wl,-rpath,@executable_path/../Resources", ] diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index ed3f9c5..524d3dc 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -47,8 +47,8 @@ jobs: runs-on: linux-arm64 container: ghcr.io/rust-cross/cargo-zigbuild@sha256:82af75c41958c2af2787e8bedd912da7678a9438937e223e9d83d006d747b38b env: - CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS: -Lnative=target/macos-linker -C link-arg=-mmacosx-version-min=26.0 -C link-arg=-Wl,-rpath,@executable_path/../Resources -C link-arg=-Wl,-headerpad,0x1000 -C link-arg=-Wl,-undefined,dynamic_lookup - CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS: -Lnative=target/macos-linker -C link-arg=-mmacosx-version-min=26.0 -C link-arg=-Wl,-rpath,@executable_path/../Resources -C link-arg=-Wl,-headerpad,0x1000 -C link-arg=-Wl,-undefined,dynamic_lookup + CARGO_TARGET_AARCH64_APPLE_DARWIN_RUSTFLAGS: -Lnative=target/macos-linker -C link-arg=-mmacosx-version-min=26.0 -C link-arg=-Wl,-rpath,@executable_path -C link-arg=-Wl,-rpath,@executable_path/../Resources -C link-arg=-Wl,-headerpad,0x1000 -C link-arg=-Wl,-undefined,dynamic_lookup + CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS: -Lnative=target/macos-linker -C link-arg=-mmacosx-version-min=26.0 -C link-arg=-Wl,-rpath,@executable_path -C link-arg=-Wl,-rpath,@executable_path/../Resources -C link-arg=-Wl,-headerpad,0x1000 -C link-arg=-Wl,-undefined,dynamic_lookup steps: - name: Check out the tag env: @@ -88,8 +88,17 @@ jobs: rest=${build#*|} build_target=${rest%%|*} platform=${rest#*|} - cargo +${RUST_TOOLCHAIN} zigbuild --release --locked --target "$build_target" \ - --package bds-ui --package bds-cli --package bds-mcp + if [ "$target" = x86_64-apple-darwin ]; then + cargo +${RUST_TOOLCHAIN} run --locked --package bds-release -- \ + macos-x64-runtime "target/$target/release" + ORT_LIB_PATH="$PWD/target/$target/release" \ + ORT_PREFER_DYNAMIC_LINK=1 \ + cargo +${RUST_TOOLCHAIN} zigbuild --release --locked --target "$build_target" \ + --package bds-ui --package bds-cli --package bds-mcp + else + cargo +${RUST_TOOLCHAIN} zigbuild --release --locked --target "$build_target" \ + --package bds-ui --package bds-cli --package bds-mcp + fi rust_lib_dir=$(rustc +${RUST_TOOLCHAIN} --target "$target" --print target-libdir) cargo +${RUST_TOOLCHAIN} run --locked --package bds-release -- package \ "$GITEA_REF_NAME" "target/$target/release" "$rust_lib_dir" "$platform" dist --upload diff --git a/Cargo.lock b/Cargo.lock index 5c5fe81..52e4049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1818,7 +1818,6 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ - "percent-encoding", "time", "version_check", ] @@ -1832,24 +1831,6 @@ dependencies = [ "futures", ] -[[package]] -name = "cookie_store" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b2c103cf610ec6cae3da84a766285b42fd16aad564758459e6ecf128c75206" -dependencies = [ - "cookie", - "document-features", - "idna", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -3265,9 +3246,9 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastembed" -version = "5.17.3" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c8600c9ec79b51d60c19911fe14eac04fe9c2895e87d2a3e80e2213d645a32" +checksum = "e7b01c79c5cb8ab3ce31c3d52916fda278e14cac027ff3a9cb66c419ed7288f8" dependencies = [ "anyhow", "hf-hub", @@ -4334,9 +4315,9 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hf-hub" -version = "0.5.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef3982638978efa195ff11b305f51f1f22f4f0a6cabee7af79b383ebee6a213" +checksum = "629d8f3bbeda9d148036d6b0de0a3ab947abd08ce90626327fc3547a49d59d97" dependencies = [ "dirs 6.0.0", "http", @@ -4348,8 +4329,8 @@ dependencies = [ "serde", "serde_json", "thiserror 2.0.19", - "ureq", - "windows-sys 0.61.2", + "ureq 2.12.1", + "windows-sys 0.60.2", ] [[package]] @@ -4530,7 +4511,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", - "webpki-roots", + "webpki-roots 1.0.9", ] [[package]] @@ -4990,14 +4971,14 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.18.6" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9433806cd6b4ec1aba79c021c7e4c58fb4c3b9977c085062e611ac929998fb0c" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ - "console 0.16.4", + "console 0.15.11", + "number_prefix", "portable-atomic", "unicode-width", - "unit-prefix", "web-time", ] @@ -6576,6 +6557,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "numkong" version = "7.7.0" @@ -7185,26 +7172,26 @@ dependencies = [ [[package]] name = "ort" -version = "2.0.0-rc.12" +version = "2.0.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7de3af33d24a745ffb8fab904b13478438d1cd52868e6f17735ef6e1f8bf133" +checksum = "4a5df903c0d2c07b56950f1058104ab0c8557159f2741782223704de9be73c3c" dependencies = [ "ndarray", "ort-sys", "smallvec", "tracing", - "ureq", + "ureq 3.3.0", ] [[package]] name = "ort-sys" -version = "2.0.0-rc.12" +version = "2.0.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7b497d21a8b6fbb4b5a544f8fadb77e801a09ae0add9e411d31c6f89e3c1e90" +checksum = "06503bb33f294c5f1ba484011e053bfa6ae227074bdb841e9863492dc5960d4b" dependencies = [ "hmac-sha256", "lzma-rust2", - "ureq", + "ureq 3.3.0", ] [[package]] @@ -8838,7 +8825,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", + "webpki-roots 1.0.9", ] [[package]] @@ -9312,15 +9299,13 @@ dependencies = [ [[package]] name = "safetensors" -version = "0.8.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b079b829cb27a1c3c374341345ed2e8b2c0c839034522cee576c140bd7f846" +checksum = "675656c1eabb620b921efea4f9199f97fc86e36dd6ffd1fbbe48d0f59a4987f5" dependencies = [ "hashbrown 0.16.1", - "libc", "serde", "serde_json", - "tempfile", ] [[package]] @@ -11343,12 +11328,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -[[package]] -name = "unit-prefix" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" - [[package]] name = "universal-hash" version = "0.6.1" @@ -11379,23 +11358,38 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.3.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", - "cookie_store", "flate2", "log", - "percent-encoding", + "once_cell", "rustls", "rustls-pki-types", "serde", "serde_json", "socks", + "url", + "webpki-roots 0.26.11", +] + +[[package]] +name = "ureq" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" +dependencies = [ + "base64 0.22.1", + "log", + "percent-encoding", + "rustls", + "rustls-pki-types", + "socks", "ureq-proto", "utf8-zero", - "webpki-roots", + "webpki-roots 1.0.9", ] [[package]] @@ -11899,6 +11893,15 @@ dependencies = [ "libwebp-sys", ] +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.9", +] + [[package]] name = "webpki-roots" version = "1.0.9" diff --git a/Cargo.toml b/Cargo.toml index 62e2918..707d3ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,9 +60,9 @@ diesel_migrations = "2.3.2" libsqlite3-sys = { version = "0.37.0", features = ["bundled"] } mlua = { version = "0.12", features = ["lua54", "vendored", "serialize"] } url = "2.5" -fastembed = { version = "5.17.3", default-features = false, features = ["hf-hub-rustls-tls", "ort-download-binaries-rustls-tls"] } +fastembed = { version = "5.12.0", default-features = false, features = ["hf-hub-rustls-tls", "ort-download-binaries-rustls-tls"] } usearch = { version = "2.26", default-features = false } -ort = { version = "=2.0.0-rc.12", default-features = false, features = ["std", "api-24", "copy-dylibs"] } +ort = { version = "=2.0.0-rc.11", default-features = false, features = ["std", "copy-dylibs"] } russh = "0.62.5" ratatui = "0.30.2" ratatui-image = { version = "11.0.6", default-features = false, features = ["crossterm", "image-defaults"] } diff --git a/README.md b/README.md index 0e1b311..372b64b 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,9 @@ The project is under active development. Core blogging workflows are broadly ava RuDS uses no JavaScript application runtime and loads no CSS or JavaScript from CDNs. The preview is served by the Rust application and displayed by the operating-system webview. -The packaged Apple Silicon application requires macOS 26 or newer. +The packaged macOS applications require macOS 26 or newer. -Packaged executables share native `bds-core` and `bds-server` dynamic libraries and link ONNX Runtime statically into `bds-core`. Windows archives additionally carry Microsoft's DirectML redistributable and license for GPU-accelerated local embeddings. The **Install CLI** action replaces `~/.local/bin/bds-cli` with a symbolic link to the packaged CLI, so the command executes beside the same runtime libraries and always follows the package selected by the latest installation. +Packaged executables share native `bds-core` and `bds-server` dynamic libraries. ONNX Runtime is linked statically where supported; Intel macOS carries Microsoft's final x64 runtime and license because current upstream releases no longer provide that architecture, while Windows carries Microsoft's DirectML redistributable and license for GPU-accelerated local embeddings. The **Install CLI** action replaces `~/.local/bin/bds-cli` with a symbolic link to the packaged CLI, so the command executes beside the same runtime libraries and always follows the package selected by the latest installation. Local macOS packages are ad-hoc signed without hardened runtime. A Developer ID and notarization remain optional release-channel steps for downloads that should pass Gatekeeper without a user override. diff --git a/crates/bds-release/src/main.rs b/crates/bds-release/src/main.rs index cfa4f40..5a0977e 100644 --- a/crates/bds-release/src/main.rs +++ b/crates/bds-release/src/main.rs @@ -11,6 +11,9 @@ fn main() -> Result<(), Box> { [command, directory] if command == "macos-linker-alias" => { packaging::prepare_macos_linker_alias(Path::new(directory)) } + [command, directory] if command == "macos-x64-runtime" => { + packaging::prepare_macos_x64_runtime(Path::new(directory)) + } [command, directory, sdk_libraries] if command == "windows-runtime" => { packaging::prepare_windows_runtime(Path::new(directory), Path::new(sdk_libraries)) } @@ -42,7 +45,7 @@ fn main() -> Result<(), Box> { gitea::upload(assets.iter().map(|path| path.as_path())) } _ => Err( - "usage: bds-release prepare|publish|macos-linker-alias |windows-runtime |upload ...|package [--upload]" + "usage: bds-release prepare|publish|macos-linker-alias |macos-x64-runtime |windows-runtime |upload ...|package [--upload]" .into(), ), } diff --git a/crates/bds-release/src/packaging.rs b/crates/bds-release/src/packaging.rs index 4caece7..d3097bc 100644 --- a/crates/bds-release/src/packaging.rs +++ b/crates/bds-release/src/packaging.rs @@ -26,6 +26,9 @@ const LC_LAZY_LOAD_DYLIB: u32 = 0x20; const LC_LOAD_UPWARD_DYLIB: u32 = 0x8000_0023; const DIRECTML_VERSION: &str = "1.15.4"; const DIRECTML_SHA256: &str = "4e7cb7ddce8cf837a7a75dc029209b520ca0101470fcdf275c1f49736a3615b9"; +const MACOS_X64_ORT_VERSION: &str = "1.23.2"; +const MACOS_X64_ORT_SHA256: &str = + "d10359e16347b57d9959f7e80a225a5b4a66ed7d7e007274a15cae86836485a6"; pub(crate) fn prepare_macos_linker_alias(directory: &Path) -> Result<(), Box> { fs::create_dir_all(directory)?; @@ -33,6 +36,72 @@ pub(crate) fn prepare_macos_linker_alias(directory: &Path) -> Result<(), Box Result<(), Box> { + fs::create_dir_all(directory)?; + let archive_path = directory.join(format!( + "onnxruntime-osx-x86_64-{MACOS_X64_ORT_VERSION}.tgz" + )); + let result = (|| { + let url = format!( + "https://github.com/microsoft/onnxruntime/releases/download/v{MACOS_X64_ORT_VERSION}/onnxruntime-osx-x86_64-{MACOS_X64_ORT_VERSION}.tgz" + ); + let mut response = reqwest::blocking::get(url)?.error_for_status()?; + let mut archive = File::create(&archive_path)?; + io::copy(&mut response, &mut archive)?; + drop(archive); + + let mut archive = BufReader::new(File::open(&archive_path)?); + let mut digest = Sha256::new(); + let mut buffer = [0_u8; 64 * 1024]; + loop { + let read = archive.read(&mut buffer)?; + if read == 0 { + break; + } + digest.update(&buffer[..read]); + } + if format!("{:x}", digest.finalize()) != MACOS_X64_ORT_SHA256 { + return Err("macOS x64 ONNX Runtime archive checksum mismatch".into()); + } + + prepare_macos_x64_runtime_from_archive(File::open(&archive_path)?, directory) + })(); + if archive_path.try_exists()? { + fs::remove_file(archive_path)?; + } + result +} + +fn prepare_macos_x64_runtime_from_archive( + archive: impl Read, + directory: &Path, +) -> Result<(), Box> { + fs::create_dir_all(directory)?; + let decoder = flate2::read::GzDecoder::new(archive); + let mut archive = tar::Archive::new(decoder); + for entry in archive.entries()? { + let mut entry = entry?; + let path = entry.path()?; + let destination = if path.ends_with(format!( + "lib/libonnxruntime.{MACOS_X64_ORT_VERSION}.dylib" + )) { + Some(format!("libonnxruntime.{MACOS_X64_ORT_VERSION}.dylib")) + } else if path.ends_with("LICENSE") { + Some("ONNXRuntime-LICENSE.txt".to_owned()) + } else { + None + }; + if let Some(destination) = destination { + io::copy(&mut entry, &mut File::create(directory.join(destination))?)?; + } + } + let versioned = directory.join(format!("libonnxruntime.{MACOS_X64_ORT_VERSION}.dylib")); + require_file(&versioned)?; + require_file(&directory.join("ONNXRuntime-LICENSE.txt"))?; + fs::copy(versioned, directory.join("libonnxruntime.dylib"))?; + Ok(()) +} + pub(crate) fn prepare_windows_runtime( directory: &Path, sdk_libraries: &Path, @@ -259,12 +328,24 @@ fn runtime_files( files.push((path, name)); } let mut external_names = match platform { - Platform::MacOs => fs::read_dir(release_dir)? - .filter_map(Result::ok) - .map(|entry| entry.file_name()) - .filter_map(|name| name.into_string().ok()) - .filter(|name| name.starts_with("libonnxruntime") && name.contains(".dylib")) - .collect::>(), + Platform::MacOs => { + let mut names = fs::read_dir(release_dir)? + .filter_map(Result::ok) + .map(|entry| entry.file_name()) + .filter_map(|name| name.into_string().ok()) + .filter(|name| name.starts_with("libonnxruntime") && name.contains(".dylib")) + .collect::>(); + let has_versioned = names + .iter() + .any(|name| name != "libonnxruntime.dylib"); + if has_versioned { + names.retain(|name| name != "libonnxruntime.dylib"); + } + if release_dir.join("ONNXRuntime-LICENSE.txt").is_file() { + names.push("ONNXRuntime-LICENSE.txt".to_owned()); + } + names + } Platform::Linux => fs::read_dir(release_dir)? .filter_map(Result::ok) .map(|entry| entry.file_name()) @@ -362,7 +443,7 @@ fn macos_dmg<'a>( for (source, name) in &files { let entry = FileEntry::new_from_path(source, true); - if name.ends_with(".dylib") { + if is_macos_bundle_resource(name) { bundle.add_file_resources(name, entry)?; } else { bundle.add_file_macos(name, entry)?; @@ -375,12 +456,14 @@ fn macos_dmg<'a>( .map(|(_, name)| name.clone()) .collect::>(); for (_, name) in &files { - let staged = if name.ends_with(".dylib") { + let staged = if is_macos_bundle_resource(name) { materialized.join("Contents/Resources").join(name) } else { materialized.join("Contents/MacOS").join(name) }; - rewrite_macho_rpaths(&staged, &runtime_names)?; + if is_macos_macho(name) { + rewrite_macho_rpaths(&staged, &runtime_names)?; + } } let signer = UnifiedSigner::new(SigningSettings::default()); signer.sign_path_in_place(&materialized)?; @@ -395,6 +478,14 @@ fn macos_dmg<'a>( Ok(()) } +fn is_macos_bundle_resource(name: &str) -> bool { + name.ends_with(".dylib") || name.ends_with(".txt") +} + +fn is_macos_macho(name: &str) -> bool { + !name.ends_with(".txt") +} + fn rewrite_macho_rpaths(path: &Path, runtime_names: &[String]) -> Result<(), Box> { let mut bytes = fs::read(path)?; if read_u32(&bytes, 0)? != 0xfeed_facf { @@ -582,6 +673,88 @@ mod tests { ); } + #[test] + fn macos_x64_runtime_extracts_the_versioned_library_and_license() { + let temp = tempdir().unwrap(); + let runtime = temp.path().join("runtime"); + let archive = Vec::new(); + let encoder = GzEncoder::new(archive, Compression::default()); + let mut archive = tar::Builder::new(encoder); + for (name, contents) in [ + ( + "onnxruntime-osx-x86_64-1.23.2/lib/libonnxruntime.1.23.2.dylib", + b"runtime".as_slice(), + ), + ( + "onnxruntime-osx-x86_64-1.23.2/LICENSE", + b"license".as_slice(), + ), + ( + "onnxruntime-osx-x86_64-1.23.2/include/onnxruntime.h", + b"header".as_slice(), + ), + ] { + let mut header = tar::Header::new_gnu(); + header.set_size(contents.len() as u64); + header.set_mode(0o644); + header.set_cksum(); + archive.append_data(&mut header, name, contents).unwrap(); + } + let encoder = archive.into_inner().unwrap(); + let archive = std::io::Cursor::new(encoder.finish().unwrap()); + + prepare_macos_x64_runtime_from_archive(archive, &runtime).unwrap(); + + assert_eq!( + fs::read(runtime.join("libonnxruntime.1.23.2.dylib")).unwrap(), + b"runtime" + ); + assert_eq!( + fs::read(runtime.join("libonnxruntime.dylib")).unwrap(), + b"runtime" + ); + assert_eq!( + fs::read(runtime.join("ONNXRuntime-LICENSE.txt")).unwrap(), + b"license" + ); + assert_eq!(fs::read_dir(runtime).unwrap().count(), 3); + } + + #[test] + fn macos_runtime_files_package_one_versioned_ort_library_and_its_license() { + let temp = tempdir().unwrap(); + let release = temp.path().join("release"); + let rust_libs = temp.path().join("rust-libs"); + fs::create_dir(&release).unwrap(); + fs::create_dir(&rust_libs).unwrap(); + for file in [ + "libbds_core.dylib", + "libbds_server.dylib", + "libonnxruntime.dylib", + "libonnxruntime.1.23.2.dylib", + "ONNXRuntime-LICENSE.txt", + ] { + fs::write(release.join(file), file).unwrap(); + } + + let files = runtime_files(Platform::MacOs, &release, &rust_libs).unwrap(); + let names = files.into_iter().map(|(_, name)| name).collect::>(); + + assert!(names.contains(&"libonnxruntime.1.23.2.dylib".to_owned())); + assert!(names.contains(&"ONNXRuntime-LICENSE.txt".to_owned())); + assert!(!names.contains(&"libonnxruntime.dylib".to_owned())); + } + + #[test] + fn macos_license_is_a_non_macho_bundle_resource() { + assert!(is_macos_bundle_resource("ONNXRuntime-LICENSE.txt")); + assert!(!is_macos_macho("ONNXRuntime-LICENSE.txt")); + assert!(is_macos_bundle_resource("libonnxruntime.1.23.2.dylib")); + assert!(is_macos_macho("libonnxruntime.1.23.2.dylib")); + assert!(!is_macos_bundle_resource("bds-ui")); + assert!(is_macos_macho("bds-ui")); + } + #[test] fn windows_runtime_extracts_only_redistributable_files() { let temp = tempdir().unwrap(); diff --git a/crates/bds-ui/tests/packaging_assets.rs b/crates/bds-ui/tests/packaging_assets.rs index 2ba7f3d..22f6934 100644 --- a/crates/bds-ui/tests/packaging_assets.rs +++ b/crates/bds-ui/tests/packaging_assets.rs @@ -46,6 +46,7 @@ fn desktop_packages_have_native_icons_and_cargo_commands() { } assert!(cargo_config.contains("prefer-dynamic")); assert!(cargo_config.contains("-mmacosx-version-min=26.0")); + assert!(cargo_config.contains("link-arg=-Wl,-rpath,@executable_path\",")); assert!(cargo_config.contains("@executable_path/../Resources")); assert!(cargo_config.contains("$ORIGIN:$ORIGIN/../lib/bds-ui")); @@ -129,7 +130,11 @@ fn tagged_releases_are_built_and_packaged_with_rust_tools() { "runs-on: linux-arm64", "cargo-zigbuild", "macos-linker-alias", + "macos-x64-runtime", + "ORT_LIB_PATH", + "ORT_PREFER_DYNAMIC_LINK", "-Lnative=target/macos-linker", + "-Wl,-rpath,@executable_path ", "-Wl,-undefined,dynamic_lookup", "aarch64-apple-darwin", "x86_64-apple-darwin",