feat(packaging): add a thin AppImage build
build-appimage.sh produces pixelpass-<version>-x86_64.AppImage via linuxdeploy. PixelPass links almost nothing (only libpipewire, which is excludelisted) and shells out to gst-launch-1.0/pactl/a player on the host PATH, while its GUI graphics libs are dlopen'd and also excludelisted — so the AppImage bundles just the binary, AppRun, desktop entry, and icon (~13 MB, zero bundled libs). The no-sandbox model lets the bundled binary spawn the host's tools, which is why AppImage fits this orchestrator better than Flatpak. AppRun opens --gui when launched with no args and no controlling terminal (file manager / .desktop), and passes through otherwise so the CLI, interactive menu, and viewer all work. README documents the host-deps contract + the glibc-baseline and VAAPI caveats. Verified: builds to 13 MB; --version/--help work; the GUI launches cleanly on a live Wayland session via both --gui and the no-tty AppRun path. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
.tools/
|
||||
AppDir/
|
||||
*.AppImage
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
# AppRun for the PixelPass AppImage.
|
||||
#
|
||||
# PixelPass is an orchestrator: it shells out to gst-launch-1.0, pactl, and a
|
||||
# player (mpv/vlc) found on the host PATH. We prepend our own usr/bin so any
|
||||
# bundled helpers win, but the host's tools remain reachable — that's why this
|
||||
# app suits AppImage (no sandbox) better than a Flatpak.
|
||||
HERE="$(dirname "$(readlink -f "$0")")"
|
||||
export PATH="$HERE/usr/bin:$PATH"
|
||||
|
||||
BIN="$HERE/usr/bin/pixelpass"
|
||||
|
||||
# With no arguments and no controlling terminal — i.e. launched from a file
|
||||
# manager or the .desktop entry — open the GUI. From a terminal, or with any
|
||||
# argument (a ticket, --host, --gui, --repair, …), pass through so the CLI and
|
||||
# the interactive menu both work.
|
||||
if [ "$#" -eq 0 ] && [ ! -t 0 ]; then
|
||||
exec "$BIN" --gui
|
||||
fi
|
||||
exec "$BIN" "$@"
|
||||
@@ -0,0 +1,41 @@
|
||||
# PixelPass AppImage
|
||||
|
||||
A "thin" AppImage: the gui-enabled `pixelpass` binary, a launcher (`AppRun`),
|
||||
and the desktop entry + icon. Run `./build-appimage.sh` to produce
|
||||
`pixelpass-<version>-x86_64.AppImage`.
|
||||
|
||||
## Why thin
|
||||
|
||||
`pixelpass` is an orchestrator — it links almost nothing (only `libpipewire`,
|
||||
which is excludelisted because it must match the host daemon) and instead
|
||||
**shells out** to `gst-launch-1.0`, `pactl`, and a player (`mpv`/`vlc`) found on
|
||||
the host `PATH`. The GUI's graphics libraries (`libGL`, `libwayland-*`,
|
||||
`libxkbcommon`, X11) are dlopen'd at runtime and are likewise on the AppImage
|
||||
excludelist — every desktop already has a matching set. So there is nothing
|
||||
useful to bundle, and bundling the graphics stack would only risk driver
|
||||
mismatches. The AppImage therefore carries just the binary.
|
||||
|
||||
This also explains why PixelPass suits AppImage better than Flatpak: the
|
||||
no-sandbox model lets the bundled binary freely spawn the host's `gst-launch`,
|
||||
`pactl`, and player, which a Flatpak sandbox would block.
|
||||
|
||||
## Host requirements
|
||||
|
||||
The AppImage runs on any reasonably current glibc-based distro that has:
|
||||
|
||||
- **GStreamer + plugins** — `gst-launch-1.0`/`gst-inspect-1.0` plus base,
|
||||
good/bad/ugly, libav, and the PipeWire plugin (the binary tells you the exact
|
||||
package names for your distro if something is missing).
|
||||
- **PipeWire** (with the PulseAudio shim, for `pactl`).
|
||||
- **A player** — `mpv` (preferred) or `vlc` — for the viewer side.
|
||||
- For X11 single-window capture: `xwininfo`.
|
||||
|
||||
These are the same dependencies the Arch package lists; the AppImage just spares
|
||||
you the Rust toolchain.
|
||||
|
||||
## Caveats
|
||||
|
||||
- **Built on a bleeding-edge glibc** (CachyOS), so the AppImage requires a host
|
||||
glibc at least that new. For broad compatibility, rebuild on an older base.
|
||||
- **Hardware encode (VAAPI `vah264enc`)** uses the host GPU driver; it can't be
|
||||
bundled. The software path (`--no-hwencode`, x264) always works.
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build a "thin" PixelPass AppImage: the gui-enabled release binary plus only
|
||||
# its non-excludelisted shared libraries. The graphics stack (libGL, wayland,
|
||||
# xkbcommon, X11) is intentionally left to the host — those libs are on the
|
||||
# AppImage excludelist because they must match the host driver — and the
|
||||
# runtime tools PixelPass shells out to (gst-launch-1.0, pactl, mpv/vlc) are
|
||||
# expected on the host PATH, the same contract the Arch package documents.
|
||||
#
|
||||
# Usage: packaging/appimage/build-appimage.sh
|
||||
# Output: packaging/appimage/pixelpass-x86_64.AppImage
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
repo="$(cd "$here/../.." && pwd)"
|
||||
tools="$here/.tools"
|
||||
appdir="$here/AppDir"
|
||||
mkdir -p "$tools"
|
||||
|
||||
# linuxdeploy is itself an AppImage; run it without FUSE so this works on hosts
|
||||
# (and CI) that lack libfuse2.
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
# Embed the version from Cargo.toml into the AppImage filename metadata.
|
||||
VERSION="$(grep -m1 '^version' "$repo/Cargo.toml" | sed -E 's/.*"(.*)".*/\1/')"
|
||||
export VERSION
|
||||
|
||||
echo ">> building release binary (--features gui)"
|
||||
( cd "$repo" && cargo build --release --features gui )
|
||||
bin="$repo/target/release/pixelpass"
|
||||
|
||||
echo ">> fetching linuxdeploy"
|
||||
ld="$tools/linuxdeploy-x86_64.AppImage"
|
||||
if [ ! -x "$ld" ]; then
|
||||
curl -fL --retry 3 -o "$ld" \
|
||||
"https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||
chmod +x "$ld"
|
||||
fi
|
||||
|
||||
echo ">> assembling AppDir"
|
||||
rm -rf "$appdir"
|
||||
mkdir -p "$appdir/usr/bin"
|
||||
install -m755 "$bin" "$appdir/usr/bin/pixelpass"
|
||||
|
||||
echo ">> running linuxdeploy (bundles libs, builds the AppImage)"
|
||||
# -e: analyse this binary for libraries to bundle (only libpipewire et al. that
|
||||
# aren't excludelisted will be copied; glibc + graphics libs are skipped).
|
||||
# -d/-i: desktop entry + icon for desktop integration.
|
||||
# --custom-apprun: our launcher that opens --gui from a file manager.
|
||||
( cd "$here" && OUTPUT="pixelpass-${VERSION}-x86_64.AppImage" "$ld" \
|
||||
--appdir "$appdir" \
|
||||
-e "$bin" \
|
||||
-d "$repo/assets/pixelpass.desktop" \
|
||||
-i "$repo/assets/pixelpass-256.png" \
|
||||
--icon-filename pixelpass \
|
||||
--custom-apprun "$here/AppRun" \
|
||||
--output appimage )
|
||||
|
||||
echo ">> done: $here/pixelpass-${VERSION}-x86_64.AppImage"
|
||||
Reference in New Issue
Block a user