/ports/*/\:
#!/bin/mkpkg
# description: one-line summary
# url: upstream homepage
name=example
version=1.0
release=1
depends=(foo bar)
makedeps=(baz)
source=(https://example.com/$name-$version.tar.gz)
sha256sums=(abc123...)
build() {
cd $name-$version
./configure --prefix=/
make
make DESTDIR=$PKG install
}
signify() {
untrusted comment: opentux.pub
RWQ8ABCD1234...base64...==
}
# vim: filetype=sh
nameversionrelease_branch=stable _commit=abc1234
makedeps
are only needed during build and can be auto-removed.
depends=(openssl curl) makedeps=(cmake ninja)
source=(https://example.com/$name-$version.tar.gz fix-build.patch)Local files (no path separator) are looked up relative to the port directory.
N
in renames applies to entryN
in source. Use empty strings orSKIP
to leave entries unchanged.
source=(https://example.com/archive/v$version.tar.gz) renames=($name-$version.tar.gz)
SKIP
for entries that should not be verified.
sha256sums=(a1b2c3d4... SKIP)
groups=(groupname)Extended format — create a group, system user, and home directory:
groups=(groupname:user:username:homedir:mode)The second field must be the literal word user . Example:
groups=(dhcpcd:user:dhcpcd:/var/lib/dhcpcd:700)This runs:
groupadd -r dhcpcd useradd -r -s /bin/false -d /var/lib/dhcpcd -g dhcpcd dhcpcd install -d -m 700 -o dhcpcd -g dhcpcd /var/lib/dhcpcdOn pkg.del(8), the user and group are removed if no other installed package declares the same group.
/etc/sv
is a regular package file shipped by build() or post_build() .services=(nftables)
/path:owner:group:modeExample:
permissions=( /sbin/wpa_supplicant:root:wpa_supplicant:750 /sbin/wpa_cli:root:wpa_supplicant:750 /etc/wpa_supplicant.conf:root:wpa_supplicant:640 )Paths are relative to the installation root. No undo is needed on removal — the files are deleted.
/path:capabilitiesExample:
capabilities=( /usr/bin/ping:cap_net_raw+ep /usr/bin/arping:cap_net_raw+ep )Capabilities are extended attributes and cannot survive in tar archives, which is why they are applied at install time rather than at build time. Paths are relative to the installation root. No undo is needed on removal — the files are deleted.
twice
if defined twice. The firstshell()
runs before download (setup phase); the second runs after
packaging (cleanup phase).
Both execute in the port directory.
Typical use: create temporary wrapper scripts for builds that
need them, then remove them afterward.
shell() {
ln -sf /bin/python3 $SRC/.local/bin/python
}
Both invocations source
/etc/mkpkg.conf .
mkpkg
skips auto-extraction of source archives.
Does
not
source mkpkg.conf.
extract() {
tar -xf $PKGMK_SOURCE_DIR/$name-$version.tar.gz -C $SRC
}
not
source mkpkg.conf.
patch() {
cd $name-$version
patch -p1 < $PKGMK_SOURCE_DIR/fix-musl.patch
}
build() {
cd $name-$version
./configure --prefix=/
make
make DESTDIR=$PKG install
}
post_build() {
cd $name-$version
install -d $PKG/etc/sv/$name/log
printf '%s\\n' \\
'#!/bin/sh' \\
'exec 2>&1' \\
"exec $name -f" \\
> $PKG/etc/sv/$name/run
printf '%s\\n' \\
'#!/bin/sh' \\
"mkdir -p /var/log/$name" \\
"exec svlogd -tt /var/log/$name" \\
> $PKG/etc/sv/$name/log/run
chmod 755 $PKG/etc/sv/$name/run
chmod 755 $PKG/etc/sv/$name/log/run
}
capabilities
arrays are defined,
mkpkg
writes a metadata file into the package at:
var/lib/pkg/meta/name
Format:
group dhcpcd:user:dhcpcd:/var/lib/dhcpcd:700 service dhcpcd permission /sbin/dhcpcd:root:dhcpcd:750 capability /usr/bin/ping:cap_net_raw+epThis file is read by pkg.add(8) and pkg.del(8) and is tracked as a regular package file.
not
a shell function — it is a data block containing two lines: the untrusted comment and the base64-encoded public key.
signify() {
untrusted comment: opentux.pub
RWQ8ABCD1234...base64...==
}
When verifying a port signature,
mkpkg
uses this embedded key instead of looking for external
.pub
files in /etc/ports/ . This makes each port self-verifying: the trust is per-port and transparent. Generate or update with:mkpkg -up # reads .pub matching MKPKG_SECRET_KEYDisplay with:
mkpkg -p # prints the embedded keyThe signify() block should be placed at the end of the file, just before the
# vim:
footer.
#!/bin/mkpkg
# description: Shows the full path of shell commands
# url: https://www.gnu.org/software/which/
name=which
version=2.21
release=1
depends=()
source=(https://ftp.gnu.org/gnu/$name/$name-$version.tar.gz)
build() {
cd $name-$version
./configure --prefix=/
make
make DESTDIR=$PKG install
}
signify() {
untrusted comment: opentux.pub
RWQ8...base64...==
}
# vim: filetype=sh
Package with privilege separation:
#!/bin/mkpkg
# description: DHCP client daemon
# url: https://github.com/NetworkConfiguration/dhcpcd
name=dhcpcd
version=10.2.2
release=1
depends=(openssl)
groups=(dhcpcd:user:dhcpcd:/var/lib/dhcpcd:700)
services=(dhcpcd)
permissions=(
/sbin/dhcpcd:root:dhcpcd:750
)
source=(https://github.com/NetworkConfiguration/$name/releases/download/v$version/$name-$version.tar.xz)
build() {
cd $name-$version
./configure --prefix=/ --privsepuser=dhcpcd
make
make DESTDIR=$PKG install
}
post_build() {
cd $name-$version
install -d $PKG/etc/sv/$name/log
# ... service files ...
}
# vim: filetype=sh