Skip to content

Package Management Policy

glaucus uses the filesystem tree as its database to store package information and build scripts.

Anatomy of a Package

info file

  • An info file is a TOML file that stores package information (aka metadata)
  • info files are also valid POSIX shell scripts due to the way they are written; can be sourced by .
  • To create a new package, create a directory with the package name under a cluster of yours, then create an info file inside that directory with the mandatory variable nom inside; nom should be equal to the package directory’s name
  • The following is a list of all the variables supported by info files:
    • nom: package name, mandatory
      • Do not put version numbers in nom
    • ver: package version number, or commit number if url is a git repository
    • url: package source url
      • Prefer https over http and ftp
      • Order of tarball preference: .zst > .gz > .xz > .bz2
      • Prefer cdn mirrors when available:
        • GNU packages should use: https://ftpmirror.gnu.org/
        • Kernel packages should use: https://cdn.kernel.org/pub/linux/
        • Non GNU packages should use: https://download.savannah.nongnu.org/releases/
        • Packages from OpenBSD should use: https://cdn.openbsd.org/pub/OpenBSD/
    • sum: package checksum, only valid if the url is not a git repository
    • bld: package build time dependencies sorted alphabetically
      • Do not add common packages that are expected to exist at build time as build time dependencies (e.g. make, linux-headers and so on)
    • run: package run time dependencies sorted alphabetically
    • nop: package “no operation” and includes:
      • bootstrap: install package to /; only available in cross
      • check: do not run check(); must be provided for build without check()
      • doc, man: do not remove documentation
      • empty: do not remove empty directories
      • la, libtool: do not remove libtool archives (.la files) in native; they are deleted either ways in cross
      • lto: do not use LTO
      • parallel: use -j 1
      • purge, prune: do not remove unwanted files
      • static: do not remove static libraries (.a files)

build file

  • A build file is a POSIX shell script that includes the build instructions of a package
  • The build process of a package is split into 5 different phases:
    • Preparation: handled by the function prepare()
    • Configuration: handled by the function configure()
    • Compilation: handled by the function build()
    • Checking: handled by the function check()
    • Packaging: handled by the function package(), mandatory
  • Some packages include special versions of the build file called build-toolchain and build-cross; these are only intended to be run by developers when bootstrapping the toolchain and cross stages of glaucus

prepare() function

  • glaucus package manager rad automatically does a cd into $TMPD/$nom/$nom-$ver if the package’s url is not a git repository, and into $TMPD/$nom if it is a git repository
  • If extracting the source tarball provided by url does not follow the $nom-$ver rule then you are expected to manually cd into whatever the directory name is (e.g. for python we do a cd "$TMPD"/$nom/Python-$ver); do not interact with $SRCD, only $TMPD
  • If a package uses autotools, always run autoreconf -vfis to update its files
  • If the package provides an autogen.sh or a bootstrap.sh then prefer these over manually running autoreconf -vfis
  • This is done because updating config.guess, config.sub and config.rpath is usually not enough
  • Disable po4a generation and gtkdocize when running autoreconf -vfis, autogen.sh or bootstrap.sh
  • If a patch is absolutely necessary, then it is applied here in prepare(); otherwise, keep things vanilla
  • All patches should use -p 0
  • Avoid modifications and patches to documentation and manual pages as they render autoreconf harder; require more stuff
  • Double check if the package’s build system requires that it be built out-of-tree; if so then mkdir -p build and cd build

configure() function

  • glaucus provides wrappers for various build systems that come with the required installation paths and basic configuration options
  • Use glaucus-configure for autotools build system
  • Use glaucus-cmake for cmake build system
  • Use glaucus-muon for muon and meson build systems
  • For developers who are bootstrapping the toolchain and cross stages use full paths to glaucus-* in build-toolchain and build-cross respectively
  • Avoid substituting flag strings with variables like nom; e.g. pcre2 has a flag --enable-pcre2-32, do not type --enable-$nom-32
Disable
  • In glaucus, it is preferred to disable the following options:
    • assert
    • audit
    • dbus
    • debug
    • doc
    • examples
    • fuzzing
    • gettext
    • gtk-doc
    • i18n
    • iconv
    • idn
    • intltool
    • l10n
    • logind
    • man
    • nls
    • pam
    • polkit
    • rpath
    • selinux
    • static
    • symvers
    • systemd
    • tests
    • x11
    • year2038
Enable
  • It is also preferred to enable the following options:
    • acl
    • attr
    • ipv6
    • lto
    • pic
    • pie
    • pthreads
    • shared
    • threads=posix
    • tls
    • xattr

build() function

  • PassCFLAGS, CXXFLAGS and LDFLAGS as arguments to make and not as environment variables, so they are propagated correctly:
Terminal window
## Correct
make foo=bar
## Incorrect, might get unexported in the Makefile and not get passed to submakes
foo=bar make

check() function

  • Only relevant for native build recipes; will not be called in cross and toolchain stages (do not add a check() function in build-cross and build-toolchain)
  • Report packages without a test suite
  • Report failing tests
  • Try VERBOSE=1 V=1 for make check
  • Prefer make -k check to keep going until all tests are checked
  • If tests fail in parallel, try -j1
  • Compare failing tests with Alpine and LFS

package() function

  • package() is the only required function to declare build files
  • Do not install in: /bin, /boot, /dev,/home,/lib, /mnt, /proc, /root, /run, /sbin, /sys, /tmp, /usr/sbin
  • Everything related to s6 should reside under /etc/s6
  • All text files must end with a newline (POSIX)
  • Prefer strip targets install-strip to manually running strip
  • For developers, do not create fifo files when in cross stage as they can’t be copied
  • Consider removing the following files if unnecessary:
    • .a (static libraries whenever possible)
    • .alias
    • .bs (perl files)
    • .cmd (kernel files)
    • .dbg
    • .e2x (perl files)
    • .install (kernel files)
    • .la (libtool archives)
    • .packlist (perl files)
    • .pod (perl files)
    • .py (python files)
    • .pyc (python files) (ewe)
    • .pyo (python files) (ewe)
    • alias
    • application (kiss)
    • bash
    • charset
    • cmake
    • completion
    • consolekit (kiss)
    • dbus
    • doc (kiss)
    • extralibs (perl files)
    • fish
    • gdb (kiss)
    • gettext (kiss)
    • gtk-doc (kiss)
    • i18n
    • icon (kiss)
    • info (kiss)
    • intl (kiss)
    • locale
    • logind (kiss)
    • man (kiss)
    • pam
    • polkit (kiss)
    • pulse (kiss)
    • sound (kiss)
    • systemd
    • test (ewe)
    • zsh (kiss)

Misc

  • Avoid -e and -x in the shebang (vague behavior)
  • Do not store commands inside variables
  • Do not declare empty functions; if a function does nothing then it shoul not be declared
prepare() {
:
}
  • Brace expansion is not POSIX
  • Use mkdir -p over install -d
  • cp -a is not POSIX; use cp -fPp for files and cp -fPpR for directories
  • cp -v and mv -v are not POSIX; rm -v is POSIX though
  • ln -r and ln -n are not POSIX; use ln -fs instead
  • patch only accepts one diff/patch file at a time when using -i; if multiple files are provided it will use the last one
  • touch is faster than :>
  • command -v is faster than type
  • Group commands that deal with multiple arguments into one (e.g. cp, rm, mkdir (if same permissions)…)
  • Group commands that are repeated 3 or more times into for loops
  • Only quote shell variables with whitespace characters
  • Separate options that accept arguments from ones that do not; prefer this:
mkdir -m 555 -p

to this:

mkdir -pm 555
  • Use a single space character to separate arguments from their options; prefer this:
patch -p 0 ...

to this:

patch -p0 ...

Repository Layout

  • /var/cache/rad/pkg (built packages with contents)
  • /var/cache/rad/src (source tarballs, read-only, equals $SRCD)
  • /var/lib/rad/clusters/cerata (official cluster, equals $CERD)
  • /var/lib/rad/clusters/custom (custom cluster)
  • /var/lib/rad/clusters/fleet (community cluster)
  • /var/lib/rad/pkg (installed packages with contents)
  • /var/log/rad (log files, equals $LOGD)
  • /var/tmp/rad (temporary build artefacts)

References