From 9823dfb680463d441b4516a8d9f78854d652523f Mon Sep 17 00:00:00 2001 From: Afonso Jorge Ramos Date: Tue, 31 Mar 2026 02:58:20 +0200 Subject: [PATCH 1/2] fix(macos): enable x86_64 cross-compilation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgrade rust_cast 0.18.1 → 0.21 (switches from openssl to rustls, removing the openssl-sys dependency that blocked x86_64 cross-compile) - Split mupdf sys-lib features to Linux-only (on macOS there are no GTK symbol conflicts, and system libs don't support x86_64 cross-compile from Apple Silicon) - Update release-macos workflow to build both aarch64 and x86_64 DMGs using a matrix strategy --- .github/workflows/release-macos.yml | 17 ++++++++---- crates/qbz-cast/Cargo.toml | 2 +- src-tauri/Cargo.lock | 40 +++++++++++++++++++---------- src-tauri/Cargo.toml | 18 ++++++------- 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index 104e0fdf8..ac62a9761 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -13,7 +13,13 @@ on: jobs: build-macos: - # Apple Silicon only — Intel Macs run via Rosetta 2 + strategy: + matrix: + include: + - target: aarch64-apple-darwin + artifact: qbz-macos-aarch64 + - target: x86_64-apple-darwin + artifact: qbz-macos-x86_64 runs-on: macos-latest permissions: contents: write @@ -78,29 +84,30 @@ jobs: - name: Setup Rust uses: dtolnay/rust-toolchain@stable with: - targets: aarch64-apple-darwin + targets: ${{ matrix.target }} - name: Rust cache uses: Swatinem/rust-cache@v2 with: workspaces: src-tauri -> target + shared-key: macos-${{ matrix.target }} - name: Install JS dependencies run: npm ci - name: Build DMG - run: npm run tauri build -- --target aarch64-apple-darwin --bundles dmg + run: npm run tauri build -- --target ${{ matrix.target }} --bundles dmg - name: Collect artifacts run: | mkdir -p dist - cp -v src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg dist/ || true + cp -v src-tauri/target/${{ matrix.target }}/release/bundle/dmg/*.dmg dist/ || true ls -la dist - name: Upload artifacts uses: actions/upload-artifact@v4 with: - name: qbz-macos-aarch64 + name: ${{ matrix.artifact }} path: dist/* - name: Publish GitHub Release Assets diff --git a/crates/qbz-cast/Cargo.toml b/crates/qbz-cast/Cargo.toml index d96203964..b8bbb31d2 100644 --- a/crates/qbz-cast/Cargo.toml +++ b/crates/qbz-cast/Cargo.toml @@ -6,7 +6,7 @@ description = "Casting support for QBZ - Chromecast, AirPlay, DLNA" [dependencies] # Chromecast -rust_cast = "0.18.1" +rust_cast = "0.21" # mDNS discovery mdns-sd = "0.11" diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8716b1717..f7e6c6b52 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -4417,9 +4417,9 @@ dependencies = [ [[package]] name = "protobuf" -version = "3.2.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55bad9126f378a853655831eb7363b7b01b81d19f8cb1218861086ca4a1a61e" +checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" dependencies = [ "once_cell", "protobuf-support", @@ -4428,9 +4428,9 @@ dependencies = [ [[package]] name = "protobuf-codegen" -version = "3.2.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd418ac3c91caa4032d37cb80ff0d44e2ebe637b2fb243b6234bf89cdac4901" +checksum = "5d3976825c0014bbd2f3b34f0001876604fe87e0c86cd8fa54251530f1544ace" dependencies = [ "anyhow", "once_cell", @@ -4443,12 +4443,12 @@ dependencies = [ [[package]] name = "protobuf-parse" -version = "3.2.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d39b14605eaa1f6a340aec7f320b34064feb26c93aec35d6a9a2272a8ddfa49" +checksum = "b4aeaa1f2460f1d348eeaeed86aea999ce98c1bded6f089ff8514c9d9dbdc973" dependencies = [ "anyhow", - "indexmap 1.9.3", + "indexmap 2.13.0", "log", "protobuf", "protobuf-support", @@ -4459,9 +4459,9 @@ dependencies = [ [[package]] name = "protobuf-support" -version = "3.2.0" +version = "3.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d4d7b8601c814cfb36bcebb79f0e61e45e1e93640cf778837833bbed05c372" +checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" dependencies = [ "thiserror 1.0.69", ] @@ -5306,18 +5306,19 @@ dependencies = [ [[package]] name = "rust_cast" -version = "0.18.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c9b210a559ed66ebb5096ebb754ad14e197bf8954c029bae6bfc82f0f51e460" +checksum = "235d09067a35143d271fdeaf28298b4f729b5da50abdbf3b9e6395262d8bc7a9" dependencies = [ "byteorder", "log", - "openssl", "protobuf", "protobuf-codegen", + "rustls", + "rustls-native-certs", "serde", - "serde_derive", "serde_json", + "thiserror 2.0.18", ] [[package]] @@ -5391,6 +5392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ "aws-lc-rs", + "log", "once_cell", "ring", "rustls-pki-types", @@ -5399,6 +5401,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pki-types" version = "1.14.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a38efd317..988710953 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -99,16 +99,13 @@ souvlaki = "0.8" image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp"] } # PDF rendering with MuPDF engine (high-quality rasterization for booklet viewer) -# NOTE: Use sys-lib-* for zlib/harfbuzz/freetype to avoid symbol conflicts with -# GTK/GdkPixbuf. But NOT libjpeg — Ubuntu ships libjpeg8 (libjpeg.so.8) while -# Debian/Fedora ship libjpeg62-turbo (libjpeg.so.62). Let mupdf vendor its own -# libjpeg to avoid cross-distro breakage (GitHub #161, #162). -mupdf = { version = "0.6", default-features = false, features = [ - "system-fonts", - "sys-lib-zlib", - "sys-lib-harfbuzz", - "sys-lib-freetype", -] } +# NOTE: On Linux, use sys-lib-* for zlib/harfbuzz/freetype to avoid symbol +# conflicts with GTK/GdkPixbuf. But NOT libjpeg — Ubuntu ships libjpeg8 while +# Debian/Fedora ship libjpeg62-turbo. Let mupdf vendor its own libjpeg to avoid +# cross-distro breakage (GitHub #161, #162). +# On macOS, let mupdf vendor everything (no GTK conflicts, and system libs +# don't support x86_64 cross-compilation from Apple Silicon). +mupdf = { version = "0.6", default-features = false, features = ["system-fonts"] } # URL opening open = "5" @@ -146,6 +143,7 @@ futures-util = "0.3" [target.'cfg(target_os = "linux")'.dependencies] tauri-plugin-dialog = { version = "2.6.0" } ashpd = { version = "0.13", default-features = false, features = ["tokio", "notification", "inhibit"] } +mupdf = { version = "0.6", features = ["sys-lib-zlib", "sys-lib-harfbuzz", "sys-lib-freetype"] } # Direct ALSA access for bit-perfect playback (bypasses CPAL limitations) alsa = "0.9" From 84b1f1a542ae4c021ce5a2c298817aae9716a143 Mon Sep 17 00:00:00 2001 From: Afonso Jorge Ramos Date: Wed, 1 Apr 2026 14:51:26 +0200 Subject: [PATCH 2/2] docs: remove Apple Silicon only note from macOS section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f851bfb2f..f2e1b8a24 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Download from [Releases](https://github.com/vicrodh/qbz/releases): `chmod +x QBZ > **QBZ is a Linux-first application.** macOS support is experimental and limited. Features like PipeWire, ALSA Direct, casting, and device control are unavailable. -Download the unsigned DMG from [Releases](https://github.com/vicrodh/qbz/releases) (Apple Silicon only). +Download the unsigned DMG from [Releases](https://github.com/vicrodh/qbz/releases). Since the DMG is unsigned, you may need to allow it in System Settings > Privacy & Security after first launch.