chore(packaging): point channel packagers at the Slint build

Flatpak manifest builds the crates/ workspace with rust-stable+llvm20
(node SDK and the intltool/libdbusmenu/ayatana chain removed). Root
snapcraft.yaml becomes a from-source Slint recipe (core24, rustup,
MIN memory tier) mirroring packaging/snap-slint runtime sections.
AUR/arch/gentoo swap webkit/gtk/appindicator runtime deps for the
measured Slint set and the source builders compile crates/ directly.
flake.nix: cargoRoot crates, no npm hooks, dlopen runtime libs wrapped.

cc
This commit is contained in:
vicrodh committed 2026-07-02 10:11:16 -06:00
1 parent 1b933299e1
commit 058d38c8d2
7 files changed
+222 -335

No files matched your search

+38 -43
View File
@@ -12,13 +12,23 @@
pkgs = import nixpkgs { inherit system; };
# ──────────────────────────────────────────────
# VERSION BUMP: update version, rev, and hashes
# when tagging a new release.
# VERSION BUMP: update version, rev, and srcHash
# when tagging a new release. (npmHash is gone —
# v2.0+ is the Slint crates/ workspace, no node.)
# ──────────────────────────────────────────────
qbzVersion = "1.2.15";
qbzRev = "v${qbzVersion}";
srcHash = "sha256-G7wR5HV0qwlrCPmKTv68+EeDTTyCAvvmPr7GDhrwTaA=";
npmHash = "sha256-RIR3erHN27fU9tTNQdUK0/5QDS9Dgd+O03PfqlYfRcM=";
# Runtime libraries winit/wgpu/glutin dlopen at runtime — a Nix
# binary cannot find system copies, so the installed program is
# wrapped with this library path.
runtimeLibs = with pkgs; [
wayland
libxkbcommon
libglvnd
vulkan-loader
];
in
{
packages.default = pkgs.rustPlatform.buildRustPackage rec {
@@ -32,53 +42,46 @@
hash = srcHash;
};
cargoRoot = "src-tauri";
cargoRoot = "crates";
buildAndTestSubdir = cargoRoot;
# Build only the app binary, not every workspace member's tests.
cargoBuildFlags = [ "-p" "qbz" ];
cargoLock = {
lockFile = "${src}/src-tauri/Cargo.lock";
};
npmDeps = pkgs.fetchNpmDeps {
name = "${pname}-${version}-npm-deps";
inherit src;
hash = npmHash;
lockFile = "${src}/crates/Cargo.lock";
};
env.LIBCLANG_PATH = "${pkgs.lib.getLib pkgs.llvmPackages.libclang}/lib";
nativeBuildInputs = with pkgs; [
clang
cargo-tauri.hook
nodejs
npmHooks.npmConfigHook
pkg-config
cmake
nasm
makeWrapper
];
buildInputs = with pkgs; [
alsa-lib
openssl
webkitgtk_4_1
libappindicator-gtk3
libayatana-appindicator
fontconfig
freetype
];
checkFlags = [
# These require a writable HOME and D-Bus keyring service
"--skip=credentials::tests::test_credentials_roundtrip"
"--skip=credentials::tests::test_encryption_roundtrip"
];
# The qbz_ui rustc alone peaks ~30 GB; running the test profile on
# top of the build doubles the wall time and memory exposure for
# no packaging value. Engine crates are tested in the repo's CI.
doCheck = false;
postInstall = ''
wrapProgram $out/bin/qbz \
--prefix LD_LIBRARY_PATH : ${
pkgs.lib.makeLibraryPath [
pkgs.libappindicator
pkgs.libappindicator-gtk3
pkgs.libayatana-appindicator
]
}
--prefix LD_LIBRARY_PATH : ${pkgs.lib.makeLibraryPath runtimeLibs}
install -Dm644 $src/packaging/linux/qbz.desktop \
$out/share/applications/qbz.desktop
for size in 32 48 64 128 256 512; do
install -Dm644 $src/packaging/icons/"$size"x"$size".png \
$out/share/icons/hicolor/"$size"x"$size"/apps/qbz.png
done
'';
meta = with pkgs.lib; {
@@ -96,9 +99,7 @@
# `inputsFrom` pulls in buildInputs/nativeBuildInputs from the
# package but does NOT propagate `env.*` attributes, so we must
# re-export LIBCLANG_PATH here — otherwise `mupdf-sys`'s bindgen
# fails with "Unable to find libclang" when running
# `npm run tauri dev` inside `nix develop` (issue #312).
# re-export LIBCLANG_PATH here for bindgen.
LIBCLANG_PATH = "${pkgs.lib.getLib pkgs.llvmPackages.libclang}/lib";
packages = with pkgs; [
@@ -108,17 +109,11 @@
];
# The package's `postInstall` wraps the installed binary with
# LD_LIBRARY_PATH so libappindicator is dlopen-able at runtime.
# Inside `nix develop` we run `target/debug/qbz` directly, with
# no wrapper, so we replicate that here — otherwise the tray
# init panics with "Failed to load ayatana-appindicator3 or
# appindicator3 dynamic library" (issue #312).
# LD_LIBRARY_PATH for the dlopen'd display/GPU stack. Inside
# `nix develop` we run `crates/target/debug/qbz` directly, with
# no wrapper, so replicate it here.
shellHook = ''
export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath [
pkgs.libappindicator
pkgs.libappindicator-gtk3
pkgs.libayatana-appindicator
]}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH="${pkgs.lib.makeLibraryPath runtimeLibs}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
'';
};
});
+17 -11
View File
@@ -7,43 +7,49 @@ pkgdesc="Native Qobuz client for Linux with bit-perfect playback"
arch=(x86_64)
url="https://github.com/vicrodh/qbz"
license=(MIT)
# v2.0+ (Slint/winit binary): no webkit/gtk/appindicator/node.
depends=(
alsa-lib
gtk3
libappindicator-gtk3
fontconfig
freetype2
libpng
bzip2
expat
zlib
libxkbcommon
openssl
webkit2gtk
wayland
libglvnd
dbus
)
makedepends=(
nodejs
npm
rust
cargo
pkgconf
clang
nasm
)
optdepends=(
'alsa-utils: Required for bit-perfect device detection and better ALSA device names'
'pipewire-alsa: PipeWire audio support'
'pipewire-pulse: PulseAudio compatibility'
'vulkan-driver: GPU-accelerated rendering (wgpu)'
)
source=("https://github.com/vicrodh/qbz/archive/refs/tags/v${pkgver}.tar.gz")
sha256sums=('SKIP')
build() {
cd "${srcdir}/qbz-${pkgver}"
npm ci
npm run build
npx tauri build --no-bundle
# Symbols stripped by the workspace [profile.release]. The qbz_ui rustc
# peaks ~30 GB RAM — single job keeps the footprint at its measured MIN.
CARGO_BUILD_JOBS=1 cargo build --release --manifest-path crates/Cargo.toml -p qbz
}
package() {
cd "${srcdir}/qbz-${pkgver}"
install -Dm755 src-tauri/target/release/qbz "${pkgdir}/usr/bin/qbz"
install -Dm755 crates/target/release/qbz "${pkgdir}/usr/bin/qbz"
# .desktop basename and Icon MUST be the app-id so GNOME resolves the MPRIS
# app icon (MPRIS DesktopEntry = com.blitzfc.qbz → <id>.desktop → Icon=).
install -Dm644 packaging/arch/com.blitzfc.qbz.desktop "${pkgdir}/usr/share/applications/com.blitzfc.qbz.desktop"
install -Dm644 src-tauri/icons/128x128.png "${pkgdir}/usr/share/icons/hicolor/128x128/apps/com.blitzfc.qbz.png"
install -Dm644 packaging/icons/128x128.png "${pkgdir}/usr/share/icons/hicolor/128x128/apps/com.blitzfc.qbz.png"
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
}
+6 -1
View File
@@ -6,11 +6,16 @@ pkgdesc="Native Qobuz client for Linux with bit-perfect hi-res audio, DAC passth
arch=('x86_64' 'aarch64')
url="https://github.com/vicrodh/qbz"
license=('MIT')
depends=('webkit2gtk-4.1' 'gtk3' 'alsa-lib' 'libappindicator-gtk3' 'libxkbcommon' 'openssl')
# v2.0+ (Slint/winit binary): no webkit/gtk/appindicator — the measured
# runtime link set is alsa/fontconfig/freetype/png/bz2/expat/zlib, plus the
# wayland/x11/GL/dbus/xkbcommon stack dlopen'd by winit/wgpu.
depends=('alsa-lib' 'fontconfig' 'freetype2' 'libpng' 'bzip2' 'expat' 'zlib'
'libxkbcommon' 'wayland' 'libglvnd' 'dbus')
optdepends=(
'alsa-utils: Required for bit-perfect device detection and better ALSA device names'
'pipewire-alsa: PipeWire audio support'
'pipewire-pulse: PulseAudio compatibility'
'vulkan-driver: GPU-accelerated rendering (wgpu)'
)
provides=('qbz')
conflicts=('qbz')
+30 -125
View File
@@ -1,10 +1,22 @@
# Flatpak manifest — GitHub Releases bundle (network build).
#
# Rewritten 2026-07-02 for the Tauri -> Slint migration (v2.0): builds the
# crates/ workspace with the rust-stable SDK extension. The node SDK, the
# whole intltool/libdbusmenu/libayatana-appindicator module chain and the
# lib64 workaround are gone — the Slint tray is ksni (pure Rust over D-Bus),
# no C appindicator involved.
#
# The FLATHUB manifest (flathub/com.blitzfc.qbz repo) is the OFFLINE twin of
# this file (cargo-sources.json, no network); keep the two in sync when
# changing modules or finish-args. scripts/update-flathub.sh regenerates it.
app-id: com.blitzfc.qbz
runtime: org.gnome.Platform
runtime-version: '49'
sdk: org.gnome.Sdk
sdk-extensions:
- org.freedesktop.Sdk.Extension.node24
- org.freedesktop.Sdk.Extension.rust-stable
# bindgen (aws-lc-sys et al.) needs libclang.
- org.freedesktop.Sdk.Extension.llvm20
command: qbz
finish-args:
@@ -29,22 +41,14 @@ finish-args:
# builds), which write the socket directly under $XDG_RUNTIME_DIR.
# - The :create permission on the Discord-Flatpak app dir lets us read
# the socket created by Discord-via-Flathub AND lay down our own
# $XDG_RUNTIME_DIR/discord-ipc-{0..9} symlinks pointing at it. The
# crate `discord-rich-presence` only knows the static path; the
# symlinks are what bridge the two sandboxes. See discord_rpc.rs:
# prepare_flatpak_discord_socket_links — called only after the user
# opts in via the settings toggle, so users who never enable Discord
# RPC never touch this dir.
# $XDG_RUNTIME_DIR/discord-ipc-{0..9} symlinks pointing at it.
- --filesystem=xdg-run/discord-ipc-0
- --filesystem=xdg-run/app/com.discordapp.Discord:create
# User music library
- --filesystem=xdg-music
# Required for tray icon visibility in Flatpak sandbox
- --filesystem=xdg-run/tray-icon:create
# Notifications and tray
# Notifications and tray (ksni StatusNotifierItem)
- --talk-name=org.freedesktop.Notifications
- --talk-name=org.kde.StatusNotifierWatcher
@@ -55,131 +59,31 @@ finish-args:
- --talk-name=org.mpris.MediaPlayer2.*
modules:
# intltool required for libdbusmenu
- name: intltool
buildsystem: autotools
cleanup:
- '*'
sources:
- type: archive
url: https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz
sha256: 67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd
# Dependency for libayatana-appindicator
- name: libdbusmenu
buildsystem: autotools
build-options:
cflags: -Wno-error
env:
HAVE_VALGRIND_FALSE: '#'
HAVE_VALGRIND_TRUE: ''
config-opts:
- --with-gtk=3
- --disable-dumper
- --disable-static
- --disable-gtk-doc
- --enable-introspection=no
- --disable-vala
cleanup:
- /include
- /lib/pkgconfig
- /lib/*.la
- /share/doc
- /share/libdbusmenu
sources:
- type: archive
url: https://launchpad.net/libdbusmenu/16.04/16.04.0/+download/libdbusmenu-16.04.0.tar.gz
sha256: b9cc4a2acd74509435892823607d966d424bd9ad5d0b00938f27240a1bfa878a
- name: ayatana-ido
buildsystem: cmake-ninja
config-opts:
- -DENABLE_TESTS=NO
- -DCMAKE_INSTALL_LIBDIR=lib
cleanup:
- /include
sources:
- type: archive
url: https://github.com/AyatanaIndicators/ayatana-ido/archive/refs/tags/0.10.4.tar.gz
sha256: bd59abd5f1314e411d0d55ce3643e91cef633271f58126be529de5fb71c5ab38
- name: libayatana-indicator
buildsystem: cmake-ninja
config-opts:
- -DENABLE_TESTS=NO
- -DENABLE_IDO=YES
- -DENABLE_LOADER=NO
- -DCMAKE_INSTALL_LIBDIR=lib
cleanup:
- /include
- /lib/pkgconfig
- /share
sources:
- type: archive
url: https://github.com/AyatanaIndicators/libayatana-indicator/archive/refs/tags/0.9.4.tar.gz
sha256: a18d3c682e29afd77db24366f8475b26bda22b0e16ff569a2ec71cd6eb4eac95
- name: libayatana-appindicator
buildsystem: cmake-ninja
config-opts:
- -DENABLE_BINDINGS_MONO=NO
- -DENABLE_BINDINGS_VALA=NO
- -DENABLE_GTKDOC=NO
- -DCMAKE_INSTALL_LIBDIR=lib
cleanup:
- /include
- /lib/pkgconfig
sources:
- type: archive
url: https://github.com/AyatanaIndicators/libayatana-appindicator/archive/refs/tags/0.5.93.tar.gz
sha256: cbefed7a918a227bf71286246e237fcd3a9c8499b3eaac4897811a869409edf0
# Workaround: Freedesktop 25.08 cmake may install to lib64 despite CMAKE_INSTALL_LIBDIR
# Copy any libraries from lib64 to lib so they can be found at runtime
- name: fix-lib64
buildsystem: simple
build-commands:
- |
if [ -d /app/lib64 ]; then
mkdir -p /app/lib
cp -a /app/lib64/* /app/lib/ 2>/dev/null || true
# Also copy pkgconfig if it exists
if [ -d /app/lib64/pkgconfig ]; then
mkdir -p /app/lib/pkgconfig
cp -a /app/lib64/pkgconfig/* /app/lib/pkgconfig/ 2>/dev/null || true
fi
fi
# List what we have for debugging
echo "=== Contents of /app/lib ==="
ls -la /app/lib/ || echo "lib is empty"
echo "=== Contents of /app/lib64 ==="
ls -la /app/lib64/ 2>/dev/null || echo "lib64 does not exist or is empty"
- name: qbz
buildsystem: simple
build-options:
append-path: /usr/lib/sdk/node24/bin:/usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm20/bin
append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm20/bin
build-args:
- --share=network
env:
npm_config_nodedir: /usr/lib/sdk/node24
LIBCLANG_PATH: /usr/lib/sdk/llvm20/lib
# Memory tier for 16 GB builders: the qbz_ui rustc is the ~30 GB
# peak; single job + high codegen-units + opt 2 is the measured
# MIN-footprint combination. Binary symbols are stripped by the
# workspace [profile.release].
CARGO_INCREMENTAL: '0'
CARGO_BUILD_JOBS: '1'
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: '256'
CARGO_PROFILE_RELEASE_OPT_LEVEL: '2'
build-commands:
- npm ci
- export PATH="$PWD/node_modules/.bin:$PATH" && npm run build
# Flathub policy: no competing auto-updaters. Disable the `updater`
# Cargo feature so tauri-plugin-updater / tauri-plugin-process are
# not linked into the Flatpak binary.
- export PATH="$PWD/node_modules/.bin:$PATH" && npm run tauri build -- --no-bundle -- --no-default-features
- install -Dm755 src-tauri/target/release/qbz /app/bin/qbz
- cargo build --release --manifest-path crates/Cargo.toml -p qbz
- install -Dm755 crates/target/release/qbz /app/bin/qbz
- install -Dm644 packaging/flatpak/com.blitzfc.qbz.desktop /app/share/applications/com.blitzfc.qbz.desktop
- install -Dm644 packaging/flatpak/com.blitzfc.qbz.metainfo.xml /app/share/metainfo/com.blitzfc.qbz.metainfo.xml
- install -Dm644 LICENSE /app/share/licenses/com.blitzfc.qbz/LICENSE
- install -Dm644 src-tauri/icons/128x128.png /app/share/icons/hicolor/128x128/apps/com.blitzfc.qbz.png
- install -Dm644 src-tauri/icons/256x256.png /app/share/icons/hicolor/256x256/apps/com.blitzfc.qbz.png
# Install tray icon for StatusNotifierItem (symbolic icon for panel)
- install -Dm644 src-tauri/icons/tray.png /app/share/icons/hicolor/symbolic/apps/com.blitzfc.qbz-symbolic.png
- install -Dm644 src-tauri/icons/32x32.png /app/share/icons/hicolor/32x32/apps/com.blitzfc.qbz.png
- install -Dm644 packaging/icons/32x32.png /app/share/icons/hicolor/32x32/apps/com.blitzfc.qbz.png
- install -Dm644 packaging/icons/128x128.png /app/share/icons/hicolor/128x128/apps/com.blitzfc.qbz.png
- install -Dm644 packaging/icons/256x256.png /app/share/icons/hicolor/256x256/apps/com.blitzfc.qbz.png
sources:
- type: dir
path: ../..
@@ -187,4 +91,5 @@ modules:
- .git
- node_modules
- src-tauri/target
- crates/target
- .svelte-kit
+11 -4
View File
@@ -18,13 +18,20 @@ LICENSE="MIT"
SLOT="0"
KEYWORDS="~amd64 ~arm64"
# v2.0+ (Slint/winit binary): no webkit/gtk/appindicator — the measured
# runtime link set plus the wayland/x11/GL/dbus stack dlopen'd by winit/wgpu.
RDEPEND="
net-libs/webkit-gtk:4.1
x11-libs/gtk+:3
media-libs/alsa-lib
dev-libs/openssl
dev-libs/libayatana-appindicator
media-libs/fontconfig
media-libs/freetype
media-libs/libpng
app-arch/bzip2
dev-libs/expat
sys-libs/zlib
x11-libs/libxkbcommon
dev-libs/wayland
media-libs/libglvnd
sys-apps/dbus
"
BDEPEND=""
+18 -19
View File
@@ -17,14 +17,19 @@ KEYWORDS="~amd64 ~arm64"
IUSE="pipewire pulseaudio"
RESTRICT="mirror network-sandbox"
# v2.0+ (Slint/winit binary): no webkit/gtk/appindicator/node.
RDEPEND="
net-libs/webkit-gtk:4.1
x11-libs/gtk+:3
media-libs/alsa-lib
dev-libs/openssl
dev-libs/libayatana-appindicator
media-libs/fontconfig
media-libs/freetype
media-libs/libpng
app-arch/bzip2
dev-libs/expat
sys-libs/zlib
x11-libs/libxkbcommon
gnome-base/librsvg:2
dev-libs/wayland
media-libs/libglvnd
sys-apps/dbus
pipewire? (
media-video/pipewire[pipewire-alsa]
)
@@ -35,8 +40,8 @@ RDEPEND="
BDEPEND="
dev-lang/rust
net-libs/nodejs[npm]
llvm-core/clang
dev-lang/nasm
virtual/pkgconfig
"
@@ -47,32 +52,26 @@ PDEPEND="
S="${WORKDIR}/qbz-${MY_PV}"
src_compile() {
npm ci || die "npm ci failed"
npx tauri build --no-bundle || die "tauri build failed"
# Symbols stripped by the workspace [profile.release]. The qbz_ui rustc
# peaks ~30 GB RAM — single job keeps the footprint at its measured MIN.
CARGO_BUILD_JOBS=1 cargo build --release \
--manifest-path crates/Cargo.toml -p qbz || die "cargo build failed"
}
src_install() {
dobin "src-tauri/target/release/qbz"
dobin "crates/target/release/qbz"
insinto /usr/share/applications
newins packaging/arch/qbz.desktop qbz.desktop
newins packaging/linux/qbz.desktop qbz.desktop
local size
for size in 32 48 64 128 256; do
local src_icon="src-tauri/icons/${size}x${size}.png"
local src_icon="packaging/icons/${size}x${size}.png"
if [[ -f "${src_icon}" ]]; then
insinto "/usr/share/icons/hicolor/${size}x${size}/apps"
newins "${src_icon}" qbz.png
fi
done
local fallback="src-tauri/icons/128x128.png"
for size in 48 64; do
if [[ ! -f "src-tauri/icons/${size}x${size}.png" ]]; then
insinto "/usr/share/icons/hicolor/${size}x${size}/apps"
newins "${fallback}" qbz.png
fi
done
}
pkg_postinst() {
+102 -132
View File
@@ -1,36 +1,34 @@
# QBZ Snap package configuration
# NOTE: Keep this file in sync with packaging/snap/snapcraft.yaml.
# QBZ Snap recipe — SOURCE build of the Slint app (crates/ workspace).
#
# Rewritten 2026-07-02 for the Tauri -> Slint migration (v2.0). This root
# file is what `snapcraft` picks up when building from the repo (local
# builds / any builder pointed at the repo root). packaging/snap/snapcraft.yaml
# is a symlink to THIS file — keep it that way.
#
# NOTE: the CI release path (release-snap.yml) does NOT use this file — it
# builds the binary on a swap-equipped 16 GB runner and wraps it with the
# dump-plugin recipe in packaging/snap-slint/snapcraft.yaml. Reason: the
# qbz_ui rustc peaks ~30 GB (RSS+swap); small remote builders (e.g.
# Launchpad) will OOM building this recipe from source. Keep the runtime
# sections (apps/plugs/stage-packages) in sync with packaging/snap-slint/.
name: qbz-player
name: qbz-player # keep the existing registered Snap Store name
title: "QBZ — Native Qobuz Client for Linux"
version: '1.2.15'
version: git
summary: Native Qobuz player for Linux with bit-perfect audio and DAC control
description: |
QBZ is a native Linux desktop client for Qobuz™, designed for high-fidelity playback.
QBZ is a native Linux desktop client for Qobuz(TM), built for high-fidelity
playback with a native audio pipeline (direct ALSA and PipeWire), bit-perfect
output, exclusive device access, and per-track sample-rate switching for
external DACs — up to 24-bit / 192 kHz.
Unlike browser-based players or web wrappers, QBZ uses a native audio pipeline with direct ALSA and PipeWire integration, allowing bit-perfect playback, exclusive device access, and proper per-track sample-rate switching for external DACs.
This is the native (Slint) build: a single self-contained binary, no web
runtime. Features: native Qobuz(TM) streaming, bit-perfect ALSA exclusive
mode, DAC passthrough, Hi-Res FLAC, queue/playlists/favorites/offline cache,
local library, Chromecast and DLNA, MPRIS media keys and desktop integration.
Browsers are limited by system mixers and WebAudio, often resampling audio to 48 kHz. QBZ bypasses these limitations to deliver true high-resolution audio up to 24-bit / 192 kHz on Linux.
Features:
- Native Qobuz™ streaming client (not a web wrapper)
- Bit-perfect playback with ALSA exclusive mode
- DAC passthrough and per-track sample-rate switching
- Hi-Res FLAC playback
- Queue, playlists, favorites, and offline cache
- Local library integration
- Chromecast and DLNA support
- MPRIS media keys and desktop integration
- Open source (MIT license)
QBZ is built for Linux users and audiophiles who care about how audio actually reaches their hardware.
Note: When using ALSA exclusive mode or DAC passthrough, QBZ may block other
applications from recording or playing sound while audio is active. This is
expected behavior for bit-perfect playback and can be disabled in settings.
Legal:
QBZ uses the Qobuz™ API but is not affiliated with, endorsed by, or certified by Qobuz.
QBZ uses the Qobuz(TM) API but is not affiliated with, endorsed by, or
certified by Qobuz.
license: MIT
contact: https://github.com/vicrodh/qbz/discussions
@@ -40,51 +38,31 @@ issues: https://github.com/vicrodh/qbz/issues
grade: stable
confinement: strict
base: core22
base: core24
icon: packaging/snap/snap/gui/qbz.png
passthrough:
layout:
/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1:
bind: $SNAP/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1
/usr/share/alsa:
bind: $SNAP/usr/share/alsa
/etc/alsa:
bind: $SNAP/etc/alsa
/usr/lib/x86_64-linux-gnu/alsa-lib:
bind: $SNAP/usr/lib/x86_64-linux-gnu/alsa-lib
architectures:
- build-on: [amd64]
build-for: [amd64]
- build-on: [arm64]
build-for: [arm64]
platforms:
amd64:
arm64:
apps:
qbz:
command: bin/qbz
desktop: packaging/snap/snap/gui/qbz.desktop
desktop: usr/share/applications/qbz.desktop
# The gnome extension provides the graphics/font platform (Mesa GL, EGL,
# fontconfig, wayland) that a femtovg-wgpu + winit app needs — it is NOT
# about GTK here, just the runtime platform. It wires desktop/wayland/x11/
# gsettings plugs automatically.
extensions: [gnome]
environment:
# Prefer GNOME platform GL libs to avoid Mesa/driver mismatches on NVIDIA.
LD_LIBRARY_PATH: $SNAP/gnome-platform/usr/lib/x86_64-linux-gnu:$SNAP/gnome-platform/lib/x86_64-linux-gnu:$SNAP/gnome-platform/usr/lib/aarch64-linux-gnu:$SNAP/gnome-platform/lib/aarch64-linux-gnu:$SNAP/gnome-platform/usr/lib:$SNAP/gnome-platform/lib:$LD_LIBRARY_PATH
WEBKIT_EXEC_PATH: $SNAP/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1
GTK_USE_PORTAL: "0"
GIO_USE_PORTAL: "0"
PIPEWIRE_RUNTIME_DIR: $XDG_RUNTIME_DIR/..
plugs:
- network
- network-status
- audio-playback
- home
- removable-media
- desktop
- desktop-legacy
- wayland
- x11
- unity7
- gsettings
- alsa
- pipewire
- opengl
slots:
- mpris
@@ -95,84 +73,76 @@ slots:
parts:
qbz:
plugin: rust
source: https://github.com/vicrodh/qbz.git
source-tag: v1.2.15
plugin: nil
source: .
build-packages:
- libwebkit2gtk-4.1-dev
- libgtk-3-dev
- libayatana-appindicator3-dev
- librsvg2-dev
- patchelf
- libssl-dev
- libasound2-dev
- pkg-config
- curl
# alsa-utils for aplay command (device enumeration)
- alsa-utils
# unzip needed by mupdf-sys build (ODT template extraction)
- unzip
# libclang needed by bindgen (mupdf-sys 0.6 generates bindings at build time)
- libclang-dev
stage-packages:
- libwebkit2gtk-4.1-0
- libgtk-3-0
- libayatana-appindicator3-1
- libasound2
- libasound2-data
- libasound2-plugins
- libssl3
- pipewire-bin
- pulseaudio-utils
# Include alsa-utils in the snap for aplay -L command
- alsa-utils
- pkg-config
- clang
- nasm
- mold
- libasound2-dev
- libjack-jackd2-dev
- libfontconfig1-dev
- libfreetype-dev
- libxkbcommon-dev
- libwayland-dev
- libxcb1-dev
- libgl1-mesa-dev
- libegl1-mesa-dev
- libdbus-1-dev
- libssl-dev
- libharfbuzz-dev
- libjbig2dec0-dev
- libopenjp2-7-dev
- libjpeg-dev
- zlib1g-dev
- libgumbo-dev
override-build: |
export CARGO_HOME="$SNAPCRAFT_PART_BUILD/.cargo"
# Rust via rustup (the archive's rustc is too old for Slint).
export RUSTUP_HOME="$SNAPCRAFT_PART_BUILD/.rustup"
export PATH="$CARGO_HOME/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export PKG_CONFIG_PATH="/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pkgconfig:/usr/share/pkgconfig:/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pkgconfig:/snap/gnome-42-2204-sdk/current/usr/share/pkgconfig"
export LIBRARY_PATH="/usr/lib/$SNAPCRAFT_ARCH_TRIPLET:/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET"
export LD_LIBRARY_PATH="/usr/lib/$SNAPCRAFT_ARCH_TRIPLET:/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET"
# Core22 ships SQLite 3.37 which lacks sqlite3_error_offset (added 3.38).
# libsqlite3-dev is pulled in transitively by webkit2gtk-dev, and the
# RUSTFLAGS -L puts /usr/lib before the bundled sqlite output dir,
# so the linker finds the old system libsqlite3.a first.
# Fix: replace system sqlite with a version >= 3.38.
SQLITE_VER=3460100
curl -sSf "https://www.sqlite.org/2024/sqlite-autoconf-${SQLITE_VER}.tar.gz" | tar xz
pushd "sqlite-autoconf-${SQLITE_VER}"
./configure --quiet --prefix=/usr --libdir="/usr/lib/$SNAPCRAFT_ARCH_TRIPLET"
make -j"$(nproc)" && make install
popd
export CARGO_HOME="$SNAPCRAFT_PART_BUILD/.cargo"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
sh -s -- -y --profile minimal --default-toolchain stable
export PATH="$CARGO_HOME/bin:$PATH"
export RUSTFLAGS="-L native=/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -L native=/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -L native=/snap/gnome-42-2204-sdk/current/usr/lib -C link-arg=-Wl,-rpath-link,/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -C link-arg=-Wl,-rpath-link,/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -C link-arg=-Wl,-rpath-link,/snap/gnome-42-2204-sdk/current/usr/lib"
export LDFLAGS="-L/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -L/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -L/snap/gnome-42-2204-sdk/current/usr/lib -Wl,-rpath-link,/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -Wl,-rpath-link,/snap/gnome-42-2204-sdk/current/usr/lib/$SNAPCRAFT_ARCH_TRIPLET -Wl,-rpath-link,/snap/gnome-42-2204-sdk/current/usr/lib"
# MIN memory tier: the qbz_ui rustc peaks ~30 GB. Symbols are stripped
# by the workspace [profile.release].
export CARGO_INCREMENTAL=0
export CARGO_BUILD_JOBS=1
export CARGO_PROFILE_RELEASE_CODEGEN_UNITS=256
export CARGO_PROFILE_RELEASE_OPT_LEVEL=2
export RUSTFLAGS="-C link-arg=-fuse-ld=mold"
cargo build --release --manifest-path crates/Cargo.toml -p qbz
if ! command -v cargo >/dev/null 2>&1; then
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain stable
fi
# Allow sandboxed builds to override GTK_USE_PORTAL.
perl -0pi -e 'if ($_ !~ /var_os\\(\"GTK_USE_PORTAL\"\\)/) { s/std::env::set_var\\(\"GTK_USE_PORTAL\", \"1\"\\);/if std::env::var_os\\(\"GTK_USE_PORTAL\"\\).is_none() {\\n std::env::set_var(\"GTK_USE_PORTAL\", \"1\");\\n }/ }' src-tauri/src/main.rs
# Install Node.js for frontend build
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
# Build frontend
npm ci
# Snap Store policy prohibits competing auto-updaters; disable
# the `updater` Cargo feature so tauri-plugin-updater is not linked.
npm run tauri build -- --no-bundle -- --no-default-features
# Install binary, desktop file, and icon
mkdir -p $SNAPCRAFT_PART_INSTALL/bin
cp src-tauri/target/release/qbz $SNAPCRAFT_PART_INSTALL/bin/qbz
mkdir -p $SNAPCRAFT_PART_INSTALL/packaging/snap/snap/gui
cp packaging/snap/snap/gui/qbz.desktop $SNAPCRAFT_PART_INSTALL/packaging/snap/snap/gui/
cp packaging/snap/snap/gui/qbz.png $SNAPCRAFT_PART_INSTALL/packaging/snap/snap/gui/
override-prime: |
snapcraftctl prime
if [ -d "$SNAPCRAFT_PRIME/usr/lib/aarch64-linux-gnu" ] && [ ! -e "$SNAPCRAFT_PRIME/usr/lib/x86_64-linux-gnu" ]; then
ln -s aarch64-linux-gnu "$SNAPCRAFT_PRIME/usr/lib/x86_64-linux-gnu"
fi
install -Dm755 crates/target/release/qbz "$SNAPCRAFT_PART_INSTALL/bin/qbz"
install -Dm644 packaging/linux/qbz.desktop \
"$SNAPCRAFT_PART_INSTALL/usr/share/applications/qbz.desktop"
install -Dm644 packaging/icons/256x256.png \
"$SNAPCRAFT_PART_INSTALL/usr/share/icons/hicolor/256x256/apps/qbz.png"
stage-packages:
# Audio (the bit-perfect path)
- libasound2t64
- libasound2-plugins
- libpipewire-0.3-0
- libjack-jackd2-0
# GPU stack for femtovg-wgpu (Vulkan first, GL fallback)
- libvulkan1
- mesa-vulkan-drivers
- libegl1
- libgl1
# winit windowing (Wayland + X11)
- libwayland-client0
- libwayland-cursor0
- libwayland-egl1
- libxkbcommon0
- libxcb1
- libx11-6
- libxcursor1
- libxi6
- libxrandr2
# Fonts / text shaping (femtovg)
- libfontconfig1
- libfreetype6
# Tray (ksni) + portals + media controls over D-Bus
- libdbus-1-3