The OpenBSD Ports Collection is the infrastructure used
to create binary packages for third party applications.

For normal usage refer to
packages(7), as most ports
produce binary packages which are available from the official HTTP mirrors.

Each port contains any patches necessary to make the original application source
code compile and run on OpenBSD. Compiling an
application is as simple as typing make in
the port directory! The Makefile
automatically fetches the application source code, either from a local disk or
via HTTP, unpacks it on the local system, applies the patches, and compiles
it. If all goes well, simply type doas make
install to install the application.

invoked with a key, e.g., make search
key=foo, retrieve information relevant to a given port
(obsolescent).

Starting in OpenBSD 4.0, there is a port,
databases/sqlports that builds an sqlite
database containing most information relevant to every port in the ports tree.
This database can be searched using any tool able to manipulate such
databases, for instance sqlitebrowser, or a script language with an sqlite
interface, e.g., perl, python, ocaml, lua, php5.

Individual ports are controlled through a few documented targets. Some of these
targets work recursively through subdirectories, so that someone can, for
example, install all of the net ports.

The variable SKIPDIR can hold a set of
package directories to avoid during recursion. These are always specified
relative to the root of the ports tree, and can contain a flavor or subpackage
part (see
packages-specs(7)).
SKIPDIR is handled by a
case statement, and so can contain simple
wildcards (see sh(1) “File
name patterns”), e.g., SKIPDIR='editors/openoffice*' .

The variable STARTDIR can hold the path to a
starting directory. The recursion will skip all directories up to that package
path. This can be used to resume a full build at some specific point without
having to go through thousands of directories first.

The variable STARTAFTER can hold the path to
a starting directory. The recursion will skip all directories up to and
including that package path. This can be used to resume a full build after
some specific point without having to go through thousands of directories
first.

In case of failure in a subdirectory, the shell fragment held in
REPORT_PROBLEM is executed. Default
behavior is to call exit, but this can be overridden on the command line,
e.g., to avoid stopping after each problem.

$ make REPORT_PROBLEM=true

If REPORT_PROBLEM_LOGFILE is non empty, then
REPORT_PROBLEM will default to:

echo $$subdir ($@) >>$${REPORT_PROBLEM_LOGFILE}

That is, any failure will append the faulty directory name together with the
target that failed to
${REPORT_PROBLEM_LOGFILE} and proceed.

Target names starting with ‘_’ are private to the ports
infrastructure, should not be invoked directly, and are liable to change
without notice.

In the following list, each target will run the preceding targets in order
automatically. That is, build will be run
(if necessary) by install, and so on all
the way to fetch. In typical use, one will
only run install explicitly (as normal
user, with SUDO defined in
/etc/mk.conf), or
build (as user), then
install (as root).

Verify that the fetched distfile matches the one the port was tested
against. Defining NO_CHECKSUM to
Yes will skip this step. Sometimes,
distfiles change without warning. The main OpenBSD
mirror should still hold a copy of old distfiles, indexed by checksum.
Using

The ports tree can be used concurrently for building several ports at the same
time, thanks to a locking mechanism. By default, locks are stored under
/tmp/portslocks. Defining
LOCKDIR will point them elsewhere, or
disable the mechanism if set to an empty value.

All locks will be stored in ${LOCKDIR}.
LOCK_CMD should be used to acquire a lock,
and UNLOCK_CMD should be used to release
it.

Locks are named
${LOCKDIR}/${FULLPKGNAME}.lock, or
${LOCKDIR}/${DISTFILE}.lock for distfiles
fetching.

The default values of LOCK_CMD and
UNLOCK_CMD are appropriate for most uses.

The locking protocol follows a big-lock model: each top-level target in a port
directory will acquire the corresponding lock, complete its job, then release
the lock, e.g., running

$ make build

will acquire the lock, run the port through
fetch,
checksum,
extract,
patch,
configure,
build, then release the lock. If
dependencies are involved, they will invoke top-level targets in other
directories, and thus acquire some other locks as well.

The infrastructure contains some protection against acquiring the same lock
twice, thus recursive locking is not needed for
LOCK_CMD.

Starting with OpenBSD 4.3, the infrastructure supports
manual locking: the targets lock and
unlock can be used to acquire and release
individual locks. Both these targets output a shell command that must be used
to update environment variables. Manual locking can be used to protect a
directory against interference by an automated build job, while the user is
looking at or modifying a given port.

Instead of deinstalling each package and rebuilding from scratch, the ports tree
can be used to update installed packages. The
update target will replace an installed
package using pkg_add(1) in
replacement mode. If FORCE_UPDATE is set to
Yes, dependencies will also be updated
first, and packages will always be updated, even if there is no difference
between the old and the new packages.

Updates use a mechanism similar to bulk cookies and deposit cookies in the
UPDATE_COOKIES_DIR. See the next section
for more details, since most of the fine points of bulk package building also
apply to updates.

There are bugs in the ports tree, most related to libtool, which make some
updates prefer the already installed libraries instead of the newly built
ones. This shows up as undefined references in libraries, in which case there
is no choice but to proceed the old way: deinstall the offending package and
everything built on top of it, build and install new packages.

Building any significant number of packages from the ports tree should use
dpb(1), a tool located inside the
ports tree proper (normally as
/usr/ports/infrastructure/bin/dpb). In
particular, it can take advantage of machine clusters (same architecture and
same installation), and of multi-core machines.

The OpenBSD ports tree comes with a mechanism called
FLAVORS. Thanks to this mechanism, users
can select specific options provided by a given port.

If a port is “flavored”, there should be a terse description of
available flavors in the pkg/DESCR file.

For example, the misc/screen port comes with
a flavor called static. This changes the
building process so a statically compiled version of the program will be
built. To avoid confusion with other packages or flavors, the package name
will be extended with a dash-separated list of the selected flavors.

In this instance, the corresponding package will be called
screen-4.0.2-static.

To see the flavors of a port, use the show
target:

$ make show=FLAVORS

To build a port with a specific flavor, just pass
FLAVOR in the environment of the
make(1) command:

$ env FLAVOR="static" make package

and of course, use the same settings for the subsequent invocations of make:

$ env FLAVOR="static" make install
$ env FLAVOR="static" make clean

More than one flavor may be specified:

$ cd /usr/ports/mail/exim
$ env FLAVOR="mysql ldap" make package

Specifying a flavor that does not exist is an error. Additionally, some ports
impose some further restrictions on flavor combinations, when such
combinations do not make sense.

Lots of ports can be built without X11 requirement and accordingly have a
no_x11 flavor.

Flavor settings are not propagated to dependencies. If a specific combination is
needed, careful hand-building of the required set of packages is still
necessary.

The OpenBSD ports tree comes with a mechanism called
MULTI_PACKAGES. This mechanism is used when
a larger package is broken down into several smaller components referred to as
subpackages.

If a port is “subpackaged”, each subpackage will have a
corresponding description in the
pkg/DESCR-subpackage file.

For example, the databases/mariadb port comes
with subpackages called -main,
-tests and
-server.

In this instance, the build will yield multiple packages, one corresponding to
each subpackage. In the case of our mariadb example, the packages will be
called mariadb-client-<version>,
mariadb-tests-<version>, and
mariadb-server-<version>.

To install/deinstall a specific subpackage of a port, you may
pkg_add(1) them manually, or
alternatively, you may set SUBPACKAGE in
the environment of the make(1)
command during the install/deinstall phase:

During bulk package building, used to store cookies for already built
packages to avoid rebuilding them, since the actual working directory will
already have been cleaned out. Defaults to
${PORTSDIR}/bulk/${MACHINE_ARCH}.

Select read-write partition(s) that can accommodate working directories, the
distfiles repository, and the built packages. Set
WRKOBJDIR,
PACKAGE_REPOSITORY,
BULK_COOKIES_DIR,
UPDATE_COOKIES_DIR,
DISTDIR, and
PLIST_DB in
/etc/mk.conf accordingly.

The Ports Collection appeared in
FreeBSD 1.0. It was introduced in
OpenBSD by Ejovi Nuwere, with much initial effort by
Angelos D. Keromytis. Maintenance passed then to Marco S. Hyman, and then to
Christopher Turan. It is currently managed by Marc Espie, Christian
Weisgerber, along with a host of others found at
ports@openbsd.org.