Development
This page covers source builds, tests, and packaging workflows for contributors.
Prerequisites
- Rust 1.85+ (or install current stable via
rustup) just(https://github.com/casey/just) for task automationnfpm(https://nfpm.goreleaser.com) for packaging
sudo apt install build-essential pkg-config clang libclang-dev \
libopencv-dev libv4l-dev libpam0g-dev \
libgtk-4-dev libadwaita-1-dev \
libcairo2-dev libglib2.0-dev libgdk-pixbuf-2.0-dev \
libpango1.0-dev libgraphene-1.0-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-devsudo dnf install @development-tools pkg-config clang clang-devel \
opencv-devel libv4l-devel pam-devel \
gtk4-devel libadwaita-devel \
gstreamer1-devel gstreamer1-plugins-base-devel \
checkpolicy policycoreutilssudo pacman -S base-devel pkgconf clang llvm \
opencv v4l-utils pam \
gtk4 libadwaita \
gstreamer gst-plugins-baseSetup
git clone https://github.com/gundulabs/gaze
cd gaze
just --listBuild and test rust components
just build-rust
just test
just lint
just fmt-checkRun a locally-built daemon
The daemon takes no CLI arguments — paths are compiled in:
- Config:
/etc/gaze/config.toml - User templates:
/var/lib/gaze/users - Models:
/var/cache/gaze
It also owns com.gundulabs.Gaze on the system DBus bus, which requires root. You cannot run a second daemon as your user.
Easiest iteration loop: stop the installed service, run your build in the foreground.
sudo systemctl stop gazed
cargo build --workspace --release
sudo RUST_LOG=debug ./target/release/gazedRUST_LOG accepts standard tracing filters (info, debug, gaze=trace, etc.). Ctrl-C to stop, then sudo systemctl start gazed when you're done to restore the system daemon.
If you've never installed Gaze on this machine, you also need the DBus policy and a config file in place before the daemon can claim its name or load. The simplest way is to install the package once, then iterate on the binary:
sudo install -Dm644 packaging/config/com.gundulabs.Gaze.conf \
/etc/dbus-1/system.d/com.gundulabs.Gaze.conf
sudo install -Dm644 packaging/config/config.toml /etc/gaze/config.toml
sudo systemctl reload dbusThe CLI and GUI need no special setup — they talk to whichever gazed currently owns the bus name:
./target/release/gaze list-faces
./target/release/gaze auth --verbose
./target/release/gaze-guiIterating on the PAM module
pam-gaze and pam-gaze-grosshack build as cdylibs. After cargo build --release you'll have:
target/release/libpam_gaze.sotarget/release/libpam_gaze_grosshack.so
To exercise them through real PAM, copy into the system PAM library directory (path is distro-specific):
# Debian/Ubuntu
sudo cp target/release/libpam_gaze.so /lib/x86_64-linux-gnu/security/pam_gaze.so
# Fedora/RHEL
sudo cp target/release/libpam_gaze.so /lib64/security/pam_gaze.so
# Arch
sudo cp target/release/libpam_gaze.so /usr/lib/security/pam_gaze.soDon't lock yourself out
Before touching PAM files, keep a second terminal open with an active root shell (sudo -s). If the module crashes or misbehaves, you can revert from that shell. Test against a non-critical service first (e.g. add a line to /etc/pam.d/su or a custom service), not system-auth or sudo.
Quickest end-to-end test once the .so is in place:
sudo -k # invalidate cached sudo credentials
sudo -v # force a fresh PAM promptIterating on the GNOME extension
The extension source lives in gnome-shell-extension/. To run it from the tree without packaging:
mkdir -p ~/.local/share/gnome-shell/extensions
ln -sfn "$PWD/gnome-shell-extension" \
~/.local/share/gnome-shell/extensions/gaze@gundulabs.com
# compile the gsettings schema once
glib-compile-schemas ~/.local/share/gnome-shell/extensions/gaze@gundulabs.com/schemas
# on Xorg: Alt+F2 then `r`. On Wayland: log out and back in.
gnome-extensions enable gaze@gundulabs.com
gsettings set org.gnome.shell.extensions.gaze enable-face-authentication trueWatch shell logs while you iterate:
journalctl -f /usr/bin/gnome-shellFor the unlock-dialog session mode (lock screen), changes only take effect after a fresh lock, not a shell reload.
Packaging
just package <deb | rpm | archlinux>Package output:
dist/packages/
Cleaning build artifacts
just clean