Overview
- What is a Linux distribution
- How popular package managers work
- Introducing our package manager
- Internals
What is a Linux distribution
.
├── boot
├── dev
├── etc
│ ├── group
│ └── ...
├── home
├── proc
├── root
├── run
├── sys
├── tmp
├── usr
│ ├── bin
│ │ ├── awk
│ │ ├── ls
│ │ ├── sh
│ │ └── ...
│ ├── include
│ │ ├── stdio.h
│ │ ├── stdlib.h
│ │ └── ...
│ ├── lib
│ │ ├── crti.o
│ │ ├── libc.so
│ │ ├── libz.so
│ │ └── ...
│ ├── lib64 -> lib
│ └── share
│ └── ...
└── var
├── cache
└── ...
Filesystem Hierarchy
Building Packages
$ tar xf zlib-1.3.1.tar.gz
$ cd zlib-1.3.1; ls
CMakeLists.txt README crc32.h gzlib.c inflate.c old uncompr.c zlib.3.pdf
ChangeLog adler32.c deflate.c gzread.c inflate.h os400 watcom zlib.h
FAQ amiga deflate.h gzwrite.c inftrees.c qnx win32 zlib.map
INDEX compress.c doc infback.c inftrees.h test zconf.h zlib.pc.cmakein
LICENSE configure examples inffast.c make_vms.com treebuild.xml zconf.h.cmakein zlib.pc.in
Makefile contrib gzclose.c inffast.h msdos trees.c zconf.h.in zutil.c
Makefile.in crc32.c gzguts.h inffixed.h nintendods trees.h zlib.3 zutil.h
$ ./configure --prefix=/usr
Checking for gcc...
Checking for shared library support...
Building shared library libz.so.1.3.1 with gcc.
Checking for size_t... Yes.
...
Checking for attribute(visibility) support... Yes.
$ make
gcc -O2 -pipe -march=x86-64-v2 -mtune=generic -fno-math-errno -fstack-protector-strong --param ssp-buffer-size=4 -D_FORTIFY_SOURCE=3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o example.o test/example.c
...
$ make DESTDIR="/path/to/sysroot" install- Downloading source tarballs
- Configuring the build via autotools, meson, cmake, etc.
- Building & Installing
How popular package managers work
Pacman (Arch Linux)
- Uses bash-based PKGBUILD scripts for building packages
- Supports installing binary packages from repositories in addition to source-based builds (AUR)

PKGBUILD example
pkgname=make
pkgver=4.4.1
pkgrel=2
pkgdesc="GNU make utility to maintain groups of programs"
arch=('x86_64')
url="https://www.gnu.org/software/make"
license=('GPL3')
depends=('glibc' 'guile')
source=("https://ftp.gnu.org/gnu/${pkgname}/${pkgname}-${pkgver}.tar.lz"{,.sig})
sha256sums=('8814ba072182b605d156d7589c19a43b89fc58ea479b9355146160946f8cf6e9'
'SKIP')
validpgpkeys=('6D4EEB02AD834703510B117680CB727A20C79BB2') # Paul Smith
build() {
cd "${pkgname}-${pkgver}"
./configure --prefix=/usr
make
}
check() {
cd "${pkgname}-${pkgver}"
make -k check
}
package() {
cd "${pkgname}-${pkgver}"
make DESTDIR="${pkgdir}" install
}
$ makepkg
==> Making package: make 4.4.1-2 (Fri 14 Nov 2025 09:00:09 AM UTC)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
-> Downloading make-4.4.1.tar.lz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1275k 100 1275k 0 0 491547 0 0:00:02 0:00:02 --:--:-- 491584
==> Validating source files with sha256sums...
make-4.4.1.tar.lz ... Passed
==> Extracting sources...
-> Extracting make-4.4.1.tar.lz with bsdtar
==> Starting build()...
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...
gcc -I/usr/include/guile/3.0 -I/usr -march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security -fstack-clash-protection -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -g -ffile-prefix-map=/home/testuser/make/src=/usr/src/debug/make -flto=auto -Wl,--export-dynamic -Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now -Wl,-z,pack-relative-relocs -flto=auto -o make src/ar.o src/arscan.o src/commands.o src/default.o src/dir.o src/expand.o src/file.o src/function.o src/getopt.o src/getopt1.o src/guile.o src/hash.o src/implicit.o src/job.o src/load.o src/loadapi.o src/main.o src/misc.o src/output.o src/read.o src/remake.o src/rule.o src/shuffle.o src/signame.o src/strcache.o src/variable.o src/version.o src/vpath.o src/posixos.o src/remote-stub.o -lguile-3.0 -lgc -lpthread -ldl lib/libgnu.a
make[1]: Leaving directory '/home/testuser/make/src/make-4.4.1'
==> Entering fakeroot environment...
==> Starting package()...
Making install in lib
...
make[2]: Entering directory '/home/testuser/make/src/make-4.4.1'
/usr/bin/mkdir -p '/home/testuser/make/pkg/make/usr/include'
/usr/bin/mkdir -p '/home/testuser/make/pkg/make/usr/share/man/man1'
/usr/bin/mkdir -p '/home/testuser/make/pkg/make/usr/bin'
/usr/bin/install -c -m 644 src/gnumake.h '/home/testuser/make/pkg/make/usr/include'
/usr/bin/install -c -m 644 doc/make.1 '/home/testuser/make/pkg/make/usr/share/man/man1'
/usr/bin/install -c make '/home/testuser/make/pkg/make/usr/bin'
make[2]: Leaving directory '/home/testuser/make/src/make-4.4.1'
make[1]: Leaving directory '/home/testuser/make/src/make-4.4.1'
==> Tidying install...
-> Removing libtool files...
-> Purging unwanted files...
-> Removing static library files...
-> Stripping unneeded symbols from binaries and libraries...
-> Compressing man and info pages...
==> Checking for packaging issues...
==> Creating package "make"...
-> Generating .PKGINFO file...
-> Generating .BUILDINFO file...
-> Generating .MTREE file...
-> Compressing package...
==> Creating package "make-debug"...
-> Generating .PKGINFO file...
-> Generating .BUILDINFO file...
-> Generating .MTREE file...
-> Compressing package...
==> Leaving fakeroot environment.
==> Finished making: make 4.4.1-2 (Fri 14 Nov 2025 09:02:05 AM UTC)$ pushd extracted; tar xf ../make-4.4.1-2-x86_64.pkg.tar.zst; tree -a -L 3
.
├── .BUILDINFO
├── .MTREE
├── .PKGINFO
└── usr
├── bin
│ └── make
├── include
│ └── gnumake.h
└── share
├── info
├── locale
└── man
$ cd /var/lib/pacman/local/make-4.4.1-2; ls
desc files mtree
$ cat files
%FILES%
usr/
usr/bin/
usr/bin/make
usr/include/
usr/include/gnumake.h
usr/share/
usr/share/info/
usr/share/info/make.info-1.gz
usr/share/info/make.info-2.gz
usr/share/info/make.info-3.gz
usr/share/info/make.info.gz
usr/share/locale/
usr/share/locale/be/
usr/share/locale/be/LC_MESSAGES/
usr/share/locale/be/LC_MESSAGES/make.mo
usr/share/locale/bg/
usr/share/locale/bg/LC_MESSAGES/
usr/share/locale/bg/LC_MESSAGES/make.mo
usr/share/locale/cs/
usr/share/locale/cs/LC_MESSAGES/
usr/share/locale/cs/LC_MESSAGES/make.mo
usr/share/locale/da/
usr/share/locale/da/LC_MESSAGES/
usr/share/locale/da/LC_MESSAGES/make.mo
usr/share/locale/de/
usr/share/locale/de/LC_MESSAGES/
usr/share/locale/de/LC_MESSAGES/make.mo
usr/share/locale/es/
usr/share/locale/es/LC_MESSAGES/
usr/share/locale/es/LC_MESSAGES/make.mo
usr/share/locale/fi/
usr/share/locale/fi/LC_MESSAGES/
usr/share/locale/fi/LC_MESSAGES/make.mo
usr/share/locale/fr/
usr/share/locale/fr/LC_MESSAGES/
usr/share/locale/fr/LC_MESSAGES/make.mo
usr/share/locale/ga/
usr/share/locale/ga/LC_MESSAGES/
usr/share/locale/ga/LC_MESSAGES/make.mo
usr/share/locale/gl/
usr/share/locale/gl/LC_MESSAGES/
usr/share/locale/gl/LC_MESSAGES/make.mo
usr/share/locale/he/
usr/share/locale/he/LC_MESSAGES/
usr/share/locale/he/LC_MESSAGES/make.mo
usr/share/locale/hr/
usr/share/locale/hr/LC_MESSAGES/
usr/share/locale/hr/LC_MESSAGES/make.mo
usr/share/locale/id/
usr/share/locale/id/LC_MESSAGES/
usr/share/locale/id/LC_MESSAGES/make.mo
usr/share/locale/it/
usr/share/locale/it/LC_MESSAGES/
usr/share/locale/it/LC_MESSAGES/make.mo
usr/share/locale/ja/
usr/share/locale/ja/LC_MESSAGES/
usr/share/locale/ja/LC_MESSAGES/make.mo
usr/share/locale/ko/
usr/share/locale/ko/LC_MESSAGES/
usr/share/locale/ko/LC_MESSAGES/make.mo
usr/share/locale/lt/
usr/share/locale/lt/LC_MESSAGES/
usr/share/locale/lt/LC_MESSAGES/make.mo
usr/share/locale/nl/
usr/share/locale/nl/LC_MESSAGES/
usr/share/locale/nl/LC_MESSAGES/make.mo
usr/share/locale/pl/
usr/share/locale/pl/LC_MESSAGES/
usr/share/locale/pl/LC_MESSAGES/make.mo
usr/share/locale/pt/
usr/share/locale/pt/LC_MESSAGES/
usr/share/locale/pt/LC_MESSAGES/make.mo
usr/share/locale/pt_BR/
usr/share/locale/pt_BR/LC_MESSAGES/
usr/share/locale/pt_BR/LC_MESSAGES/make.mo
usr/share/locale/ro/
usr/share/locale/ro/LC_MESSAGES/
usr/share/locale/ro/LC_MESSAGES/make.mo
usr/share/locale/ru/
usr/share/locale/ru/LC_MESSAGES/
usr/share/locale/ru/LC_MESSAGES/make.mo
usr/share/locale/sr/
usr/share/locale/sr/LC_MESSAGES/
usr/share/locale/sr/LC_MESSAGES/make.mo
usr/share/locale/sv/
usr/share/locale/sv/LC_MESSAGES/
usr/share/locale/sv/LC_MESSAGES/make.mo
usr/share/locale/tr/
usr/share/locale/tr/LC_MESSAGES/
usr/share/locale/tr/LC_MESSAGES/make.mo
usr/share/locale/uk/
usr/share/locale/uk/LC_MESSAGES/
usr/share/locale/uk/LC_MESSAGES/make.mo
usr/share/locale/vi/
usr/share/locale/vi/LC_MESSAGES/
usr/share/locale/vi/LC_MESSAGES/make.mo
usr/share/locale/zh_CN/
usr/share/locale/zh_CN/LC_MESSAGES/
usr/share/locale/zh_CN/LC_MESSAGES/make.mo
usr/share/locale/zh_TW/
usr/share/locale/zh_TW/LC_MESSAGES/
usr/share/locale/zh_TW/LC_MESSAGES/make.mo
usr/share/man/
usr/share/man/man1/
usr/share/man/man1/make.1.gzIntroducing our package manager
- Entirely source-based
- Repositories are just directories on the local filesystem - synced via git (or any other mechanism)
- Packages are described by multiple files under a directory
repo/
├── core
│ ├── ...
│ ├── pigz
│ │ ├── build
│ │ ├── checksums
│ │ ├── depends
│ │ ├── post-install
│ │ ├── sources
│ │ └── version
│ └── zlib
│ ├── build
│ ├── checksums
│ ├── sources
│ └── version
├── extra
│ ├── ...
│ └── zstd
│ ├── build
│ ├── checksums
│ ├── sources
│ └── version
└── ...$ ls
build checksums depends post-install sources version
$ cat build git
#!/bin/sh -ef
#
# Intentional, globbing disabled.
# shellcheck disable=2086
for f in pigz.o yarn.o try.o; do
echo "$CC" -c -o "$f" "${f%%.o}.c" $CPPFLAGS -DNOZOPFLI $CFLAGS
"$CC" -c -o "$f" "${f%%.o}.c" $CPPFLAGS -DNOZOPFLI $CFLAGS
done
echo "$CC" -static -o pigz pigz.o yarn.o try.o $CPPFLAGS $CFLAGS -lz $LDFLAGS
"$CC" -static -o pigz pigz.o yarn.o try.o $CPPFLAGS $CFLAGS -lz $LDFLAGS
mkdir -p \
"$1/usr/bin" \
"$1/usr/share/man/man1"
cp -f pigz "$1/usr/bin"
ln -sf pigz "$1/usr/bin/gzip"
cp -f pigz.1 "$1/usr/share/man/man1"
ln -sf pigz.1 "$1/usr/share/man/man1/gzip.1"
$ cat checksums git
fa165f414a12851806d9d54920879dd989917b9aa410aec671c602b18773b23638
$ cat sources git
https://zlib.net/pigz/pigz-2.8.tar.gz
$ cat depends git
zlib make
$ cat version git
2.8 1Metadata Overview
Build & Installation
# kiss_ng build
[DEBUG] looking up dependency zlib of pigz
[INFO] fetching remote file https://zlib.net/pigz/pigz-2.8.tar.gz
0 MB 0.07 MB/s 00:01 [####################################################################################################################################################################################] 100%
[INFO] found remote file pigz-2.8.tar.gz
[INFO] checksum matched fa165f414a12851806d9d54920879dd989917b9aa410aec671c602b18773b23638 pigz-2.8.tar.gz
[INFO] found remote file zlib-1.3.1.tar.gz
[INFO] checksum matched 207c3b0862cb4e3686f8405f76a98c38dbad9c94bcf4be4b9efca0716aba51ecbb zlib-1.3.1.tar.gz
[INFO] (1/1) will build package (explicit) pigz
[INFO] (1/1) building package pigz
[INFO] handling remote source pigz-2.8.tar.gz
cc -c -o pigz.o pigz.c -DNOZOPFLI
cc -c -o yarn.o yarn.c -DNOZOPFLI
cc -c -o try.o try.c -DNOZOPFLI
cc -static -o pigz pigz.o yarn.o try.o -lz
[INFO] inspecting ELF /var/cache/kiss/proc/1311/pkg/usr/bin/pigz of type elf.ET.EXEC
[INFO] successfully built pigz
# kiss_ng install git@main
[INFO] acquiring lock file at /var/cache/kiss/lock...
[INFO] acquired lock file
[INFO] extracting pigz@2.8-1.tar.zst
[INFO] checking for conflicts
[INFO] removing system package
[INFO] successfully executed hook at /var/db/kiss/installed/pigz/post-install in /
$ ls /var/db/kiss/installed/pigz
build checksums depends manifest post-install sources version
$ cat /var/db/kiss/installed/pigz/manifest
/var/db/kiss/installed/pigz/version
/var/db/kiss/installed/pigz/sources
/var/db/kiss/installed/pigz/post-install
/var/db/kiss/installed/pigz/manifest
/var/db/kiss/installed/pigz/depends
/var/db/kiss/installed/pigz/checksums
/var/db/kiss/installed/pigz/build
/var/db/kiss/installed/pigz/README
/var/db/kiss/installed/pigz/
/var/db/kiss/installed/
/var/db/kiss/
/var/db/
/var/
/usr/share/man/man1/pigz.1
/usr/share/man/man1/gzip.1
/usr/share/man/man1/
/usr/share/man/
/usr/share/
/usr/bin/pigz
/usr/bin/gzip
/usr/bin/
/usr/Internals
Building Packages
- Compute build order of packages
- Download & cache source tarballs
- Verify source checksums
- Extract the sources in a temp. directory and execute the build scripts
- Compress the installed files into a package (tar file)
Build Order Computation
$ cat rust/depends
cmake make
curl make
llvm
openssl
pkgconf make
python make
xz
zlib$ cat cmake/depends
bzip2
curl
expat
linux-headers make
zlib$ cat llvm/depends
cmake make
python make
zlib
zstd$ cat python/depends
bzip2
expat
libffi
ncurses
openssl
sqlite
zlib$ cat curl/depends
openssl
zlib$ cat sqlite/depends
zlib[INFO] (1/16) will build package (implicit) bzip2
[INFO] (2/16) will build package (implicit) certs
[INFO] (3/16) will build package (implicit) openssl
[INFO] (4/16) will build package (implicit) zlib
[INFO] (5/16) will build package (implicit) curl
[INFO] (6/16) will build package (implicit) expat
[INFO] (7/16) will build package (implicit) linux-headers
[INFO] (8/16) will build package (implicit) cmake
[INFO] (9/16) will build package (implicit) libffi
[INFO] (10/16) will build package (implicit) ncurses
[INFO] (11/16) will build package (implicit) sqlite
[INFO] (12/16) will build package (implicit) python
[INFO] (13/16) will build package (implicit) llvm
[INFO] (14/16) will build package (implicit) pkgconf
[INFO] (15/16) will build package (implicit) xz
[INFO] (16/16) will build package (explicit) rustBuild Environment
$ pwd
/var/cache/kiss/proc/1789
$ ls
build pkg script sysroot
$ ls build
CMakeLists.txt adler32.o crc32.lo example64.o gzread.c inffast.h inftrees.lo minigzip64.o trees.h zconf.h.in zutil.lo
ChangeLog amiga crc32.o examples gzread.lo inffast.lo inftrees.o minigzipsh trees.lo zlib.3 zutil.o
...
$ tree -L 3 pkg
pkg
├── usr
│ ├── include
│ │ ├── zconf.h
│ │ └── zlib.h
│ ├── lib
│ │ ├── libz.a
│ │ ├── libz.so -> libz.so.1.3.1
│ │ ├── libz.so.1 -> libz.so.1.3.1
│ │ ├── libz.so.1.3.1
│ │ └── pkgconfig
│ └── share
│ └── man
└── var
└── db
└── kiss- Source files extracted & built in
build - Built artifacts installed to
pkg - Enumerate all installed files and write to a
manifestfile
Sandboxing
- All builds are run as root
- Process is only granted read-only permissions to the filesystem using the Landlock API
- A temporary rootfs (
sysroot) is created that only contains relevant files for the build which is executed underchroot
$ ls sysroot
bin boot dev etc home lib lib64 mnt opt proc root run sbin sys tmp usr var
$ ls sysroot/var/db/kiss/installed
baselayout bzip2 gcc gnugrep linux-headers musl xz
binutils file git libmpc make ncurses zlib
busybox flex gmp libseccomp mpfr util-linux zstd
$ ls -i sysroot/usr/bin/gcc
891411 sysroot/usr/bin/gcc
$ ls -i /usr/bin/gcc
891411 /usr/bin/gcc+---------------------------------------+
| landlock_create_ruleset() |
+---------------------------------------+
|
v
+---------------------------------------+
| landlock_add_rule("/", READ_ONLY); | // Read-only access to the whole filesystem
+---------------------------------------+
|
v
+---------------------------------------------------+
| landlock_add_rule("/var/cache/kiss", READ_WRITE); | // Read-write access for the build & packaging directory
+---------------------------------------------------+
|
v
+---------------------------------------+
| unshare(CLONE_NEWNS); | // Unshare a new mount namespace for the sysroot
+---------------------------------------+
|
v
+-----------------------------------------------------------+
| mount("/var/cache/kiss/proc/<PID>", | // Bind mount relevant directories like the build directory
| "sysroot/var/cache/kiss/proc/<PID>", MS_BIND); | // and /dev, /proc, etc.
+-----------------------------------------------------------+
|
v
+------------------------------------------------+
| linkat("/usr/bin/gcc", "sysroot/usr/bin/gcc"); | // Enumerate all files provided by symlinks and hardlink them into the sysroot
+------------------------------------------------+
|
v
+---------------------------------------+
| chroot("sysroot"); | // Chroot into the sysroot directory
+---------------------------------------+
|
v
+-----------------------------------------------------------+
| execve("/var/cache/kiss/proc/<PID>/script"); | // Execute the build step
+-----------------------------------------------------------+
deck
By git-bruh
deck
- 11