Zainium Dynamics
Docs / Developers

Building packages

Write a recipe — ZEXBUILD and manifest.toml — and let CI build and publish the package.

Zainium packages are built from recipes. A recipe is a directory with a ZEXBUILD (a POSIX shell script, like an Alpine APKBUILD) and a manifest.toml. CI builds it in a container against the Zainium musl toolchain, checks every program's loader, packs it with substrate and publishes it to archive.zainiumdynamics.tech.

RepositoryHolds
userland-recipescommunity packages for the userland
syshub-recipesthe base system

Adding a package

  1. Fork userland-recipes.
  2. Create <pkgname>/ZEXBUILD and <pkgname>/manifest.toml (see htop/ for a complete example).
  3. Put any *.patch files next to ZEXBUILD and apply them inside it.
  4. Open a pull request. CI runs a build-only check.
  5. After the merge, CI builds and publishes the package, and zex install can fetch it.

ZEXBUILD

maintainer="Your Name <you@example.com>"
pkgname=htop
pkgver=3.5.2
pkgrel=0
source="https://github.com/htop-dev/htop/releases/download/$pkgver/htop-$pkgver.tar.xz"
sha256sums="<hash>  htop-$pkgver.tar.xz"

build() {
    ./configure \
        --host="$CHOST" \
        --prefix=/overlayer/syshub \
        --sysconfdir=/overlayer/syshub/etc \
        --localstatedir=/overlayer/syshub/var
    make
}

package() {
    make DESTDIR="$PAYLOAD_DIR" install
}
VariableMeaning
pkgname, pkgver, pkgrelname (must match manifest.toml), upstream version, recipe revision
source, sha256sumswhat to fetch and its checksums
$CHOSTtarget triplet, x86_64-zainium-linux-musl
$PAYLOAD_DIRstaging directory of the package
subpackagesoptional -dev split, with a dev() function and its own manifest

Install prefix

Always build with --prefix=/overlayer/syshub, even for userland packages: /overlayer/syshub is the merged view of the base and the userland, so it is the only path a running program sees. The _syshub = false flag in manifest.toml decides which layer the files are written to.

substrate pack sets every binary's interpreter to the musl loader and its library path to /overlayer/syshub/lib, so recipes normally do nothing. Rust packages build against the custom x86_64-zainium-linux-musl target in the repository.

All documentation