CI / check (push) Canceled after 0s
The repo assumed a distro with a system-wide Rust, which NixOS does not provide. This adds a flake devShell carrying the full dependency surface: - Build: rustc/cargo/clippy/rustfmt, pkg-config, clang (pipewire-sys and libspa-sys need a real libclang for bindgen, via LIBCLANG_PATH), cmake (audiopus_sys's vendored-libopus fallback), and git (build.rs stamps PEERSPEAK_GIT_SHORT from `git rev-parse`). - Link: alsa-lib, libopus, pipewire. - dlopen'd at runtime: vulkan-loader, libxkbcommon, wayland and the X11 libs. Nothing links these, so they never land in the binary's rpath and are reachable only through LD_LIBRARY_PATH. Omitting them builds fine and then fails at window creation, which is a confusing way to find out. - The supply-chain gates CI runs (cargo-deny, cargo-audit) plus cargo-deb. These were `cargo install`ed on the CachyOS side, which does not carry over — those binaries link that distro's glibc. It also carries the screen-share tools (GStreamer + plugin search path, pactl, mpv). Those look like they belong only to pixelpass, but tests/screenshare_host_fault.rs starts a REAL pixelpass host, which aborts at its own preflight without them — so they are a dependency of this test suite. They are duplicated from pixelpass's flake rather than imported: the two projects are mutually optional by design, and having one flake consume the other would reintroduce the build-level dependency that rule prevents. nixpkgs is pinned to nixos-26.05, the same channel the hosts run, so the libraries here match the running PipeWire daemon and Vulkan ICD. Verified: 640 lib tests pass, all 4 screenshare_host_fault live gates pass (real audio backend, real network bind, real pixelpass child), fmt clean. Known delta: clippy 1.95.0 (nixpkgs 26.05) flags one collapsible_match in src/widget/selectable_text.rs that clippy 1.97.1 on CachyOS did not.
135 lines
5.7 KiB
Nix
135 lines
5.7 KiB
Nix
{
|
|
description = "PeerSpeak — decentralized P2P voice chat (Rust/iroh/PipeWire/Opus/iced)";
|
|
|
|
# Pinned to the same channel the hosts run (nixos-config tracks nixos-26.05),
|
|
# so the libraries this shell links and dlopens are built against the same
|
|
# release as the PipeWire daemon and Vulkan ICD actually running on the
|
|
# machine. Floating to unstable here would reintroduce precisely the
|
|
# client/server version skew the pin exists to prevent.
|
|
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05";
|
|
|
|
outputs =
|
|
{ nixpkgs, ... }:
|
|
let
|
|
system = "x86_64-linux";
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
|
|
# Libraries that iced/winit/wgpu open with dlopen at RUNTIME rather than
|
|
# linking at build time. Because nothing links them, they never land in
|
|
# the binary's rpath — under `cargo run` the loader finds them only
|
|
# through LD_LIBRARY_PATH. Leaving them out builds fine and then panics
|
|
# at window creation, which is a genuinely confusing failure, so they are
|
|
# listed explicitly instead of discovered the hard way.
|
|
runtimeLibs = with pkgs; [
|
|
vulkan-loader # wgpu's Vulkan backend (iced's renderer)
|
|
libxkbcommon # winit keyboard handling
|
|
wayland # wayland-sys, dlopen'd on a Wayland session
|
|
libx11 # x11-dl, dlopen'd on the X11 fallback path
|
|
libxcursor
|
|
libxrandr
|
|
libxi
|
|
];
|
|
|
|
# Screen sharing spawns pixelpass as a CHILD PROCESS, and pixelpass in
|
|
# turn drives GStreamer as a subprocess. That makes these tools a
|
|
# dependency of peerspeak's own test suite, not just of pixelpass:
|
|
# `tests/screenshare_host_fault.rs` starts a real pixelpass host, which
|
|
# aborts at its preflight if gst-launch-1.0 is missing.
|
|
#
|
|
# Deliberately duplicated from pixelpass's flake rather than importing it
|
|
# as an input. The two projects are mutually optional by design — neither
|
|
# is a dependency of the other, and the coupling is a runtime subprocess
|
|
# contract. Making one flake consume the other would quietly reintroduce
|
|
# exactly the build-level dependency that rule exists to prevent.
|
|
screenshareTools = with pkgs; [
|
|
gst_all_1.gstreamer
|
|
gst_all_1.gst-plugins-base
|
|
gst_all_1.gst-plugins-good
|
|
gst_all_1.gst-plugins-bad
|
|
gst_all_1.gst-plugins-ugly
|
|
gst_all_1.gst-libav
|
|
pipewire # pipewiresrc (Wayland capture; ships in this pkg)
|
|
];
|
|
in
|
|
{
|
|
devShells.${system}.default = pkgs.mkShell {
|
|
nativeBuildInputs = with pkgs; [
|
|
rustc
|
|
cargo
|
|
rustfmt
|
|
clippy
|
|
|
|
# The supply-chain gates .gitea/workflows/ci.yml runs, so the same
|
|
# checks are reproducible locally before a push. These were `cargo
|
|
# install`ed on the CachyOS side, which does not carry over — those
|
|
# binaries link that distro's glibc and will not run here.
|
|
# cargo-deny reads deny.toml; cargo-audit reads .cargo/audit.toml.
|
|
cargo-audit
|
|
cargo-deny
|
|
# Debian packaging (`cargo deb --no-build`). Note the .deb itself
|
|
# should still be built inside a Debian/Ubuntu distrobox so the
|
|
# binary links that distro's glibc — see the packaging notes in
|
|
# Cargo.toml.
|
|
cargo-deb
|
|
|
|
pkg-config
|
|
|
|
# pipewire-sys and libspa-sys generate their bindings with bindgen,
|
|
# which needs a real libclang present at build time.
|
|
clang
|
|
|
|
# audiopus_sys prefers the system libopus via pkg-config but falls
|
|
# back to a vendored CMake build; cmake keeps that fallback working
|
|
# rather than failing obscurely inside a build script.
|
|
cmake
|
|
|
|
# build.rs shells out to `git rev-parse --short=8 HEAD` to stamp
|
|
# PEERSPEAK_GIT_SHORT into the binary (surfaced in Settings).
|
|
git
|
|
]
|
|
++ screenshareTools
|
|
++ [
|
|
pkgs.pulseaudio # `pactl`, used by pixelpass's audio routing
|
|
pkgs.mpv # the screen-share viewer
|
|
];
|
|
|
|
buildInputs =
|
|
with pkgs;
|
|
[
|
|
alsa-lib # alsa-sys, pulled in by rodio/cpal
|
|
libopus # audiopus_sys, linked dynamically
|
|
pipewire # pipewire-sys + libspa-sys: the Linux audio backend
|
|
]
|
|
++ runtimeLibs;
|
|
|
|
# bindgen finds libclang through this variable specifically — having
|
|
# clang on PATH is not sufficient.
|
|
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
|
|
|
|
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath runtimeLibs;
|
|
|
|
# NixOS keeps every GStreamer plugin in its own store path, so the
|
|
# gst-launch-1.0 that pixelpass spawns discovers them ONLY through this
|
|
# search path. Same reasoning as hosts/darp5 and hosts/cazen in
|
|
# nixos-config.
|
|
GST_PLUGIN_SYSTEM_PATH_1_0 =
|
|
pkgs.lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" screenshareTools;
|
|
|
|
# Only greet an interactive shell. shellHook also runs under
|
|
# `nix develop --command …`, where printing this would interleave the
|
|
# banner with the command's own output.
|
|
shellHook = ''
|
|
if [ -t 1 ]; then
|
|
echo "peerspeak — rustc $(rustc --version | cut -d' ' -f2) / cargo $(cargo --version | cut -d' ' -f2)"
|
|
echo " cargo build --release build"
|
|
echo " cargo test lib tests"
|
|
echo " cargo clippy --all-targets -- -D warnings lint"
|
|
echo
|
|
echo "Screen sharing spawns pixelpass as a child process — it must be"
|
|
echo "on PATH. Build it from ../pixelpass and add its target/release."
|
|
fi
|
|
'';
|
|
};
|
|
};
|
|
}
|