diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d6bf507..1726227 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -23,9 +23,6 @@ jobs: - platform: 'macos-latest' # Apple Silicon (arm64) args: '--target aarch64-apple-darwin' rust_targets: 'aarch64-apple-darwin' - - platform: 'macos-13' # Intel (x86_64) — last Intel GitHub runner - args: '--target x86_64-apple-darwin' - rust_targets: 'x86_64-apple-darwin' - platform: 'ubuntu-24.04' # glibc 2.39 — required by ORT prebuilt binaries args: '' rust_targets: '' @@ -169,3 +166,5 @@ jobs: releaseDraft: true prerelease: false args: ${{ matrix.args }} + + diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 38d53ff..f14fe8a 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4339,6 +4339,7 @@ dependencies = [ "image", "log", "ort", + "pkg-config", "rexiv2", "rfd", "serde", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 001243b..3af91ae 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -16,6 +16,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] tauri-build = { version = "2", features = [] } +pkg-config = "0.3" [dependencies] tauri = { version = "2", features = ["protocol-asset"] } diff --git a/src-tauri/build.rs b/src-tauri/build.rs index d860e1e..65c34f9 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,25 @@ fn main() { + // The macOS `gexiv2_metadata_free` shim in lib.rs calls `g_object_unref`, + // which lives in libgobject-2.0. gexiv2 lists gobject only under + // Requires.private, so pkg-config omits it from the dynamic link line and + // the symbol goes unresolved. Link gobject-2.0 explicitly on macOS. + // + // Gate on the *target* OS (CARGO_CFG_TARGET_OS) rather than a cfg! attribute: + // a build script is compiled for the host, so #[cfg(target_os = ...)] here + // would reflect the host, not what we are building for. + if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("macos") { + match pkg_config::Config::new().probe("gobject-2.0") { + Ok(lib) => { + for path in lib.link_paths { + println!("cargo:rustc-link-search=native={}", path.display()); + } + } + Err(e) => { + println!("cargo:warning=pkg-config could not locate gobject-2.0: {e}"); + } + } + println!("cargo:rustc-link-lib=dylib=gobject-2.0"); + } + tauri_build::build() } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 534004a..47fc49e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1,5 +1,16 @@ mod tagger; +// gexiv2 0.16 (Homebrew) removed gexiv2_metadata_free; rexiv2 0.10 still calls it. +// This shim forwards to g_object_unref, which is the correct GObject cleanup path. +#[cfg(target_os = "macos")] +#[no_mangle] +pub unsafe extern "C" fn gexiv2_metadata_free(metadata: *mut std::ffi::c_void) { + extern "C" { + fn g_object_unref(object: *mut std::ffi::c_void); + } + g_object_unref(metadata); +} + use tagger::{ get_folder_depth_analysis, get_image_ai_tags, get_image_data, get_image_metadata, get_images_in_folder, get_initial_folder, get_recursive_images, get_subfolders, get_thumbnail,