# Maintainer: unom # # Arch Linux / SteamOS split package: punktfunk-host (the gaming-rig HOST, NVENC) and # punktfunk-client (the GTK4 couch/Deck CLIENT). Mirrors the rpm subpackages # (packaging/rpm/punktfunk.spec) and the two deb build scripts. On a Steam Deck you want # `punktfunk-client` (it's what the Decky plugin launches); on a gaming rig, `punktfunk-host`. # # Two build modes: # - AUR / standalone: makepkg in this dir (fetches the git tag below). # - In-tree / CI: PF_SRCDIR=$(git rev-parse --show-toplevel) makepkg --holdver # (builds the working tree instead of the tagged source — see build()). # # IMPORTANT: host encode is NVENC-only (crates/punktfunk-host/src/encode/linux.rs) — functional on # NVIDIA hosts; an AMD Deck-as-HOST needs a VAAPI backend first. The CLIENT decodes via VAAPI # (AMD/Intel, incl. the Deck) with a software fallback, so it works everywhere. See README.md. pkgbase=punktfunk # punktfunk-web (the browser console) is OPT-IN: building it needs `bun` (AUR-only as bun-bin on # stock Arch/SteamOS), so a default makepkg builds only host+client with no JS tooling — mirroring # the RPM spec's `%bcond_with web` (off by default). Set PF_WITH_WEB=1 to also build punktfunk-web # (appended to pkgname + bun to makedepends below). pkgname=('punktfunk-host' 'punktfunk-client') pkgver=0.2.0 pkgrel=1 arch=('x86_64') url="https://git.unom.io/unom/punktfunk" license=('MIT OR Apache-2.0') # All build deps for both crates (Arch runtime packages ship their own headers, so these cover # build + link). aws-lc/ring need clang+cmake; nasm is for asm. makedepends=('rust' 'cargo' 'clang' 'cmake' 'nasm' 'pkgconf' 'git' 'gtk4' 'libadwaita' 'sdl3' 'ffmpeg' 'pipewire' 'wayland' 'libxkbcommon' 'opus' 'libei') # Opt-in punktfunk-web: only then is bun (build tool; the console runs on plain nodejs) required. if [ "${PF_WITH_WEB:-0}" = 1 ]; then pkgname+=('punktfunk-web') makedepends+=('bun') # `bun-bin` from the AUR if bun isn't in your configured repos fi # AUR source (a tagged release). For an in-tree CI build, set PF_SRCDIR to the repo root and # build() uses it instead; see the README. source=("git+https://git.unom.io/unom/punktfunk.git#tag=v${pkgver}") sha256sums=('SKIP') _repo() { printf '%s' "${PF_SRCDIR:-$srcdir/punktfunk}"; } build() { cd "$(_repo)" export RUSTUP_TOOLCHAIN=stable CARGO_TARGET_DIR="$srcdir/target" export PUNKTFUNK_BUILD_VERSION="${pkgver}-${pkgrel}" # stamp --version / mgmt /health (build.rs) # The host's zero-copy FFI link-needs libcuda at build time; nvidia-utils provides it on an # NVIDIA builder. On a GPU-less builder symlink the CUDA stub into the link path first (same # caveat the RPM documents): ln -s "$(find / -name libcuda.so -path '*stubs*'|head -1)" /usr/lib/ cargo build --release --locked -p punktfunk-host -p punktfunk-client-linux # Management web console (opt-in): the node-server .output bundle (built with bun, run with node). if [ "${PF_WITH_WEB:-0}" = 1 ]; then ( cd web && bun install --frozen-lockfile && bun run build ) fi } package_punktfunk-host() { pkgdesc="Low-latency desktop/game streaming HOST (Moonlight-compatible + punktfunk/1)" # NVENC + GPU EGL/CUDA come from the NVIDIA driver (nvidia-utils) — kept an optdepend, never a # hard dep, exactly as the RPM (__requires_exclude libcuda) and deb (shlibdeps filter) do. depends=('ffmpeg' 'pipewire' 'pipewire-pulse' 'wireplumber' 'opus' 'libei' 'mesa' 'libglvnd' 'libxkbcommon' 'wayland') optdepends=('nvidia-utils: NVENC hardware encode + GPU EGL/CUDA zero-copy (REQUIRED to encode on NVIDIA)' 'gamescope: per-session nested compositor backend (no desktop login needed) — needs >=3.16.22' 'kwin: stream a KDE Plasma desktop (kwin VirtualDisplay backend)' 'mutter: stream a GNOME desktop (Mutter RecordVirtual backend)' 'sway: stream a wlroots desktop (Sway VirtualDisplay backend)' 'xdg-desktop-portal-kde: portal for the headless KDE session helper' 'xdg-desktop-portal-wlr: portal for the headless Sway session helper' 'punktfunk-web: browser management console (device pairing + status)') install=punktfunk-host.install local R; R="$(_repo)"; local T="$srcdir/target/release" install -Dm0755 "$T/punktfunk-host" "$pkgdir/usr/bin/punktfunk-host" # /dev/uinput + /dev/uhid -> input group (virtual gamepads + DualSense UHID) install -Dm0644 "$R/scripts/60-punktfunk.rules" "$pkgdir/usr/lib/udev/rules.d/60-punktfunk.rules" # 32 MB UDP socket buffers (send-side headroom at high bitrate) install -Dm0644 "$R/scripts/99-punktfunk-net.conf" "$pkgdir/usr/lib/sysctl.d/99-punktfunk-net.conf" # systemd USER units (the host runs in the graphical session, not as root); repoint ExecStart. install -Dm0644 "$R/scripts/punktfunk-host.service" "$pkgdir/usr/lib/systemd/user/punktfunk-host.service" sed -i 's#%h/punktfunk/target/release/punktfunk-host#/usr/bin/punktfunk-host#' \ "$pkgdir/usr/lib/systemd/user/punktfunk-host.service" install -Dm0644 "$R/scripts/punktfunk-kde-session.service" "$pkgdir/usr/lib/systemd/user/punktfunk-kde-session.service" sed -i 's#%h/punktfunk/scripts/headless/run-headless-kde.sh#/usr/share/punktfunk/headless/run-headless-kde.sh#' \ "$pkgdir/usr/lib/systemd/user/punktfunk-kde-session.service" # KWin Desktop-mode authorization: non-launcher .desktop whose X-KDE-Wayland-Interfaces lets the # host bind KWin's restricted zkde_screencast (virtual output) + fake_input globals on an # interactive Plasma session. Must ship with the host (KWin caches the per-exe grant on first # connect). See the file's header comment. install -Dm0644 "$R/packaging/linux/io.unom.Punktfunk.Host.desktop" \ "$pkgdir/usr/share/applications/io.unom.Punktfunk.Host.desktop" # headless session helpers + env templates + OpenAPI doc install -Dm0755 "$R/scripts/headless/run-headless-kde.sh" "$pkgdir/usr/share/punktfunk/headless/run-headless-kde.sh" install -Dm0755 "$R/scripts/headless/run-headless-sway.sh" "$pkgdir/usr/share/punktfunk/headless/run-headless-sway.sh" install -Dm0644 "$R/scripts/headless/kde-authorized" "$pkgdir/usr/share/punktfunk/headless/kde-authorized" install -Dm0644 "$R/scripts/headless/punktfunk-sink.conf" "$pkgdir/usr/share/punktfunk/headless/punktfunk-sink.conf" install -Dm0644 "$R/scripts/host.env.example" "$pkgdir/usr/share/punktfunk/host.env.example" install -Dm0644 "$R/packaging/bazzite/host.env" "$pkgdir/usr/share/punktfunk/host.env.bazzite" install -Dm0644 "$R/packaging/kde/host.env" "$pkgdir/usr/share/punktfunk/host.env.kde" install -Dm0644 "$R/api/openapi.json" "$pkgdir/usr/share/punktfunk/openapi.json" install -Dm0644 "$R/LICENSE-MIT" "$pkgdir/usr/share/licenses/punktfunk-host/LICENSE-MIT" install -Dm0644 "$R/LICENSE-APACHE" "$pkgdir/usr/share/licenses/punktfunk-host/LICENSE-APACHE" install -Dm0644 "$R/README.md" "$pkgdir/usr/share/doc/punktfunk-host/README.md" } package_punktfunk-client() { pkgdesc="Low-latency desktop/game streaming CLIENT (GTK4) — the couch/Deck side" # The GTK4/libadwaita client: SDL3 gamepads, FFmpeg (VAAPI) decode, PipeWire audio/mic. depends=('gtk4' 'libadwaita' 'sdl3' 'ffmpeg' 'pipewire' 'wireplumber' 'pipewire-pulse' 'opus' 'libglvnd') optdepends=('libva-mesa-driver: VAAPI hardware decode on AMD (incl. Steam Deck); software fallback otherwise' 'intel-media-driver: VAAPI hardware decode on Intel' 'gamescope: run the client fullscreen in a Gaming-Mode session') install=punktfunk-client.install local R; R="$(_repo)"; local T="$srcdir/target/release" install -Dm0755 "$T/punktfunk-client" "$pkgdir/usr/bin/punktfunk-client" install -Dm0644 "$R/packaging/linux/io.unom.Punktfunk.desktop" \ "$pkgdir/usr/share/applications/io.unom.Punktfunk.desktop" # DualSense hidraw access (full pad fidelity through SDL's HIDAPI driver). install -Dm0644 "$R/scripts/70-punktfunk-client.rules" \ "$pkgdir/usr/lib/udev/rules.d/70-punktfunk-client.rules" # 32 MB UDP recv buffer (so high-bitrate streams don't overflow the kernel socket buffer). install -Dm0644 "$R/scripts/99-punktfunk-client-net.conf" \ "$pkgdir/usr/lib/sysctl.d/99-punktfunk-client-net.conf" install -Dm0644 "$R/LICENSE-MIT" "$pkgdir/usr/share/licenses/punktfunk-client/LICENSE-MIT" install -Dm0644 "$R/LICENSE-APACHE" "$pkgdir/usr/share/licenses/punktfunk-client/LICENSE-APACHE" } package_punktfunk-web() { pkgdesc="punktfunk management web console (Nitro/Node SSR) — pairing + status in the browser" arch=('any') # Runtime is plain node (the .output is portable JS — bun was only the build tool). Auto-wired to # the host's mgmt token via the systemd --user units; enable with `systemctl --user enable --now punktfunk-web`. depends=('nodejs') local R; R="$(_repo)" # Pre-built node-server bundle (from build()) + a PATH-stable launcher (matches the .deb/.rpm). install -d "$pkgdir/usr/share/punktfunk-web/.output" cp -r "$R/web/.output/server" "$pkgdir/usr/share/punktfunk-web/.output/server" cp -r "$R/web/.output/public" "$pkgdir/usr/share/punktfunk-web/.output/public" install -d "$pkgdir/usr/bin" printf '%s\n' '#!/bin/sh' 'exec /usr/bin/node /usr/share/punktfunk-web/.output/server/index.mjs "$@"' \ > "$pkgdir/usr/bin/punktfunk-web-server" chmod 0755 "$pkgdir/usr/bin/punktfunk-web-server" # systemd USER units: the console runs per-user; web-init generates the login password on first start. install -Dm0644 "$R/scripts/punktfunk-web.service" "$pkgdir/usr/lib/systemd/user/punktfunk-web.service" install -Dm0644 "$R/scripts/punktfunk-web-init.service" "$pkgdir/usr/lib/systemd/user/punktfunk-web-init.service" install -Dm0755 "$R/scripts/web-init.sh" "$pkgdir/usr/share/punktfunk-web/web-init.sh" install -Dm0644 "$R/web/web.env.example" "$pkgdir/usr/share/punktfunk-web/web.env.example" install -Dm0644 "$R/LICENSE-MIT" "$pkgdir/usr/share/licenses/punktfunk-web/LICENSE-MIT" install -Dm0644 "$R/LICENSE-APACHE" "$pkgdir/usr/share/licenses/punktfunk-web/LICENSE-APACHE" }