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.
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
For the sake of this example we'll assume that the source files are in
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
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
sudo umount <mnt-dir>
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>
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
unionfs-fuse -o cow <build-dir>=rw:<delta-dir>=ro:<source-dir>=ro <mnt-dir>
To later unmount it, use the
fusermount -u <mnt-dir>
To perform a build, use the
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.