# Debian / Ubuntu `.deb` build This documents how the `peerspeak_*.deb` is produced, so the deb path is as self-documenting as the Arch (`packaging/PKGBUILD`) and AppImage paths. The deb **recipe itself** lives in-repo as the `[package.metadata.deb]` block in the top-level `Cargo.toml` (cargo-deb's equivalent of a PKGBUILD). This file documents only the **build environment**, which is otherwise undiscoverable from a fresh clone. ## TL;DR ```sh # one-time: create + provision the build box (see "Build environment" below) distrobox enter peerspeak-bookworm -- bash -lc ' source ~/.cargo/env cd ~/git/butter/peerspeak export CARGO_TARGET_DIR=~/.cache/cargo-deb-targets/peerspeak # MANDATORY, see below cargo deb ' # output: $CARGO_TARGET_DIR/debian/peerspeak_-1_amd64.deb ``` ## Build environment - **Base: a Debian 12 (bookworm) distrobox named `peerspeak-bookworm`.** Created with `distrobox create --name peerspeak-bookworm --image debian:12`. Bookworm ships **glibc 2.36**, which sets the widest practical compatibility floor (see "glibc floor" below). - **NEVER build the `.deb` on the Arch host.** Two independent reasons: 1. The Arch host's glibc is far newer, so the resulting `.deb` would demand a glibc no normal Debian/Ubuntu user has, and ships an empty `Depends`. 2. distrobox shares `$HOME` (and therefore the repo's `target/`) with the host, so a host build links Arch-compiled C objects into the "Debian" binary. ### One-time provisioning inside the box ```sh distrobox enter peerspeak-bookworm sudo apt update sudo apt install -y build-essential pkg-config clang libclang-dev \ libpipewire-0.3-dev libopus-dev libasound2-dev libxcb1-dev # clang/libclang -> pipewire-sys bindgen ; libxcb1-dev -> link curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y source ~/.cargo/env cargo install cargo-deb ``` ### The mandatory separate `CARGO_TARGET_DIR` Because distrobox shares `$HOME`, the repo's default `target/` is the **same directory** the Arch host builds into. If you run `cargo deb` without overriding the target dir, cargo will happily reuse Arch-built `.o`/rlib artifacts and link them into the Debian binary, producing a `.deb` that crashes or demands the host's glibc. Always point the build at a box-local cache: ```sh export CARGO_TARGET_DIR=~/.cache/cargo-deb-targets/peerspeak ``` (Run `cargo clean` first if you ever suspect a polluted target dir.) ## glibc floor The `.deb` is built against the build box's glibc, which becomes the install floor (`libc6 (>= 2.36)` lands in `Depends` via `$auto`): | Build box | glibc | Runs on | |----------------------|-------|--------------------------------------| | `debian:12` (current)| 2.36 | Debian 12+, Ubuntu 24.04+ (glibc ≥ 2.36) | | `ubuntu:26.04` (old) | 2.43 | Ubuntu 26.04+ only — too narrow, abandoned | If a friend is on something even older than Debian 12, drop the floor further by recreating the box from an older base image and rebuilding. ## Runtime `Depends` / `Recommends` - `Depends = "$auto"` — cargo-deb runs `dpkg-shlibdeps`, which discovers the linked shared libraries (PipeWire, Opus, ALSA, xcb, glibc, …) automatically. - `Recommends = "pixelpass, mpv"` — `pixelpass` provides in-room screen sharing and `mpv` is the screen-share viewer (these are companion programs invoked as subprocesses, not linked libraries, so they are Recommends not Depends). See `pixelpass`'s own `packaging/debian/README.md` for why **its** `Depends` lists the whole GStreamer stack explicitly.