Executes docs/superpowers/specs/2026-07-07-runtime-performance-pass-design.md: - database.rs: every pooled connection now runs WAL + synchronous=NORMAL + busy_timeout=5000 + foreign_keys=ON via with_init (in-memory pools get the latter two). Fixes the SQLITE_BUSY failure mode under the parallel scanner and makes FK cascades work on every connection, not just whichever one last ran the old one-shot pragma in delete_folder. - database.rs: prepare_cached for the per-video info_cache queries; new info_cache_put_many bulk upsert (single transaction) replaces the per-row autocommitted info_cache_put, with a round-trip unit test. - library.rs: enrich_with_cache collects cache misses and flushes them once per channel; title sort uses sort_by_cached_key. - app.rs: Title/ChannelAsc sorts use sort_by_cached_key instead of allocating two lowercased strings per comparison. - Cargo.toml: panic=abort in release (crash-hook still fires; Cargo forces unwind for test harnesses). PACKAGING.md documents the local RUSTFLAGS target-cpu=native opt-in; repo stays portable. - .gitignore: catacomb.db-wal / catacomb.db-shm sidecars. Verified: 146 tests pass (integration suite exercises the pragmas end-to-end), x86_64-pc-windows-gnu check green, live smoke shows journal_mode=wal + batched cache writes landing correct rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.4 KiB
Packaging Catacomb
This document covers building distributable packages. The one-liner:
scripts/package.sh all # .deb + .rpm + .AppImage into dist/
scripts/package.sh deb # just the .deb
scripts/package.sh rpm # just the .rpm
scripts/package.sh appimage
The script builds the release binary once and reuses it for every
format. Output lands in dist/ (gitignored).
Building for your own machine? Distributed packages must stay portable, so the repo never sets
target-cpu. If you compile locally and only run the binary on the build host, you can opt into host-specific SIMD (helps the ffmpeg-adjacent hot paths like the perceptual-dedup hashing):RUSTFLAGS="-C target-cpu=native" cargo build --releaseDon't ship that binary — it will SIGILL on any older CPU.
Linux formats
.deb (Debian / Ubuntu / Mint)
Built by cargo-deb, driven by
[package.metadata.deb] in Cargo.toml. The script installs cargo-deb
on demand. Runtime deps declared: yt-dlp, ffmpeg, mpv, xdg-utils,
libxcb1, libc6 (and libnotify4 recommended).
scripts/package.sh deb
sudo apt install ./dist/catacomb_*_amd64.deb
.rpm (Fedora / RHEL / openSUSE)
Built by cargo-generate-rpm,
driven by [package.metadata.generate-rpm]. It packages the
already-built (and release-profile-stripped) binary.
scripts/package.sh rpm
sudo dnf install ./dist/catacomb-*.x86_64.rpm
Note: ffmpeg on Fedora lives in RPM Fusion;
the dependency is declared but the user may need that repo enabled.
AppImage (any Linux)
A hand-rolled AppDir + appimagetool
(downloaded to dist/tools/ on first run). The image bundles the GUI
binary and its shared-library closure only — yt-dlp/ffmpeg/mpv are
still expected on the host PATH, same as the package deps. Bundling them
would balloon the image and tangle the licensing.
scripts/package.sh appimage
chmod +x dist/catacomb-*-x86_64.AppImage
./dist/catacomb-*-x86_64.AppImage
Arch Linux
Use the PKGBUILD in the repo root (not this script). It builds from a
fresh git clone, so run it from a clean directory:
mkdir build && cd build
cp /path/to/repo/PKGBUILD .
makepkg -si
For repeated builds after pushing new commits, always pass -C
(cleanbuild) so makepkg re-checks out the latest source instead of
reusing a stale cached clone.
Windows (.zip)
Windows cross-compiles cleanly from Linux — the formerly-blocking
Linux-only deps are target-gated in Cargo.toml (ksni and rfd's
xdg-portal backend are cfg(target_os = "linux"); tray::start is a
no-op off Linux; rfd falls back to its native Win32 backend).
rustup target add x86_64-pc-windows-gnu
sudo apt install mingw-w64 zip # or your distro's equivalent
scripts/package.sh win
This produces dist/catacomb-<ver>-x86_64-windows.zip containing
catacomb.exe, LICENSE.txt, and a README.txt listing the runtime
PATH deps (yt-dlp / ffmpeg / mpv). Release builds link as a GUI-subsystem
app (no console window); the binary reattaches to the launching terminal
at runtime (attach_windows_console in main.rs) so catacomb.exe --web 8080 from PowerShell prints its logs, while a double-click stays
windowless.
scripts/package.sh all includes the Windows zip automatically when the
target + mingw + zip are all present, and silently skips it otherwise.
macOS (.app .zip)
macOS cross-compiles via osxcross,
which needs Apple's macOS SDK (extracted from Xcode — its license does not
permit redistribution, which is why this build is local-only and not in
CI). The crypto stack is ring, which builds against the osxcross SDK
without trouble.
One-time setup: build osxcross with a macOS SDK and put its
target/bin on your PATH (this provides the oa64-clang / o64-clang
wrapper compilers). Then:
rustup target add aarch64-apple-darwin # or x86_64-apple-darwin
MAC_ARCH=arm64 scripts/package.sh mac # arm64 (default) | x86_64
This cross-compiles, assembles an unsigned catacomb.app
(Info.plist + the Mach-O binary; an .icns icon too if png2icns is
available), and zips it to dist/catacomb-<ver>-<arch>-macos.zip. The
.app is not codesigned or notarized, so on the target Mac it must be
opened the first time via right-click → Open, or cleared with xattr -dr com.apple.quarantine catacomb.app. Runtime deps (yt-dlp / ffmpeg / mpv)
are expected on PATH as on the other platforms.
A .dmg and codesigning/notarization (and a tray-icon-based macOS tray)
are follow-ups; the tray is currently a no-op off Linux. A MacPorts
port (a Portfile building from source, like the Arch PKGBUILD) is a
possible future native-distribution path — unscheduled.
CI
.forgejo/workflows/release.yml runs scripts/package.sh all on every
pushed tag (v*) and attaches the resulting artifacts to the Codeberg
release. The Linux container also installs mingw-w64 + zip + the
x86_64-pc-windows-gnu target, so the Windows zip is built in CI
alongside the .deb/.rpm/.AppImage. The macOS zip is not in CI
(the SDK can't be hosted in a public image) — build it locally per the
section above, or add a GitHub Actions macos-latest job which has Xcode
and can also codesign/notarize.