Table of Contents

Union Mounts For Building

To separate source files and build products, it's possible to use all sorts of systems of top-level build directories and/or symbolic links. A simple way to implement this on top of an otherwise standard source tree is to use a union mount, however.

The concept is simply to layer an empty read-write directory on top of a read-only source tree and perform the build in this merged layer. In this document two approaches are described, one using aufs and one using the user-space unionfs-fuse.

Dependencies

To use aufs, make sure it's installed. On Ubuntu this can be achieved with:

sudo apt-get install aufs-tools

To use unionfs-fuse, that'll need to be installed instead:

sudo apt-get install unionfs-fuse

Setup

For the sake of this example we'll assume that the source files are in ~/projects/ipsum/src.

First, a directory to create the build artifacts must be created as well as a directory for a mount point:

mkdir ~/projects/ipsum/build-artifacts
mkdir ~/projects/ipsum/build-mnt

Using aufs

To use aufs root privileges are required:

sudo mount -t aufs -o dirs=<build-dir>=rw:<source-dir>=ro none <mnt-dir>

… where, in this example:

To unmount it later, simply use standard umount:

sudo umount <mnt-dir>

Using unionfs-fuse

To use unionfs-fuse root privileges are not required. Being a user-space filesystem, the binary for it is simply invoked and will automatically fork into the background:

unionfs-fuse -o cow <build-dir>=rw:<source-dir>=ro <mnt-dir>

The cow option enables copy-on-write semantics, without which files located in the source partition will be regarded as read-only (which may be useful for detecting build errors, but can be annoying when compiling broken third-party code or building in a source directory which has already been polluted with build products).

If you wish to override certain files locally without risking putting them into the source repository, you can insert an extra read-only layer whose files will override those in <source-dir>, but still not be affected by scrubbing the <build-dir>:

unionfs-fuse -o cow <build-dir>=rw:<delta-dir>=ro:<source-dir>=ro <mnt-dir>

To later unmount it, use the fusermount utility:

fusermount -u <mnt-dir>

Results

To perform a build, use the <build-mnt> directory.

Do not edit any source in this location, any changes should be made in <source-dir>.

The result of this setup is that any objects are built in the <build-dir> directory, leaving <source-dir> untouched. This can also be used to detect what files being created and/or changed when performing a build.

To perform a clean build simply remove everything in <build-dir> and repeat the build. Depending on the package concerned, this may be faster than doing a make clean and can be done selectively on different parts of the tree.