What is a port?
A port is the recipe, or set of instructions, that describes how to build a program from its source code: where to download it from, what dependencies it needs, and what commands must be run to compile and install it. In starkOS a port is, in practice, a directory containing an spkgbuild template, which is the minimum that starkpm requires to build a package. In some ports you may additionally find patches, configuration files, or pre/post-install and pre/post-remove hooks that need to run during the installation or removal of the port on the system.
Port vs. package: the difference
It's easy to confuse the two terms because one becomes the other, but they serve different purposes:
-
Port: the recipe (spkgbuild) with the metadata and build
instructions. It's plain text written in shell script, version-controlled with git,
and takes up almost no space.
$ tree /usr/ports/main/linux ├── CBUILD-KFLAGS │ └── linux.opt ├── depends ├── fix-build.patch ├── post-install ├── post-remove ├── spkgbuild └── x86_64-dotconfig -
Package: the result of building a port. A
.spkg.tar.xzfile containing the already-compiled binaries, libraries, and configuration files, ready for starkpm to install on the system.$ ls -sh /var/cache/starkpm/packages/linux-7* 28M /var/cache/starkpm/packages/linux-7.1.5-1.spkg.tar.xz
In short: you build a port to obtain an installable package on the system; the portsync command syncs ports (recipes), not packages — each machine compiles its own packages from ports.
-
01
Requirements and local repository
You need
fakerootto build ports without using root directly. Install it with starkpm if you don't already have it:# portsync # stark install fakeroot
It's recommended to keep your own ports in a local repository, inside your home directory:
$ mkdir $HOME/local -
02
Create the template with portcreate
As an example, dfc will be used, a command-line tool that displays disk space usage with graphs and colors. Use
portcreate <portname>to generate the initial template and enter its directory:$ portcreate Usage: portcreate [-b builder]
Create a port template directory with spkgbuild file. Options: -b Specify build system (default: autotools) Available: autotools, meson, cmake, go, python -h Show this help message Examples: portcreate myport # Creates autotools template portcreate -b meson myport # Creates meson template portcreate -b cmake myport # Creates cmake template portcreate -b go myport # Creates go template portcreate -b python myport # Creates python template The generated template looks like this:
$ portcreate myport Template port created for 'myport' using 'autotools' build system.$ cat myport/spkgbuild
description="" maintainer="starkOS Team, starkos at disroot dot org" homepage="" name=myport version= release=1 noextract="" backup="" source="" build() { cd $name-$version ./configure --prefix=/usr make make DESTDIR=$PKG install } -
03
spkgbuild format
Each field in the spkgbuild serves a specific purpose:
Field Required Description description Yes Brief description of the port maintainer Yes Port maintainer homepage Yes Project website depends No Dependencies, in a separate file within the port directory name Yes Port name, same as the directory version Yes Program version release Yes Port revision for the same version source Yes Remote location of the source code noextract No Sources that should not be extracted backup No Files to preserve during an update nostrip No Files to exclude from stripping build() Yes Function containing the build commands Inside
build(),$PKGis the simulated install directory and$SRCis the directory where the extracted sources end up.The port name must be lowercase and cannot contain spaces; if the original project uses uppercase, fix it with
sedwhen writing the spkgbuild. If the source uses date-based versioning, hyphens (-) cannot be used — replace them with underscores (_) or dots (.) if strictly necessary. -
04
Recommended schemes for each builder
Global options are defined in
/etc/starkpm.conf; for a specific port they are overridden in its own spkgbuild withoptions="". Prefix with!to disable an option, for exampleoptions="!strip !emptydirs".make ./configure \ --prefix=/usr \ --disable-option \ --enable-option make make DESTDIR=$PKG installautoconf / automake autoreconf -fi ./configure \ --prefix=/usr \ --disable-option \ --enable-option make make DESTDIR=$PKG installmeson
The distribution provides a starkos-meson wrapper script which sets some common options.
starkos-meson $name-$version build \ -Doption=false \ -Doption2=true meson compile -C build DESTDIR=$PKG meson install --no-rebuild -C buildcmake cmake -S $name-$version -B build \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_INSTALL_LIBDIR=lib \ -DCMAKE_INSTALL_LIBEXECDIR=lib \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_FLAGS_RELEASE="$CFLAGS" \ -DCMAKE_CXX_FLAGS_RELEASE="$CXXFLAGS" \ -DOPTION=ON/OFF \ -Wno-dev cmake --build build DESTDIR=$PKG cmake --install buildgo cd $name-$version export CGO_LDFLAGS="${LDFLAGS}" export CGO_CFLAGS="${CFLAGS}" export CGO_CPPFLAGS="${CPPFLAGS}" export CGO_CXXFLAGS="${CXXFLAGS}" export GOFLAGS="-buildmode=pie -trimpath -mod=readonly \ -modcacherw -ldflags=-linkmode=external" export GOPATH=$SRC/go export PATH=$PATH:$GOPATH/bin go build -o bin/$name *.gopython python3 setup.py build python3 setup.py install --prefix=/usr --root=$PKGpip (python) pip3 install --isolate --root=$PKGbuild (python) python3 -m build --wheel --skip-dependency-check --no-isolation python3 -m installer --destdir=$PKGgpep517 (python) gpep517 build-wheel --wheel-dir .dist --output-fd 3 3>&1 >&2 python3 -m installer -d $PKG .dist/*.whl -
05
Edit the spkgbuild
With the format clear, you can now fill in the template with curl's actual data:
$ vim spkgbuildThe complete spkgbuild for dfc would look like this:
description="Utility and a library used for transferring files" homepage="https://curl.se" maintainer="starkOS Team, starkos at disroot dot org" name=curl version=8.21.0 release=1 source="https://curl.haxx.se/download/$name-$version.tar.xz" build() { cd $name-$version autoreconf ./configure \ --prefix=/usr \ --disable-static \ --disable-ldap \ --disable-ldaps \ --enable-ipv6 \ --enable-threaded-resolver \ --with-ca-bundle=/etc/ssl/cert.pem \ --with-ca-path=/etc/ssl/certs \ --with-nghttp2 \ --with-openssl \ --without-brotli \ --without-libidn2 \ --without-libpsl \ --without-librtmp \ --without-zstd make make DESTDIR=$PKG install }It's recommended to save sources following "$name-$version.*". If the source needs to be saved under a different name, use
<new-name>::<url>insource="", for example"$name-$version.tar.gz::https://project/file/v${version}.tar.gz". -
06
Build the package
With the spkgbuild finished, run
portbuildinside the port's directory to download the source and compile it. For a new port, do this first withfakeroot; if something is misconfigured, it won't affect your system.$ fakeroot portbuild ==> Building: curl-8.21.0-1 ==> Fetching: https://curl.haxx.se/download/curl-8.21.0.tar.xz ==> .checksums updated ==> Unpacking: /mnt/starkos/var/cache/starkpm/sources/curl-8.21.0.tar.xz ==> Build start: curl-8.21.0-1 + build + cd curl-8.21.0 + autoreconf ... ==> .pkgfiles updated ==> Packaging success: curl-8.21.0-1.spkg.tar.xz (1.3M) -
07
Install the package
Once built, you can install it directly with portbuild:
# portbuild -i
For dependencies, repository synchronization, and updating the system once the package is installed, see the install guide.