Skip to main content

Package buildsystem

active

How I build and publish my personal slackware64-current package repository.

My personal Slackware packages for slackware64-current are built by a small pipeline of tools running inside one dedicated QEMU virtual machine. Nothing here is a single program: it is a repository that gets reassembled, a dependency layer that gets patched, a builder that turns SlackBuilds into packages, and a publishing step that puts them online at packages.danix.xyz. This page walks the whole flow in the order a build actually happens.

Flowchart of the package buildsystem: assemble the repo with slackrepo_setup, fix -current dependencies with mkhint, build with slackrepo, and publish through the finish hooks, with a separate green side path for testing on Slackware 15.0 stable before submitting to SBo.
The pipeline end to end. The green side path is the 15.0 stable test, run only for packages headed to SlackBuilds.org.

The VM

The buildsystem lives in a QEMU virtual machine running slackware64-current, kept up to date with slackpkg against a local mirror of Slackware’s own system packages. It has 8 CPU cores and around 8 GB of RAM, enough to build all but the heaviest packages comfortably, and I reach it over SSH. Keeping it in its own VM means a build, a broken dependency, or a full repository regeneration never touches my daily driver: the box exists to be hammered and, if needed, thrown away and rebuilt.

Assembling the repository

Once a week the SlackBuilds tree is regenerated from scratch. It starts as a clone of Ponce’s slackbuilds checked out on the current branch, the community tree that tracks SlackBuilds.org against slackware-current. On top of that I overlay my own two collections as squashed git subtrees: my-slackbuilds for general personal packages and Slackware-Pentesting-Suite for security tooling.

Where a personal package shares a name with an upstream one, the upstream copy is shadowed: its directory is removed so my version wins. The result is a single local tree that is standard SBo plus my additions, ready to build. That whole assembly is one script, which will get its own page here later.

The -current dependency problem

SBo SlackBuilds target Slackware stable, so some of their build-time dependencies are unnecessary on -current, which already ships them as system packages or newer versions. rust-opt and google-go-lang are typical: needed on stable, pointless on -current. These “phantom” dependencies would otherwise force needless rebuilds.

slackrepo strips a dependency from a package with a per-package hint file carrying DELREQUIRES, but writing one by hand for every affected package after each weekly regeneration is exactly the tedium a script should own. That job belongs to mkhint: its -F sweep reads a list of phantom deps and, for every package whose requirements hit one, writes or merges the right DELREQUIRES across the freshly rebuilt tree in a single pass.

Curious how the phantom-dep sweep actually works? The whole thing is one Bash script.

Read the mkhint source

Building

The actual building is done by slackrepo, an automated SlackBuild builder for Slackware, now maintained by Andrew Clemons. It compiles each package and its dependencies in a clean chroot, tracks upstream git revisions to work out what has changed and needs rebuilding, and produces a repository that plugs straight into slackpkg+. I run it with a start hook that first rebases my SlackBuilds tree onto upstream, so every build starts from a current tree, and it handles the dependency ordering so a single command rebuilds everything that moved.

Publishing

When a build finishes, a chain of slackrepo finish hooks takes over. They regenerate the slackpkg+ repository metadata, build the styled HTML frontend for the package site, sync the result out to the live server, and send a notification that the run is done. The frontend wraps Apache’s plain directory autoindex in a themed header and footer so packages.danix.xyz reads as a proper repository rather than a bare file listing. That frontend is its own small project and will get a page here later too.

It is mostly a shell hook that walks the package tree and writes the header and footer HTML. Have a look under the hood.

See the frontend generator

Testing against 15.0 stable

Some of the packages I write are meant to be submitted upstream to SlackBuilds.org, which targets Slackware stable, not -current. Since my whole buildsystem is -current, a package building fine here proves nothing about 15.0. Before I submit one, I test it with a separate, independent tool built for exactly that: it resolves the SlackBuild’s dependency tree locally, then builds and installs every package in a fresh disposable overlay chroot layered over a clean, read-only Slackware 15.0 base. That catches the current-versus-15.0 drift a -current build hides.

It does not touch or drive slackrepo, and its built packages are throwaway: the only question it answers is “does this still build clean on 15.0”. One limit worth naming: it shares the host kernel, so packages that build kernel modules still want a real 15.0 VM. This tool will also get its own page here in time.

The overlay-chroot and dependency-resolution logic live here if you want to read how the 15.0 test is built.

Browse sbo-batch-tester

The weekly rhythm

Put together, the week is one repeatable cycle: regenerate the SlackBuilds tree, sweep the phantom-dependency hints with mkhint -F, build and publish with slackrepo and its hooks, and, for anything headed to SlackBuilds.org, spot-test it against a clean 15.0 base first. Four small tools, each doing one job well, and a disposable VM to run them in. Very Slackware.

I hope you found this walk through my buildsystem interesting. If you end up running something similar, or you have questions, ideas, or suggestions about any piece of it, drop me a line and I will gladly get in touch.

See you next time.

Everything the buildsystem produces lands here. If you run slackware64-current, you can point slackpkg+ at it and pull my packages straight in.

Browse the package repository