Lulo builds from a single Makefile into a standard /usr layout: three binaries on PATH, three helpers in libexec, two systemd units (one user, one system), a polkit policy, and the default scheduler config – plus a one-time GNOME Shell extension step when you want focus tracking on GNOME.
The build is a plain make with PREFIX controlling the install root.
| Command | Purpose |
|---|---|
make PREFIX=/usr |
Standard build |
make strict PREFIX=/usr |
Build with stricter warnings |
make analyze PREFIX=/usr |
Static analysis pass |
make asan PREFIX=/usr |
Sanitizer build |
make print-install-paths PREFIX=/usr |
Show the resolved install paths |
make install lays the project out under PREFIX (here /usr) plus system config under /etc.
| Path | Contents |
|---|---|
/usr/bin |
lulo, lulod, lulod-system |
/usr/libexec/lulo |
lulo-admin, lulod-focus-kde, lulod-focus-gnome |
/usr/share/lulo |
Runtime data, KWin focus script, GNOME Shell extension, example scheduler config |
/usr/lib/systemd/user |
lulod.service |
/usr/lib/systemd/system |
lulod-system.service |
/usr/share/polkit-1/actions |
Polkit policy (the two actions) |
/etc/lulo/scheduler |
Default scheduler config |
The simplest path builds, installs, sets up the user and system services, and launches the TUI:
cd /path/to/lulo
make PREFIX=/usr
sudo make install PREFIX=/usr
./install-lulod-user-service.sh
./install-lulod-system-service.sh
/usr/bin/lulo -i nc
The helper scripts detect the installed /usr layout and use it. install-lulod-user-service.sh also auto-detects your desktop and, on GNOME, sets LULOD_FOCUS_PROVIDER=gnome for the user service.
For a single command that builds, installs to /usr, wires up both services, and (on GNOME) installs the focus extension:
cd /path/to/lulo
./install-system.sh
KDE loads its focus script at runtime, but GNOME Shell only loads extensions from its own directories, so the GNOME focus provider needs a one-time extension install (see Focus Providers for why):
./install-lulo-gnome-extension.sh # copies + enables lulod-focus@ninez.org for your user
On Wayland, log out and back in so GNOME Shell loads the extension, then systemctl --user restart lulod.service. The provider can always be overridden with LULOD_FOCUS_PROVIDER (kde, gnome, none, or auto).
Lulo runs two long-lived services with very different privilege.
| Unit | Scope | Role |
|---|---|---|
lulod.service |
systemd user unit | The unprivileged session daemon: snapshot caches and focus integration |
lulod-system.service |
systemd system unit | The privileged daemon: scheduler enforcement, privileged edits, tracing |
If you prefer to rely on the installed vendor units directly:
sudo systemctl daemon-reload
systemctl --user daemon-reload
sudo systemctl enable --now lulod-system.service
systemctl --user enable --now lulod.service
The privileged daemon is the only component that runs as root; the TUI stays unprivileged and reaches privilege through the RW lease or the pkexec helper (see Process Model & IPC). The two polkit actions installed under /usr/share/polkit-1/actions govern those two paths.
/usr/bin/lulo -i nc
The -i flag selects the input backend; LULO_INPUT is the environment equivalent. Lulo supports a Notcurses input backend and a raw-terminal backend, auto-selecting based on TERM when not told otherwise – -i nc forces the Notcurses backend, which is the right choice on VTE/GNOME terminals. Inside the TUI, ? shows a per-page help overlay, Tab switches pages, Shift+Tab cycles subviews, and Shift+W unlocks RW mode.
To update in place when the install path is unchanged:
cd /path/to/lulo
make PREFIX=/usr
sudo make install PREFIX=/usr
sudo systemctl restart lulod-system.service
systemctl --user restart lulod.service
If your session environment changed significantly, rerun ./install-lulod-user-service.sh. To replace /etc/lulo/scheduler with the shipped example config:
./reset-lulod-system-config.sh
sudo systemctl restart lulod-system.service
If you previously used old repo-local systemd units, disable and remove them before enabling the installed ones (the user unit under ~/.config/systemd/user/lulod.service, the system unit under /etc/systemd/system/lulod-system.service), then daemon-reload each scope.
For staged / distro packaging, install into a DESTDIR root:
make install PREFIX=/usr DESTDIR=/tmp/pkgroot
make print-install-paths PREFIX=/usr shows exactly where each artifact will land, which is useful when authoring a package manifest.