SPS · log · files · refs · tags · releases · people · languages · GitHub · file
README.md
13827 bytes at 2909919 · GitHub
SPS Source Package System
SPS is currently under active testing and development, usage is not recommended if you arent a tester.
*SPS* is solo developed, and a small amount of AI is used (for debugging, releases, testing)! it is in slow, but fast development. patience is a virtue, people!
SPS is a source package system for small, administrator-run Unix-like systems. It is made from separate command-line tools, plain text state, POSIX shell, POSIX AWK, and normal tar archives.
The layout is influenced by CRUX and older Unix package tools, but SPS is not a CRUX compatibility project. It has its own recipes, package metadata, repository index, dependency handling, commands, and upgrade rules.
If you REALLY want the project rationale and the boundaries of the design, read [MANIFESTO.md](MANIFESTO.md). The exact 1.0 file formats and behavior are in [DESIGN.md](DESIGN.md).
SPS is not the distro
SPS is the source package system. It is not locked to one operating system. You can run src, sget, mkpkg, pkin, and the rest on Linux From Scratch, on a custom chroot, or next to another distro's userland. Recipes are plain text; an LFS tree can consume sps-core and sps-extra the same way SPS Linux does.
SPS Linux is a rolling release Linux distribution that uses SPS (natively). Informally it is called Splux. Official installer flow, live ISOs, Plasma profiles, and the linux-desktop kernel are SPS Linux pieces. They live in this tree and in the core/extra collections because that is how Splux is built and installed.
If you take SPS into an LFS (or any other) project, do not assume setup will do the right thing for you. The installer partitions disks, writes fstab, chooses systemd or OpenRC (and others, copies a Splux hostname, and installs distro profiles. Your LFS book already has its own disk, boot, and configuration story. Use sget and mkpkg there; skip setup and mkiso unless you actually want SPS Linux on that machine.
Tools
SPS is a set of tools rather than one large front end:
srcindexes and queries source repositories.sgethandles dependency-aware installs, upgrades, removals, and queries.mkpkgbuilds a binary package from a recipe.pkininstalls or upgrades one binary package.pkdelremoves one installed package.pkstatreads the installed package database (pkstat --countprints
the number of installed packages).
pkcheckchecks installed files and database consistency.pkmarkchanges whether an installed package is explicit or dependency-only.pkconfreconciles protected configuration files with the packaged defaults
an upgrade left beside them, the way CRUX has rejmerge and Gentoo has etc-update.
setupis the SPS Linux (Splux) dialog(1) installer (Slackware/FreeBSD
style). Optional; other projects using SPS do not need it.
mkisobuilds an SPS Linux live ISO (systemd by default; busybox init if
systemd is not on the build host) you can flash and boot into setup.
tools/upgrade-recipesis a maintainer command, not a runtime package tool.
It walks core and extra recipes, finds the newest stable upstream, rewrites version/source/hash, and records newly required libraries. See [PACKAGE-MAINTAINER.md](PACKAGE-MAINTAINER.md).
tools/audit-recipesis the other maintainer command. It checks a recipe
tree for defects an index build cannot see, and with --net it downloads every declared source and verifies its SHA-256. A tarball that upstream moved or re-rolled is the most common way a source distribution stops installing, and nothing else notices until a user's build aborts.
The split matters. pkin does not search repositories. pkdel does not solve dependencies. src does not install anything. sget ties the lower-level tools together when you want the usual package-manager workflow.
Below is [MOSTLY] info on installing the package manager elsewhere, not Splux itself. And for maintainers of Splux.
Requirements
SPS does not compile into a binary. The core needs a POSIX sh, a POSIX awk, and a fairly normal Unix userland:
tar find sort sed grep comm cmp cp mv rm mkdir ls mktempA SHA-256 tool is also required. sha256sum, sha256, shasum, and openssl are supported where available.
git is required only when a git repository is configured. Local dir repositories can be indexed without it.
Compression support depends on the package or source being used. Install gzip, xz, or zstd if you want those formats. Remote HTTP or HTTPS sources need curl or wget when building.
Test it
make checkThe tests use temporary roots. They cover repository selection, dependency ordering, package creation, install and removal, upgrades, file ownership, protected configuration files, hooks, package compression, the installed layout, locks, architecture checks, and hostile archive/database cases.
Install it
For packaging into a staging root:
make DESTDIR="$pkgdir" PREFIX=/usr install
make DESTDIR="$pkgdir" install-configFor a direct system install:
sudo make PREFIX=/usr install
sudo make install-configinstall-config leaves existing sps.conf and repos.conf alone. A distribution can skip it and ship its own configuration instead.
Set up repositories
Official repositories are ordinary Git checkouts managed by src. Local administrator trees use the same recipe format and need no transport layer. Put this in /etc/sps/repos.conf:
dir local /usr/local/src/sps-local 200
git core https://github.com/RobertFlexx/sps-core.git 100
git extra https://github.com/RobertFlexx/sps-extra.git 80
# Community recipes are not enabled by default.
# git community https://github.com/RobertFlexx/sps-community.git 50setup, mkiso, and install-config enable core and extra only. A third collection, sps-community, is opt-in. Uncomment that git line, or add it yourself:
git community https://github.com/RobertFlexx/sps-community.git 50Then synchronize Git checkouts and build the local index:
src update
src search shell
sget info bashGit repositories are cloned below /usr/src/sps by default, so the example uses /usr/src/sps/core and /usr/src/sps/extra. src update fetches and fast-forwards clean tracking branches, but never resets, cleans, or overwrites a checkout with local changes. The checkouts remain normal Git repositories; git status, git log, and git diff work as usual. A dir repository is never synchronized by SPS.
Normal use
The high-level interface is sget:
sget install neovim
sget upgrade --plan
sget upgrade
sget depends firefox
sget dependees openssl
sget why firefox libxml2
sget remove neovimsget install prints each package as it begins, then leaves mkpkg and the upstream build attached to the terminal. An exact cached archive is reused instead of rebuilding.
The lower-level tools are always available:
mkpkg /usr/local/src/sps-local/base/foo/recipe
pkin foo-1.0-1-x86_64.pkg.tar.zst
pkstat foo
pkcheck foo
pkdel fooThis is useful for recovery work, distro installers, package development, and cases where the administrator wants to bypass dependency policy on purpose.
Install SPS Linux (Splux)
setup is the SPS Linux installer, not a generic SPS or LFS installer. It uses dialog screens, or the same choices from flags for scripts:
setup
setup --plan --profile plasma-desktop --target /mnt --user alex
setup --non-interactive --profile minimal --target /mnt --hostname darkstarProfiles are minimal, server, plasma-desktop, and plasma-full. Optional sets cover CLI tools, development, languages, KDE apps, NVIDIA, Flatpak, power management, multimedia, printing, browsers, extra shells, fonts, office tools, SSH, and more. setup --list-sets prints them. There is also an extra-package checklist (--extra) plus locale and login-shell screens.
The installer writes hostname, timezone, keymap, and a first user into the target, indexes the bundled live recipe trees in place (when present), runs src update, and sget install. The installed system is registered with the official sps-core/sps-extra Git repositories, so it keeps receiving recipe updates after install; only the install-time indexing uses the live bundles. Guided partitioning is optional and waits until the last confirmation. Choose systemd, OpenRC, s6, runit, dinit, Shepherd, or SysV as PID 1 (--init); those packages conflict. grub-install still needs --install-bootloader and --disk.
SPS Linux live ISO
mkiso writes a hybrid ISO for SPS Linux (Splux). Flash it to USB, boot to a console, mount a destination filesystem on /mnt, and run setup. Ready-made images:
https://github.com/RobertFlexx/SPS/releases/tag/live-2026-09-06-1
mkiso --output dist/sps-live.iso --init systemd \
--busybox /path/to/busybox \
--core /usr/src/sps/core \
--extra /usr/src/sps/extra
make iso
make iso-slim
make iso-plasmaLive PID 1 is systemd when the build host has it, otherwise busybox init with gettys on tty1 and ttyS0. The earlier live TTY image exec'd a shell as PID 1 and panicked in QEMU (Attempted to kill init, exit 127) when that shell exited. --session plasma copies a host Plasma/Wayland stack; NVIDIA live graphics go through nouveau.
--layout DIR writes the live root without making an ISO. --no-seed skips copying the host compiler. --with-firmware copies /lib/firmware (large; published images omit it). The live image never runs grub-install on a disk.
Download a ready-made hybrid ISO from this repository's GitHub Releases, flash it to USB, boot the "SPS Linux live (Splux)" entry, mount a destination filesystem on /mnt, and run setup. The image includes the installer, sps-core and sps-extra recipes, and a host seed compiler so setup can build packages. A full Plasma install compiles Qt and KDE from source and takes a long time.
# flash (example)
dd if=sps-live.iso of=/dev/sdX bs=4M status=progress conv=fsyncAlternate roots
SPS_ROOT points SPS at another filesystem tree. Database, cache, and build paths are rooted below it unless you override those paths separately.
For example:
SPS_ROOT=/mnt/root pkin base-1.0-1-x86_64.pkg.tar.zstThat makes SPS usable from an installer or rescue system without needing a special package-install mode.
Upgrades and configuration files
By default, regular files below etc are protected when an administrator has changed them locally. During an upgrade SPS keeps the local file. If the new package also changed its copy, the new one is written beside it as .sps-new (or a versioned .sps-new name if necessary).
SPS never attempts to merge the two files automatically.
To review what a round of upgrades left for you, run:
sget config-status # list protected files that changed locally
sget config-status openssl # limit the list to one package
sget config-status --raw # tab-separated records for scripts
sget config-status --diff /etc/ssl/openssl.cnf # unified diff vs the new defaultconfig-status is read-only. It reports the local file, its installed package, and whether an upgrade wrote a packaged default beside it as .sps-new, so you can merge by hand before the next upgrade. pkcheck --modified remains the low-level way to see every locally-changed owned file.
To act on what it found, run pkconf:
pkconf # review each pending default, one at a time
pkconf --list # what is waiting, without changing anything
pkconf --diff /etc/ssl/openssl.cnf
pkconf --accept /etc/ssl/openssl.cnf # take the packaged default
pkconf --keep /etc/ssl/openssl.cnf # keep yours, drop the .sps-new
pkconf --keep-all # after a big upgrade, keep every local fileThe interactive review offers diff, take-the-new-file, keep-mine, and an e key that opens a scratch copy in $EDITOR so you can merge the two by hand. This is the same job CRUX gives rejmerge and Gentoo gives etc-update; SPS keeps it in a separate command rather than folding it into the upgrade, so an upgrade never blocks waiting for an answer.
Taking the packaged default restores the file to the digest pkin recorded, so pkcheck reports the package clean again. Keeping your file leaves the path locally modified, which is the truth and is what the next upgrade will respect.
pkin is still a direct installer. sget upgrade starts from the explicit world set, resolves that dependency closure, and upgrades it in dependency order. A locally newer version is kept unless --downgrade is requested.
Hooks
A recipe may ship these files in a hooks/ directory:
pre-install
post-install
pre-remove
post-removeThey are copied into the package and can be inspected before installation. Hooks run with /bin/sh -eu. There is no generic plugin loader or background trigger service.
Use hooks sparingly. Most packages should just install files.
Files and state
The defaults are:
/etc/sps/ configuration
/var/lib/sps/ installed records, ownership, world, history
/var/cache/sps/ sources, repository indexes, built packages
/var/tmp/sps/ build and staging directoriesPackage state is text. Binary packages are tar archives, optionally compressed with gzip, xz, or zstd.
Nothing in SPS needs a daemon or a database server, and no command refreshes a repository in the background. If you do not run a state-changing command, SPS does not change the system. Its intentionally minimal ;)