OpenBSD FAQ - Packages and Ports [FAQ Index]



Introduction

There are many applications one might want to use on an OpenBSD system. To make this software easier to install and manage, it is ported to OpenBSD and packaged. The aim of the package system is to keep track of which software gets installed, so that it may be easily updated or removed. In minutes, a large number of packages can be fetched and installed, with everything put in the right place.

The ports collection does not go through the same thorough security audit that is performed on the OpenBSD base system. Although we strive to keep the quality of the packages high, we just do not have enough resources to ensure the same level of robustness and security.

In general, you are advised to use packages over building an application from ports. The OpenBSD ports team considers packages to be the goal of their porting work, not the ports themselves.

Package management

How does it work?

Packages can be easily managed with the help of several utilities, also referred to as the pkg_* tools: In order to run properly, application X may require that other applications Y and Z be installed. Application X is said to be dependent on these other applications, which is why Y and Z are called dependencies of X. In turn, Y may require other applications P and Q, and Z may require application R to function properly. This way, a whole dependency tree is formed.

Packages look like simple .tgz bundles. Basically they are just that, but there is one crucial difference: they contain some extra packing information. This information is used by pkg_add(1) for several purposes:

Selecting a mirror

You can make things easy by defining your preferred mirror in the PKG_PATH environment variable or pkg.conf(5) file.

Example 1: fetching packages with PKG_PATH:

# export PKG_PATH=http://a.local.mirror/$(uname -r)/packages/$(uname -p)/
# pkg_add irssi
It's a good idea to add a similar "export" line to your ~/.profile. If you're using doas(1), note that you will need to pass setenv { PKG_PATH } in the config file for this variable to stick. You can specify multiple locations, separated by colons. If the first entry in PKG_PATH fails, the next one will be tried, and so on, until the package is found. If all entries fail, an error is produced.

The -r and -p flags to uname(1) will expand to the version of OpenBSD you're running and your CPU architecture. If you are using snapshots, replace "$(uname -r)" with "snapshots" instead.

Example 2: fetching packages with pkg.conf(5):

# echo 'installpath = a.local.mirror' > /etc/pkg.conf
# pkg_add mutt
This assumes that a.local.mirror uses the standard "/pub/OpenBSD/VERSION/packages/ARCH" directory layout, which most mirrors do. Unlike PKG_PATH, this method doesn't rely on the environment, so it can be a bit easier to manage when things like X sessions are involved. Note that OpenBSD also includes a list of package mirrors in the /etc/examples/pkg.conf file by default.

Finding packages

A large collection of pre-compiled packages is available for the most common architectures. To search for any given package name, use the -Q flag of pkg_info(1).
$ pkg_info -Q unzip
lunzip-1.8
unzip-6.0p9
unzip-6.0p9-iconv
You will notice that certain packages are available in a few different varieties -- these are called flavors. These will be detailed later on, but flavor basically means they're configured with different sets of options. For example, a package might have optional database support, support for systems without X11, etc. Some packages are also divided into subpackages that may be installed separately.

Not all possible packages are necessarily available on the mirror servers. Some applications simply don't work on all architectures. Some applications cannot be distributed via mirrors for licensing reasons.

If you're looking for a specific filename, install the pkglocatedb package, then use the pkg_locate command to find which package(s) contain that file.

Installing new packages

The pkg_add(1) utility is used to install packages. If multiple flavors of a package exist, you will be prompted to choose which one you want to install.
# pkg_add rsync
Ambiguous: choose package for rsync
a       0: <None>
        1: rsync-3.1.2p0
        2: rsync-3.1.2p0-iconv
Your choice:
Here you would select 1 if you want the standard package or 2 if you need iconv support.

It is possible to specify multiple package names on one line, which then all get installed at once, along with their dependencies. You may also specify the absolute location of a package, be it a local file or remote URL. Supported URL prefixes are http, https, ftp and scp.

For some packages, important additional information will be given about the configuration or use of the application.

# pkg_add jove
jove-4.16.0.73p0: ok
--- +jove-4.16.0.73p0 -------------------
See /usr/local/share/jove/README about changes to /etc/rc or
/etc/rc.local so that the system recovers jove files
on reboot after a system crash
Additionally, some packages provide configuration and other information in a file located in /usr/local/share/doc/pkg-readmes.

For your safety, if you are installing a package which you had installed earlier and removed, configuration files which have been modified will not be overwritten. The same is true for when you upgrade a package.

Sometimes you may encounter an error like the one in the following example:

# pkg_add xv
xv-3.10ap4:jpeg-6bp3: ok
xv-3.10ap4:png-1.2.14p0: ok
xv-3.10ap4:tiff-3.8.2p0: ok
Can't install xv-3.10ap4: lib not found X11.9.0
Even by looking in the dependency tree:
        tiff-3.8.2p0, jpeg-6bp3, png-1.2.14p0
Maybe it's in a dependent package, but not tagged with @lib ?
(check with pkg_info -K -L)
The packing information bundled in the package includes information about shared libraries that the package expects to be installed. If one of the required libraries can't be found, the package is not installed because it would not function anyway. To solve this type of conflict, you must find out what to install in order to get the required libraries on your system.

There are several things to check:

Updating installed packages

Let's say you had an older version of unzip installed before upgrading this box to the latest OpenBSD release. You can easily upgrade the package to the newer version like this:
# pkg_add -u unzip
unzip-5.52->unzip-5.52p0: ok
Read shared items: ok
When a package has dependencies, they are also examined for updates. Invoking pkg_add(1) with only the -u flag will try to update all installed packages. A mirror must be properly configured for this to work.

Removing installed packages

To remove a package, simply take the name of the package and use pkg_delete(1).
# pkg_delete screen
screen-4.0.3p3: ok
Read shared items: ok
--- screen-4.0.3p3 -------------------
You should also remove /etc/screenrc (which was modified)
Again, modified configuration files will not be removed.

Incomplete package installation or removal

In some odd cases, you may find a package was not added or deleted completely, due to conflicts with other files. The incomplete installation is usually marked with "partial-" prepended to the package name. This can, for instance, happen when you coincidentally press CTRL+C during installation. It's always a good idea to remove partial packages from your system, and to fix potential problems that lead to this failure. The pkg_check(8) utility can help clean things up.

Working with ports

The ports tree is meant for advanced users. Everyone is encouraged to use the pre-compiled binary packages. If you have questions about the ports tree, it is assumed that you have read the manual pages and this FAQ, and that you are able to work with it.

How does it work?

The ports tree is a set of Makefiles, one for each third party application, that controls: Apart from the Makefile, each port also contains at least the following: All this information is kept in a directory hierarchy under /usr/ports. This hierarchy contains three special subdirectories: The other subdirectories all form different application categories, which contain the subdirectories of the actual ports. Complex ports may be organized to an even deeper level, for example if they have a core part and a set of extensions, or a stable and a snapshot version of the application. Every port directory must contain a pkg/ subdirectory with packing list(s) and description file(s). There may also be patches/ and files/ subdirectories, for source patches and additional files, respectively.

When a user issues make(1) in the subdirectory of a specific port, the system will recursively walk its dependency tree, check whether the required dependencies are installed, build and install any missing dependencies, and then continue the build of the desired port. All of the building happens inside the working directory that the port creates. Normally this is under ${WRKOBJDIR}, defaulting to /usr/ports/pobj, but you may override this (see configuration of the ports system).

The ports tree is tied to OpenBSD's flavors. Do not check out a -current ports tree and expect it to work on a -release or -stable system. If you follow -current, you need both a -current base system and a -current ports tree. Because no intrusive changes are made in -stable, it is possible to use a -stable ports tree on a -release system and vice versa.

Another common failure is a missing X11 installation. Even if the port you try to build has no direct dependency on X11, a subpackage of it or its dependencies may require X11 headers and libraries. Building ports on systems without X11 is not supported.

More information about the ports system may be found in these man pages:

Fetching the ports tree

Once you have decided which flavor of the ports tree you want, you can get it from different sources. The table below gives an overview of where you can find the different flavors, and in which form. An 'o' marks availability and '-' means it is not available through that specific source.

Source Form Flavor
-release -stable snapshots -current
Mirrors .tar.gz o - o -
AnonCVS cvs checkout o o - o

Look for a file named ports.tar.gz on the mirrors.

$ cd /tmp
$ ftp https://ftp.openbsd.org/pub/OpenBSD/$(uname -r)/{ports.tar.gz,SHA256.sig}
$ signify -Cp /etc/signify/openbsd-$(uname -r | cut -c 1,3)-base.pub -x SHA256.sig ports.tar.gz
You want to untar this file in the /usr directory, which will create /usr/ports and all the directories under it.
# cd /usr
# tar xzf /tmp/ports.tar.gz
The snapshots available on the mirrors are generated daily from the -current ports tree. You will find the snapshots in the /pub/OpenBSD/snapshots/ directory. If you are using a snapshot of the ports tree, you should have installed a matching snapshot of OpenBSD. Make sure you keep your ports tree and your OpenBSD system in sync!

For more information about obtaining the ports tree via CVS, read the AnonCVS page, which contains a list of available servers and a number of examples.

Configuration of the ports system

This section introduces some additional global settings for building ports. You can skip it, but then you will be required to perform many of the make(1) statements in later examples as root.

Because the OpenBSD project does not have the resources to fully review the source code of all software in the ports tree, you can configure the ports system to take a few safety precautions. The ports infrastructure is able to perform all building as a regular user, and perform only those steps that require superuser privileges as root (for example, the install make target). However, because root privileges are always required at some point, the ports system will not save you when you decide to build a malicious application.

It is possible to use a read-only ports tree by separating directories that are written to during port building: For example, you could add the following lines to /etc/mk.conf:
WRKOBJDIR=/usr/obj/ports
DISTDIR=/usr/distfiles
PACKAGE_REPOSITORY=/usr/packages
If desired, you can also change the ownership of these directories to your local username and group, so that the ports system can create the underlying working directories as a regular user. Again, ports can be built as a user, but must be installed by root or with doas(1).

Searching the ports tree

Once you have the ports tree in place on your system, it becomes very easy to search for software. Just use make search key="searchkey" as shown in this example:
$ cd /usr/ports
$ make search key=rsnapshot
Port:   rsnapshot-1.3.1p0
Path:   net/rsnapshot
Info:   remote filesystem snapshot utility
Maint:  Antoine Jacoutot <ajacoutot@openbsd.org>
Index:  net sysutils
L-deps:
B-deps: :net/rsync
R-deps: :devel/p5-Lchown :net/rsync
Archs:  any
The search result gives a nice overview of each application that is found: the port name, the path to the port, a one-line description, the port's maintainer, keywords related to the port, library/build/runtime dependencies, and architectures on which the port is known to work.

This mechanism, however, is a very basic one, which just runs awk(1) on the ports index file. A port called "sqlports" allows very fine-grained searching using SQL. It is an SQLite database, but just about any database format can be created using the ports infrastructure. The sqlports port includes the script used to generate the database, which could be used as a basis to generate databases in different formats.

Just install the sqlports package to get started. A sample session could look like this:

$ sqlite3 /usr/local/share/sqlports
SQLite version 3.3.12
Enter ".help" for instructions
sqlite> SELECT FULLPKGNAME,COMMENT FROM Ports WHERE COMMENT LIKE '%statistics%';
Guppi-0.40.3p1|GNOME-based plot program with statistics capabilities
mailgraph-1.12|a RRDtool frontend for Postfix statistics
R-2.4.1|clone of S, a powerful math/statistics/graphics language
py-probstat-0.912p0|probability and statistics utilities for Python
darkstat-3.0.540p1|network statistics gatherer with graphs
pfstat-2.2p0|packet filter statistics visualization
tcpstat-1.4|report network interface statistics
wmwave-0.4p2|Window Maker dockapp to display wavelan statistics
diffstat-1.43p0|accumulates and displays statistics from a diff file
sqlite>
The above is still a very basic search. With SQL, just about anything can be searched for, including dependencies, configure flags, shared libraries, etc.

Straightforward installation: a simple example

For clarity's sake, let's consider a simple example: rsnapshot. This application has one dependency: rsync. The following commands assume you've configured the SUDO varable in /etc/mk.conf as mentioned above.
$ cd /usr/ports/net/rsnapshot
$ make install
===>  Checking files for rsnapshot-1.2.9
>> rsnapshot-1.2.9.tar.gz doesn't seem to exist on this system.
>> Fetch http://www.rsnapshot.org/downloads/rsnapshot-1.2.9.tar.gz.
100% |**************************************************|   173 KB    00:02
>> Size matches for /usr/ports/distfiles/rsnapshot-1.2.9.tar.gz
>> Checksum OK for rsnapshot-1.2.9.tar.gz. (sha1)
===>  rsnapshot-1.2.9 depends on: rsync-2.6.9 - not found
===>  Verifying install for rsync-2.6.9 in net/rsync
===>  Checking files for rsync-2.6.9
>> rsync-2.6.9.tar.gz doesn't seem to exist on this system.
>> Fetch ftp://ftp.samba.org/pub/rsync/old-versions/rsync-2.6.9.tar.gz.
100% |**************************************************|   792 KB    00:31
>> Size matches for /usr/ports/distfiles/rsync-2.6.9.tar.gz
>> Checksum OK for rsync-2.6.9.tar.gz. (sha1)
===>  Verifying specs:  c
===>  found c.40.3
===>  Extracting for rsync-2.6.9
===>  Patching for rsync-2.6.9
===>  Configuring for rsync-2.6.9
  [...]
===>  Building for rsync-2.6.9
  [...]
===>  Faking installation for rsync-2.6.9
  [...]
===>  Building package for rsync-2.6.9
Link to /usr/ports/packages/i386/ftp/rsync-2.6.9.tgz
Link to /usr/ports/packages/i386/cdrom/rsync-2.6.9.tgz
===>  Installing rsync-2.6.9 from /usr/ports/packages/i386/all/rsync-2.6.9.tgz
rsync-2.6.9: ok
===> Returning to build of rsnapshot-1.2.9
===>  rsnapshot-1.2.9 depends on: rsync-2.6.9 - found
===>  Extracting for rsnapshot-1.2.9
===>  Patching for rsnapshot-1.2.9
===>  Configuring for rsnapshot-1.2.9
  [...]
===>  Building for rsnapshot-1.2.9
  [...]
===>  Faking installation for rsnapshot-1.2.9
  [...]
===>  Building package for rsnapshot-1.2.9
Link to /usr/ports/packages/i386/ftp/rsnapshot-1.2.9.tgz
Link to /usr/ports/packages/i386/cdrom/rsnapshot-1.2.9.tgz
===>  rsnapshot-1.2.9 depends on: rsync-2.6.9 - found
===>  Installing rsnapshot-1.2.9 from /usr/ports/packages/i386/all/rsnapshot-1.2.9.tgz
rsnapshot-1.2.9: ok

As you can see, the ports system is doing many things automatically. It will fetch, extract, and patch the source code, configure and build (compile) the source, install the files into a fake directory, create a package (corresponding to the packing list) and install this package onto your system (usually under /usr/local/). And it does this recursively for all dependencies of the port. Notice the "===> Verifying install for ..." and "===> Returning to build of ..." lines in the above output, indicating the walk through the dependency tree.

If a previous version of the application you want to install was already installed on your system, you can use make update instead of make install. This will call pkg_add(1) with the -r flag.

Large applications will require a lot of system resources to build. If you get "out of memory" type of errors when building such a port, this usually has one of two causes:

Cleaning up after a build

You probably want to clean the port's default working directory after you have built the package and installed it.
$ make clean
===>  Cleaning for rsnapshot-1.2.9
In addition, you can also clean the working directories of all dependencies of the port with this make target:
$ make clean=depends
===>  Cleaning for rsync-2.6.9
===>  Cleaning for rsnapshot-1.2.9
If you wish to remove the source distribution set(s) of the port, you would use:
$ make clean=dist
===>  Cleaning for rsnapshot-1.2.9
===>  Dist cleaning for rsnapshot-1.2.9
In case you have been compiling multiple flavors of the same port, you can clear the working directories of all these flavors at once using:
$ make clean=flavors
You can also clean things up as they get built by setting a special variable. Work directories will automatically be cleaned after packages have been created.
$ make package BULK=Yes

Uninstalling a port's package

It is very easy to uninstall a port:
$ make uninstall
===> Deinstalling for rsnapshot-1.2.9
rsnapshot-1.2.9: ok
Read shared items: ok
This will call pkg_delete(1) to have the corresponding package removed from your system. If desired, you can also uninstall and reinstall a port's package by using:
$ make reinstall
===>  Cleaning for rsnapshot-1.2.9
/usr/sbin/pkg_delete rsnapshot-1.2.9
rsnapshot-1.2.9: ok
===>  Installing rsnapshot-1.2.9 from /usr/ports/packages/i386/all/rsnapshot-1.2.9.tgz
rsnapshot-1.2.9: ok
If you would like to get rid of the packages you just built, you can do so as follows:
$ make clean=packages
===>  Cleaning for rsnapshot-1.2.9
rm -f /usr/ports/packages/i386/all/rsnapshot-1.2.9.tgz

Using flavors and subpackages

Please read the ports(7) man page, which gives a good overview of this topic. There are two mechanisms to control the packaging of software according to different needs.

The first mechanism is called flavors. A flavor usually indicates a certain set of compilation options. For instance, some applications have a "no_x11" flavor which can be used on systems without X. Some shells have a "static" flavor that will build a statically linked version. There are ports which have different flavors for building them with different graphical toolkits. Other examples include support for different database formats, different networking options (SSL, IPv6, ...), different paper sizes, etc.

Summary: You will most likely use flavors when a package has not been made available for the flavor you are looking for. In this case, you can specify the desired flavor and build the port yourself.

Most port flavors have their own working directory during compilation, and every flavor will be packaged into a correspondingly-named package to avoid any confusion. To see the different flavors of a certain port, you would change to its subdirectory and issue:

$ make show=FLAVORS
You can also look at the port's DESCR files, which explain the available flavors in more detail.

The second mechanism is called subpackages. A porter may decide to create subpackages for different pieces of the same application if they can be logically separated. You will often see subpackages for the client part and the server part of a program. Sometimes extensive documentation is bundled in a separate subpackage because it takes up a lot of disk space. Extra functionality that pulls in heavy dependencies will often be packaged separately. The porter will also decide which subpackage is the main subpackage, to be installed as a default. Other examples are extensive test suites which come with the software, separate modules with support for different things, etc.

Summary: Some ports are split into several packages. make install will only install the main subpackage.

To list the different packages built by a port, use:

$ make show=PKGNAMES
make install will only install the main subpackage. To install them all, use:
$ make install-all
To list the different subpackages available for a port, use:
$ make show=MULTI_PACKAGES
It is possible to select which subpackage(s) to install from within the ports tree. After some tests, this procedure will just call pkg_add(1) to install the desired subpackage(s).
# env SUBPACKAGE="-server" make install
The subpackages mechanism only handles packages. It does not modify any configuration options before building the port. You must use flavors for that purpose.

Using dpb to build multiple ports

When you need to build more than one or two ports at a time, you can use the /usr/ports/infrastructure/bin/dpb tool. dpb(1) takes a list of ports to build and automatically builds them all in an optimal order, making use of as much parallelism as possible. It can also use multiple machines to perform the building, and produces detailed logs of the build process for troubleshooting, placed in /usr/ports/log by default.
# /usr/ports/infrastructure/bin/dpb -P ~/localports
This command will read the list of pkgpaths in ~/localports and build all the packages. It can also install the packages after they have been built. The ~/localports file might look something like this:
net/rsync
www/mozilla-firefox
editors/vim
If you do not provide a list of ports to build on the command line or via -P or -I, dpb(1) will build all the ports in the ports tree. If run as root, dpb will automatically drop privileges to dedicated users for fetching distfiles and building ports. This is the recommended way to use it, but it can also run as a regular user. Additionally, the proot(1) utility can be used to further isolate building operations.

Security updates (-stable)

When serious bugs or security flaws are discovered in third party software, they are fixed in the -stable branch of the ports tree. Note that binary packages for -release and -stable are not updated. In contrast to the base system, the -stable ports tree only gets security backports for the latest release.

This means that all you need to do is make sure you check out the correct branch of the ports tree, and build the desired software from it. You can keep your tree up to date with CVS and subscribe to the ports-changes mailing list to receive security announcements related to software in the ports tree.

Of course, security updates reach the -current ports tree before being taken up in the -stable branch.

Package signatures

Signatures are a good way to make sure packages are legitimate and not corrupted. OpenBSD offers official signed packages using signify(1). No extra effort is needed on the user's part to ensure packages haven't been tampered with.

If you want to build your own signed packages, you'll first need to create keys for signing.

# signify -Gns /etc/signify/my-pkg.sec -p /etc/signify/my-pkg.pub
Note the names: keys for signing packages should end in pkg.

Then we may sign existing packages after building them with pkg_sign(1).

# cd /usr/ports/packages/$(uname -p)
# pkg_sign -s signify -s /etc/signify/my-pkg.sec -o signed -S all
Alternately, we may add the following line to /etc/mk.conf to directly build signed packages by default:
SIGNING_PARAMETERS=-s signify -s /etc/signify/my-pkg.sec
In order to install the package on another machine, the public key my-pkg.pub should be put into the /etc/signify directory on that machine.

Reporting problems

If you have trouble with an existing port, please send an email to the port maintainer. To see who is the maintainer of the port, type, for example:
$ cd /usr/ports/archivers/unzip
$ make show=MAINTAINER
Alternatively, if there is no maintainer, or you can't reach them, send an email to the ports@openbsd.org mailing list. Please do NOT use the misc@openbsd.org mailing list for questions about ports.

In any case, please provide:

For ports which do not build correctly, a complete build transcript is almost always required. You can use the portslogger script, found in /usr/ports/infrastructure/bin, for this. A sample run might look like this:
$ mkdir ~/portlog
$ cd /usr/ports/archivers/unzip
$ make 2>&1 | /usr/ports/infrastructure/bin/portslogger ~/portlog
After this, you should have a logfile of the build in your ~/portlog directory that you can send to the port maintainer. Also, make sure you are not using any special options in your build, for example in /etc/mk.conf.

Alternatively, you can:

Helping us

There are many ways you can help. They are listed below, by increasing order of difficulty.

Hardware donations can assist testing ports on the various platforms OpenBSD runs on.