Keep host multimedia libraries out of the AppImage, document the exact Ubuntu build inputs, and resolve Rust 1.97 release-gate warnings.
PeerSpeak AppImage
A "thin" AppImage: the peerspeak binary, the bundled pixelpass screen-share
helper, a launcher (AppRun), and the desktop entry + icon. Run
./build-appimage.sh to produce peerspeak-<version>-x86_64.AppImage.
Why thin, and why pixelpass is bundled
PeerSpeak owns voice; pixelpass owns pixels. They are never Cargo
dependencies of each other — peerspeak shells out to the pixelpass binary over
its CLI. The AppImage co-locates pixelpass in usr/bin, and AppRun prepends
usr/bin to PATH, so peerspeak's normal $PATH lookup finds it with no code
change. Joe gets one file, and screen-share works out of the box.
Almost nothing is bundled: peerspeak's own assets (notification WAVs, avatar
presets, window icon, fonts) are include_bytes!-embedded, and the graphics
stack (libGL, libvulkan, libwayland-*, libxkbcommon, X11) is dlopen'd at
runtime and on the AppImage excludelist because it must match the host driver.
So the image carries just the two binaries plus a handful of small libs.
Host requirements
The AppImage runs on any reasonably current glibc-based distro that has:
- A Vulkan-capable GPU + driver (peerspeak's iced/wgpu renderer). Mesa/RADV on AMD/Intel or the NVIDIA driver all work.
- PipeWire with the PulseAudio shim,
pactl, and the hostlibpulse.so.0client library. The Pulse client stack is deliberately not bundled because PixelPass launches host GStreamer tools that must keep using the host's matching multimedia libraries. - For screen-share only — pixelpass shells out to these on the host
PATH; it prints the exact package names for your distro if any are missing:- GStreamer + plugins (
gst-launch-1.0/gst-inspect-1.0, base, good/bad/ugly, libav, and the PipeWire plugin), - mpv (or vlc) for the viewer side,
- on X11,
xwininfofor single-window capture.
- GStreamer + plugins (
On Arch/Artix that is one pacman line, e.g.:
sudo pacman -S gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad \
gst-plugins-ugly gst-libav gst-plugin-pipewire mpv xorg-xwininfo libpulse
(Add gstreamer-vaapi for hardware H.264 encode on AMD/Intel; the software
x264 path always works. On XLibre / X11 the capture path uses ximagesrc and
needs no XDG portal — no systemd required.)
Building for broad compatibility (glibc baseline)
An AppImage requires a host glibc at least as new as the build host's. Built
on a rolling distro (glibc 2.43) it only runs on equally-new systems. Build
inside Ubuntu 24.04 (glibc 2.39, PipeWire 1.0.5) for wide reach — pixelpass's
pipewire crate binds the system PipeWire headers and needs PipeWire >= 1.0, so
the older Debian 12 peerspeak-bookworm box (PW 0.3.65) cannot build it. 2.39
covers Debian 13+, Fedora 40+, and current rolling distros.
# One-time: an Ubuntu 24.04 distrobox that reuses the host rustup toolchain.
distrobox create --yes --image ubuntu:24.04 --name peerspeak-appimage
distrobox enter peerspeak-appimage -- sudo apt-get update
distrobox enter peerspeak-appimage -- sudo apt-get install -y \
build-essential cmake clang libclang-dev pkg-config \
libpipewire-0.3-dev libspa-0.2-dev libpulse-dev libasound2-dev libxcb1-dev \
curl ca-certificates file patchelf git
rustup toolchain install 1.97.1 --profile default
# PeerSpeak's ownership validator needs the modern SPA-JSON parser headers it
# is tested against. Distrobox exposes the host's headers under /run/host;
# pkg-config still links Ubuntu's older ABI-compatible libraries, preserving
# the glibc baseline. This checkout's verified host-header version is 1.6.8:
test -f /run/host/usr/include/spa-0.2/spa/utils/json-core.h
# Build with the repository's pinned Rust version (the host's ~/.rustup
# toolchain is glibc-2.17-baseline, so it runs in the box; isolated
# CARGO_TARGET_DIRs keep it off the host target/):
distrobox enter peerspeak-appimage -- env \
PATH="$HOME/.rustup/toolchains/1.97.1-x86_64-unknown-linux-gnu/bin:$PATH" \
SYSTEM_DEPS_LIBSPA_INCLUDE="/run/host/usr/include/spa-0.2" \
SYSTEM_DEPS_LIBPIPEWIRE_INCLUDE="/run/host/usr/include/pipewire-0.3:/run/host/usr/include/spa-0.2" \
./packaging/appimage/build-appimage.sh
Caveats
- Hardware encode (VAAPI) uses the host GPU driver and can't be bundled; the software x264 path always works.
- The bundled
pixelpassis built headless (noguifeature) — it is only ever driven by peerspeak, never launched standalone from this image.