Compare commits
2
Commits
eb077d81f0
...
69ddc58133
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69ddc58133 | ||
|
|
09a07f5303 |
@@ -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,72 @@
|
||||
# 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.
|
||||
|
||||
## Building for broad compatibility (lower glibc baseline)
|
||||
|
||||
An AppImage requires a host glibc **at least as new** as the build host's. Built
|
||||
straight on a rolling distro (e.g. CachyOS, glibc 2.43) the AppImage only runs
|
||||
on equally-new systems. Build inside an older base for wider reach. The script
|
||||
honours `CARGO_TARGET_DIR`, so an isolated toolchain won't clobber your host's
|
||||
`target/`:
|
||||
|
||||
```sh
|
||||
# One-time: an Ubuntu 24.04 distrobox (docker or podman backend).
|
||||
distrobox create --yes --image ubuntu:24.04 --name pixelpass-build
|
||||
distrobox enter pixelpass-build -- sudo apt-get update
|
||||
distrobox enter pixelpass-build -- sudo apt-get install -y \
|
||||
build-essential cmake clang libclang-dev pkg-config \
|
||||
libpipewire-0.3-dev libspa-0.2-dev curl ca-certificates file
|
||||
# Install rustup inside the box (edition 2024 needs rustc >= 1.85), then:
|
||||
distrobox enter pixelpass-build -- env \
|
||||
CARGO_TARGET_DIR=~/.cache/pixelpass-ubuntu/target \
|
||||
./packaging/appimage/build-appimage.sh
|
||||
```
|
||||
|
||||
**Why Ubuntu 24.04 and not something older:** PixelPass's `pipewire` crate
|
||||
binds the system's PipeWire headers via bindgen, and anything older than ~PW 1.0
|
||||
(e.g. Ubuntu 22.04's 0.3.48) fails to compile (missing struct fields / wrong
|
||||
types). And since PixelPass *is* a PipeWire/portal/Wayland app, it can only run
|
||||
on distros new enough to have modern PipeWire anyway — so an ancient glibc base
|
||||
buys nothing. 24.04 (glibc 2.39, PW 1.0.5) is the sweet spot.
|
||||
|
||||
The 24.04-built binary's baseline is **glibc 2.39** — and the only 2.39 symbols
|
||||
are two *weak* `pidfd_*` references from Rust std's process spawning (everything
|
||||
else is ≤ 2.35). That covers Ubuntu 24.04+, Debian 13+, Fedora 40+, and current
|
||||
rolling distros.
|
||||
|
||||
## Caveats
|
||||
|
||||
- **Hardware encode (VAAPI `vah264enc`)** uses the host GPU driver; it can't be
|
||||
bundled. The software path (`--no-hwencode`, x264) always works.
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/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 )
|
||||
# Honour CARGO_TARGET_DIR so an isolated build (e.g. inside an old-glibc
|
||||
# distrobox) doesn't have to clobber the host's target/.
|
||||
bin="${CARGO_TARGET_DIR:-$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