Lulo – Install & Packaging

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.

Table of Contents

  1. Build targets
  2. Installed layout
  3. First install
  4. The one-command path
  5. GNOME focus provider
  6. Services and privilege
  7. Running lulo
  8. Updating, resetting, and migrating
  9. Packaging
  10. See also

1. Build targets

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

2. Installed layout

make install lays the project out under PREFIX (here /usr) plus system config under /etc.

Installed footprint /usr/bin lulo (TUI) lulod (session daemon) lulod-system (privileged daemon) /usr/libexec/lulo lulo-admin (pkexec helper) lulod-focus-kde lulod-focus-gnome /usr/share/lulo KWin focus script GNOME Shell extension example scheduler config /usr/lib/systemd user/lulod.service system/lulod-system.service /usr/share/polkit-1/actions io.lulo.system.unlock-rw io.lulo.admin.pkexec.apply-tune /etc/lulo/scheduler scheduler.conf profiles.d / rules.d
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

3. First install

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.

4. The one-command path

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

5. GNOME focus provider

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).

6. Services and privilege

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.

7. Running lulo


/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.

8. Updating, resetting, and migrating

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.

9. Packaging

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.

10. See also