Synopsis #
OpenBSD binary packages are the preferred way to install third-party software. The ports tree is appropriate when a maintained port must be built with a documented flavor, a local patch must be tested, or port development requires source-level work. It is not a general substitute for supported packages.
This guide builds one existing port from a ports tree that matches the installed OpenBSD branch. Building arbitrary upstream source outside the ports framework bypasses OpenBSD package metadata, patches, dependency tracking, and update handling.
Confirm that a Ports Build Is Necessary #
Search packages and inspect the installed ports chapter first:
$ pkg_info -Q example
# Search available binary package names
$ pkg_info -a
# Review installed packages and versions
example is a placeholder. Use the actual software stem. Prefer pkg_add when the required package and flavor already exist.
Do not mix release packages with a -current ports tree or build release ports on a snapshot system. The base system, packages, and ports tree must follow a compatible branch.
Prepare the Build Host #
Install all required OpenBSD file sets, including comp, and allocate enough space for distfiles, work directories, packages, and dependencies. Large ports can require tens of gigabytes and long build times.
Keep the build host updated within its selected branch. Record:
$ uname -r
# Identify the running OpenBSD release
$ df -h /usr /tmp
# Confirm capacity for the ports tree and build work
$ mount
# Confirm filesystem layout and mount options
Do not change kernel limits or filesystem mount options until a documented port requirement or reproduced failure establishes the need.
Obtain a Matching Ports Tree #
Use either the signed ports.tar.gz from the matching release directory or an official AnonCVS server and branch. The current Handbook version is OpenBSD 7.9. In commands, replace OPENBSD_X_Y with the corresponding release branch name shown by the official AnonCVS documentation.
For an AnonCVS checkout, create the conventional directory and grant the wsrc group write access. Add the fetching account to wsrc only while preserving its other intended supplementary groups, then start a new login session:
# install -d -o root -g wsrc -m 775 /usr/ports
Example AnonCVS checkout:
$ cd /usr
# Place the tree at the conventional path
$ cvs -qd anoncvs@ANONCVS_SERVER:/cvs checkout -r OPENBSD_X_Y -P ports
# Fetch the matching release branch from a selected official server
ANONCVS_SERVER and OPENBSD_X_Y are placeholders. Select a listed server and the branch that exactly matches the installed release. A -current system normally tracks the current ports tree instead.
When starting from the release archive, verify the signed checksum before extraction and follow the official release-file layout. Do not extract an unverified tree as root.
Inspect the Port #
Change to the intended port directory and inspect metadata:
$ cd /usr/ports/category/example
# Enter the selected port directory
$ make show=PKGNAME
# Display the package name produced by the default build
$ make show=FLAVORS
# Display supported flavors
$ make show=MULTI_PACKAGES
# Display available subpackages
category/example is a placeholder. Use a pkgpath from the matching ports tree. Do not invent a flavor from an upstream build option; only values reported by the port are valid.
Read the port’s pkg/DESCR, patches, and maintainer comments before building. Review the estimated dependency and package impact with the available show targets documented by ports(7)
.
Configure Build Privilege Separation #
The ports infrastructure can fetch and build as dedicated unprivileged users while reserving package installation for root. Configure PORTS_PRIVSEP, writable object, distfile, and package directories, and the required narrowly scoped doas rules according to the current bsd.port.mk(5)
manual.
Do not copy an old doas.conf block. Build users, environment requirements, and ports infrastructure can change. Confirm the complete configuration with one small port before a long build.
Build and Install One Port #
With privilege separation configured, build the default package as the designated unprivileged builder and install the result as root:
$ cd /usr/ports/category/example
# Enter the verified port directory
$ make package
# Fetch, patch, configure, build, and create package files
# make install
# Install the resulting package through the package tools
For a documented flavor:
$ env FLAVOR="selected_flavor" make package
# Build the selected supported flavor
# env FLAVOR="selected_flavor" make install
# Install the package built with the same flavor selection
Replace both placeholders. Preserve the same flavor environment for related build targets.
The ports framework uses _pfetch and _pbuild for configured privilege separation. Follow the current ports(7)
and bsd.port.mk(5)
guidance rather than adding broad doas rules from an old blog post.
Verify the Result #
Confirm that the installed package records the expected pkgpath and version:
$ pkg_info -S installed-package
# Display the package update signature
$ pkg_info -L installed-package
# Inspect the installed file list
Replace installed-package with the actual installed package name. Read any package installation messages and /usr/local/share/doc/pkg-readmes/ entry before enabling services.
Clean Build Objects #
After preserving required logs and package artifacts, clean the selected port and its dependencies according to ports(7) :
$ make clean=all
Confirm the current directory before running a clean target. Do not delete /usr/ports, distfiles, packages, or work directories recursively as a substitute for the infrastructure’s cleanup targets.
Maintain the Installed Package #
Once installed, the result is an OpenBSD package and should be tracked through package metadata. A locally built flavor may not have a compatible binary update on the configured mirror. Record the pkgpath, flavor, local patches, source branch, build date, and package artifact needed to reproduce it.
Do not use make update as a general replacement for pkg_add(1)
. Review the current ports caveats and rebuild in a controlled environment. For many packages or repeatable repositories, use dpb(1)
rather than looping over individual make invocations.
See Managing Software: Packages and Ports for the package-first reference and Update and Upgrade OpenBSD for base, firmware, package, and release maintenance boundaries.