# Void packaging Void Linux (glibc, x86_64) templates in void-packages layout, built with the standard Void source tooling. Submission to upstream void-packages is out of scope for spec #16; these templates serve the signed personal xbps repository first. ## Layout ``` packaging/void/ ├── README.md this file ├── build.sh podman harness: lint + xbps-src build + import smoke ├── tool_checksums.txt pinned base image and void-packages commit └── srcpkgs/ ├── python3-pywhispercpp/ ticket #26: whisper.cpp Python binding ├── ... ticket #25: small Python dependencies └── voculinux ticket #27: the application ``` `srcpkgs/` mirrors void-packages so the tree overlays cleanly: `cp -r packaging/void/srcpkgs/. /path/to/void-packages/srcpkgs/` (`build.sh` does this inside the container.) ## Templates | Template | Ticket | Notes | |---|---|---| | `python3-pywhispercpp` | #26 | Vulkan backend on by default; see below | | `voculinux` | #27 | The app, from the canonical release sdist; see below | ## python3-pywhispercpp Version `1.5.0`, pinned to the same version `install.sh` (`PYWHISPERCPP_VERSION`) and `uv.lock` pin — never newest upstream. The sdist checksum in the template must equal the `sha256` uv.lock records for the sdist; `tests/test_void_pywhispercpp_template.py` fails otherwise. - **Vulkan** is a build option, on by default. Rebuild CPU-only with `build.sh python3-pywhispercpp -- -o ~vulkan pkg`. There is no CUDA build: Void ships no CUDA toolkit package. Rebuilding locally with a hand-installed toolkit (`GGML_CUDA=1`) is a documented, unsupported escape hatch. - **Portable CPU flags**: every ggml SIMD option is pinned off (`-DGGML_NATIVE=OFF -DGGML_SSE42=OFF ...`), the plain x86-64 baseline already used by the Flatpak (`#938`, `#957`). The offline test asserts each pin in the template (the build configuration), and the harness scans the shipped `libggml-cpu` (`.GCC.command.line`, `.comment`) for recorded `-march=native`/`-mcpu=native`/`-mtune=native` flags and fails on a match. The recorded-flags scan is a tripwire, not a proof: the proof is the pinned configuration plus `setup.py`'s documented `CMAKE_ARGS` passthrough. - **Shared libraries**: `BUILD_SHARED_LIBS=ON` with an `$ORIGIN` rpath (as `install.sh` does), so the extension resolves the whisper.cpp libraries installed beside it with no `LD_LIBRARY_PATH`. - **Offline build**: the sdist vendors whisper.cpp, pybind11, and the ggml sources; the build fetches nothing beyond the declared distfiles. `PYWHISPERCPP_VERSION` is injected because the sdist carries no `version.txt` (its version otherwise comes from git metadata). - **Runtime deps** (`python3-numpy`, `python3-requests`, `python3-tqdm`, `python3-platformdirs`) are the sdist's own `install_requires` and were verified to exist in current void-packages; the container build re-verifies via dependency resolution. ## voculinux Version `0.18.5`, matching `src/vocalinux/version.py` — never newest upstream. The template builds the canonical release source distribution (the `releases/download` sdist, the same bytes published to PyPI) with a pinned `checksum`; `tests/test_void_app_template.py` fails otherwise. The 0.18.5 asset still carries the pre-rename archive root, so the template sets `wrksrc` explicitly; the first release cut after the rename drops the override and points `distfiles` at the renamed asset. - **Runtime deps** are Void's own interpreter, GTK and desktop bindings (`python3`, `python3-gobject`, `python3-cairo`, `gtk+3`, `libayatana-appindicator`, `ibus`, `gobject-introspection`), the packaged Python libraries, and the three templates from tickets #25 and #26 (`python3-pynput`, `python3-PyAudio`, `python3-pywhispercpp`). Every name was verified to exist in current void-packages; the container build re-verifies via dependency resolution. - **No payload beyond the app**: no speech models (they download on first run), no vendored wheels, no pip at build or install time. The container smoke fails the build if the payload carries model weights or wheels. - **Renamed paths**: the `voculinux.desktop` entry, the hicolor icons, and a `usr/share/voculinux/packaged` marker the app reads to present package-manager updates. - **INSTALL.msg** covers what xbps cannot express: the `input` group for the evdev hotkey backend, first-run model downloads, optional engines as manual additions (vosk, OpenAI whisper, Parakeet, faster-whisper, onnxruntime), the absent `ydotool` rung, and updating through xbps. - **Update checker**: packaged installs keep background checks as a signal, but every update affordance (tray entry, notification, About page) presents the package-manager path (`src/vocalinux/utils/packaging.py`). ## Building ```sh packaging/void/build.sh python3-pywhispercpp packaging/void/build.sh python3-pywhispercpp -- -o ~vulkan pkg packaging/void/build.sh voculinux ``` Podman only, never Docker. The base image digest and the void-packages commit come from `tool_checksums.txt`; bump them there, never in the script. Ticket #28 wires this into the package smoke gate.