Companion to peerspeak's packaging/debian/README. Captures the shared bookworm distrobox build, the box-local CARGO_TARGET_DIR, and — most importantly — why the GStreamer capture stack is hard-coded into Depends (invoked as subprocesses, invisible to dpkg-shlibdeps). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Debian / Ubuntu .deb build
This documents how the pixelpass_*.deb is produced. The deb recipe itself
lives in-repo as the [package.metadata.deb] block in Cargo.toml (cargo-deb's
equivalent of a PKGBUILD); this file documents only the build environment.
pixelpass is the screen-share companion to peerspeak and is built the same way
in the same box. See peerspeak's packaging/debian/README.md for the full
rationale behind each step — this is the short version.
TL;DR
distrobox enter peerspeak-bookworm -- bash -lc '
source ~/.cargo/env
cd ~/git/butter/pixelpass
export CARGO_TARGET_DIR=~/.cache/cargo-deb-targets/pixelpass # MANDATORY
cargo deb
'
# output: $CARGO_TARGET_DIR/debian/pixelpass_<version>-1_amd64.deb
Build environment
- Base: the same Debian 12 (bookworm) distrobox
peerspeak-bookworm(glibc 2.36) used for peerspeak. Never build on the Arch host (newer glibc- shared
$HOME/target/would link Arch C objects into the binary).
- shared
- Use a box-local, pixelpass-specific
CARGO_TARGET_DIR(distinct from peerspeak's) so the two never share an artifact cache:export CARGO_TARGET_DIR=~/.cache/cargo-deb-targets/pixelpass. - Toolchain provisioning (rustup stable +
cargo-deb+build-essentialpkg-config) is identical to peerspeak's README. pixelpass itself links few C libraries — the heavy GStreamer stack it uses is invoked as subprocesses, not linked (see below), so it adds no extra*-devbuild-deps beyond the base.
Why Depends lists the whole GStreamer stack explicitly
pixelpass does its screen capture by shelling out to the GStreamer CLI
(gst-launch-1.0 / gst-inspect-1.0) and to pactl, not by linking the
GStreamer libraries. That means dpkg-shlibdeps (which only sees linked .so
files) cannot detect them, so $auto alone would ship a .deb whose Depends
omits the entire capture stack. A fresh Ubuntu host would then fail at
pixelpass's own deps::check_host_binaries startup probe — before it ever
prints a connection ticket, which is exactly the field bug that motivated this.
So the Cargo.toml depends hard-codes the runtime stack on top of $auto:
$auto, gstreamer1.0-tools, gstreamer1.0-plugins-base,
gstreamer1.0-plugins-good, gstreamer1.0-plugins-bad,
gstreamer1.0-plugins-ugly, gstreamer1.0-libav, gstreamer1.0-pipewire,
gstreamer1.0-pulseaudio, pulseaudio-utils, x11-utils
This covers both capture backends (pipewiresrc on Wayland, ximagesrc on X11
from plugins-good), the VAAPI + software H.264 encoders, the AAC/TS mux tail,
the PulseAudio source, and the pactl/xdpyinfo helpers.
glibc floor
Same as peerspeak: built against glibc 2.36 → runs on Debian 12+ / Ubuntu 24.04+. (pixelpass's own linked-library floor is lower, ~2.39-era, but it is always shipped alongside peerspeak, whose 2.36 floor governs the pair.)