OpenBSD FAQ - Building the System from Source [FAQ Index]

OpenBSD's Flavors

There are three flavors of OpenBSD: Only the two most recent OpenBSD releases receive security and reliability fixes for the base system.

New users should be running either -stable or a release. That being said, many people do run -current on production systems to help catch bugs and test new features.

Development Snapshots

Snapshots of the -current branch are made available between formal releases of OpenBSD. These are builds of whatever code is in the tree at the time.

A recent snapshot is usually all you need to run -current. If you wish to build it from source, starting from the latest snapshot is required. Check the following -current and using snapshots page for any configuration changes or extra steps needed to build from source.

It is possible that you may uncover bugs in snapshots. This is one of the reasons why they are built and distributed. If you find a bug, make sure it is reported.

Building OpenBSD from Source

Building OpenBSD from source involves a number of steps: This FAQ section is intended to help you with the necessary preparation. The main reference is release(8).

Upgrading to the Closest Available Binaries

Do not attempt to go from one release to another by compiling from source.

Make sure you have the closest available binaries installed. This is either OpenBSD x.y if you want to build OpenBSD x.y-stable, or the latest snapshot if you wish to build -current.

Fetching the Source Code

OpenBSD uses the CVS version control system to manage its source. The cvs(1) program is used to pull a copy of the desired source to your local machine for compilation. An introduction to cvs(1) and detailed instructions for fetching the source trees are on the anonymous CVS page. First, you must cvs checkout the source tree. After that, you maintain the tree by running cvs update to pull updated files to your local tree. You can also maintain a local CVS repository using the reposync program, available as a package. Setting up a mirror of the repository is also explained on the anonymous CVS page.

Avoiding Root Privileges

Avoid running cvs(1) as root. The /usr/src directory (where your source will typically go) is writable by the wsrc group by default, so add users that need to use cvs(1) to that group.
# user mod -G wsrc exampleuser
This change takes effect with exampleuser's next login.

If you want to fetch xenocara or ports as this user, you must create the directories and set their permissions manually.

# cd /usr
# mkdir -p   xenocara ports
# chgrp wsrc xenocara ports
# chmod 775  xenocara ports

Fetching -stable

To fetch the -stable src tree, specify the branch you want with the -r flag:
$ cd /usr
$ cvs -qd checkout -rOPENBSD_7_5 -P src
Once you have the tree checked out, you can update it at a later time with:
$ cd /usr/src
$ cvs -q up -Pd -rOPENBSD_7_5
Replace src with xenocara or ports as appropriate. As all parts of OpenBSD must be kept in sync, all the trees you use should be checked out and updated at the same time.

Fetching -current

To fetch a -current src tree, you can use the following:
$ cd /usr
$ cvs -qd checkout -P src
Update the tree with:
$ cd /usr/src
$ cvs -q up -Pd -A
Replace src with the module you want, such as xenocara or ports.

Building OpenBSD

At this point you are ready to build OpenBSD from source.

If you are building -current, review changes and special build instructions listed on this page.

Follow the detailed instructions in steps 2 and 3 of release(8).

Further Reading on the Build Process

Making a Release

A release is the complete set of files that can be used to install or upgrade OpenBSD on another system. An example use would be to build -stable on a fast machine, then make a release to be installed on all your other machines. If you have only one computer running OpenBSD, you really don't have any reason to make a release, as the above build process will do everything you need.

The instructions on making a release are in release(8). The release process uses the binaries created in the /usr/obj directory in the building process above.

Note: if you wish to distribute the resulting file sets by HTTP(s) for use by the upgrade or install scripts, you will need to add an index.txt file that contains the list of all the files in your newly created release.

# ls -nT > index.txt
If you'd like to cryptographically sign the sets you created, the signify(1) man page has details on how to do so.

Setting Up Your System

Making a release requires a noperm partition. This allows the build infrastructure to use the unprivileged build user for much of the process.

Create a filesystem on /dest with the noperm mount(8) option set. The corresponding fstab(5) line might look like this:

c73d2198f83ef845.m /dest ffs rw,nosuid,noperm 1 2
The root directory of this filesystem must be owned by build with permissions 700:
# chown build /dest
# chmod 700   /dest
Create the DESTDIR directories for base and xenocara:
# mkdir /dest/{,x}base
Your RELEASEDIR does not need to be on a noperm filesystem. Make sure that it is owned by build and has at least permissions u=rwx.

Using an mfs noperm Partition

You may want to use an mfs partition instead of a physical disk. Add a line similar to this to your /etc/fstab:
swap /dest mfs rw,nosuid,noperm,-P/var/dest,-s1.5G,noauto 0 0
Create the prototype DESTDIR directories:
# mkdir -p /var/dest/{,x}base
# chown -R build /var/dest
# chmod -R 700   /var/dest
Now you can mount /dest before making a release:
# mount /dest

Building X

Starting with X.Org v7, X switched to a modular build system, splitting the X.Org source tree into more than three hundred more-or-less independent packages.

To simplify life for OpenBSD users, a meta-build called Xenocara was developed. This system converts X back into one big tree to be built in one process. As an added bonus, this build process is much more similar to the build process used by the rest of OpenBSD than the previous versions were.

The official instructions for building X exist in the xenocara/README file and in step 5 of release(8).

Common Problems When Compiling

Most of the time, problems in the build process are caused by not following the directions carefully. There are occasional real problems with building -current from the most recent snapshot, but failures when building a release or -stable are almost always user error.

Most problems are usually one of the following:

I forgot to make obj before make build

By doing a make build before doing a make obj, you will end up with the object files scattered in your /usr/src directory. This is a bad thing. If you wish to try to avoid re-fetching your entire src tree again, you can try the following to clean out obj files:
$ cd /usr/src
$ find . -type l -name obj -delete
$ make cleandir
$ rm -rf /usr/obj/*
$ make obj

The build stopped with a "Signal 11" error

Building OpenBSD and other programs from source is a task which pushes hardware harder than most others, making intensive use of CPU, disk and memory. Signal 11 failures are typically caused by hardware problems.

You will probably find it best to repair or replace the components that are causing trouble, as problems may show themselves in other ways in the future.

For much more information, see the Sig11 FAQ.

Miscellaneous Questions and Tips

Add your user to the wobj group

If you intend to compile individual programs in the source tree -- for example, to do development -- you'll want to add your user to the wobj group. This will allow you to write to /usr/obj.

Tag Files

Being editors for developers, mg(1) and vi(1) have built-in support for ctags(1) files, which allow you to navigate source trees quickly.

In most program or library source directories, you can create a ./tags file by running:

$ make tags
When building and installing libc, a /var/db/libc.tags file is also created.

By default, kernel tags for each architecture are located in /sys/arch/$(machine)/. These files can be created with make tags from /sys/kern. You may want to run make links as root to place a symlink to your architecture's kernel tags file in each directory and in /var/db/.

How do I skip building parts of the tree?

Use the SKIPDIR option of mk.conf(5).

Can I cross-compile?

Cross-compiling tools are in the system, for use by developers bringing up a new platform. However, they are not maintained for general use.

When the developers bring up support for a new platform, one of the first big tests is a native-build. Building the system from source puts considerable load on the OS and machine, and does a very good job of testing how well the system really works. For this reason, OpenBSD does all the build process on the platform the build is being used for.

Custom Kernels

There are three ways to customize a kernel:

Boot-Time Configuration

OpenBSD's boot-time kernel configuration, boot_config(8), allows an administrator to modify certain kernel settings, such as enabling or disabling support for various devices, without recompiling the kernel itself.

To boot into the User Kernel Config, or UKC, use the -c option at startup time:

Using drive 0, partition 3.
probing: pc0 com0 com1 mem[638K 1918M a20=on]
disk: hd0+ hd1+
>> OpenBSD/amd64 BOOT 3.33
boot> boot hd0a:/bsd -c
Doing this will bring up a UKC prompt. Type help for a list of available commands.

Using boot_config(8) only provides a temporary change, meaning the procedure would have to be repeated on every reboot. The next section explains how to make the changes permanent.

Using config(8) to Change Kernel Options

Invoking config(8) with the -e flag allows you to enter the UKC on a running system. Any changes made will then take effect on the next reboot. The -u flag tests to see if any changes were made to the running kernel during boot, meaning you used boot -c to enter the UKC while booting the system.

To avoid the risk of overwriting the working kernel with a broken one, consider using the -o flag to write the changes out to a separate kernel file for testing:

# config -e -o / /bsd
This will write your changes to the / file. Once you have booted from this new kernel and verified everything works, the desired changes can be made permanent by placing them in Doing so removes the need to choose a kernel at startup and ensures that hibernation and kernel relinking keep working.

Kernel modification examples are given in the config(8) man page.

Building a Custom Kernel

Only the GENERIC and GENERIC.MP kernels are supported by the OpenBSD team. The GENERIC kernel configuration is the combination of the options in /sys/arch/$(machine)/conf/GENERIC and /sys/conf/GENERIC. Reporting a problem on a customized kernel will almost always result in you being told to try to reproduce the problem with a GENERIC kernel.

Read the config(8) and the options(4) man pages first. The following steps are part of compiling a custom kernel:

$ cd /sys/arch/$(machine)/conf
$ vi CUSTOM    # make your changes
$ config CUSTOM
$ cd ../compile/CUSTOM
$ make

Preparing a Diff

If you have made changes to the source code that you want to share with developers, follow these conventions: If you are using a git mirror of the OpenBSD source tree, set
$ git config diff.noprefix true
in your repository and generate your diff like this:
$ git diff --relative .