Firebuild is an automatic build accelerator. It works by caching the outputs of executed commands and replaying the results when the same commands are executed with the same parameters within the same environment.
The commands can be compilation or other build artifact generation steps, tests, or any command that
produces predictable output. The commands to cache and replay from the cache are determined
automatically based on firebuild's configuration and each command's and its
children's observed behavior.
Prefix your build command with firebuild:
firebuild <build command>
The first build is typically a 5-10% slower due to the overhead of analyzing the build and populating the cache. Successive builds can be 5-20 times or even faster depending on the project and the changes between the builds.
If the hit rate (check with firebuild -s) is not at the expected levels run firebuild with -d proc
to see why particular commands can't be stored to the cache or with -d shortcut to see what prevents
shortcutting of particular commands.
Firebuild can also generate a report about the whole build process with firebuild -r <build command>
that helps finding the slowest parts of the build and also helps finding what could not be shortcut.
Ccache works by having an understanding of how the C/C++ compiler works and it supports only the C/C++/Obj-C family of languages. Sccache adds Rust on top of those, and the concept is the same.
Firebuild supports accelerating any command that behaves reasonably well, like not downloading files from the network to produce output. As a result you can accelerate the linker (even with LTO) , or the configure and code generation steps of C/C++ project builds, which together made it consistently beat ccache in our testing.
Firebuild also supports many other compilers, such as Fortran, Java (including Javadoc generation) and Scala compilers which are not accelerated by ccache.
Bazel requires maintaining the Bazel build system, while Firebuilds works with any build system that does not implement its own caching. You just need to prefix your build command with firebuild, like it is done for accelerating bash's build in the autopkgtest: debian/tests/recompile-bash
...
Build times:
real1=88.28
user1=113.08
sys1=26.20
real2=12.38
user2=8.31
sys2=5.67
CPU time of the second build was 10% of the first build
autopkgtest [14:24:12]: test recompile-bash: -----------------------]
recompile-bash PASS
You can even accelerate a single command without any build system: firebuild <command>.
Firebuild can compress cache entries using zstd compression. This can be controlled with the compress_cache setting in the configuration file. Compression is disabled by default for maximal performance.
The compression level can be adjusted using the compression_level setting (values 1-22). Level 1 provides fast compression suitable for build caches, while higher levels provide better compression at the cost of speed.
compress_cache = false
compression_level = 1 // Fast compression (default)
Enabling compression may be beneficial when:
- Disk space is a concern
- Disk speed is a concern and retrieving compressed files from the cache is faster
- The underlying filesystem does not compress files
- The cache is not compressed externally (e.g., in CI pipelines the entire cache directory is compressed as a single archive)
Compression setting only affects the creation of files in the cache. Previously compressed cache
entries can still be used, when compress_cache is set to false.
Firebuild does not support remote caches yet.
Firebuild is available in Arch Linux (AUR), Debian, Ubuntu, and other Debian derivatives.
Back-ported packages for supported Ubuntu releases can be downloaded from the official PPA:
sudo add-apt-repository ppa:firebuild/stable
sudo apt install firebuild
To intercept static binaries Firebuild requires a Qemu version that supports the -libc-syscalls option. Prebuilt qemu-user-interposable packages are available from the firebuild/stable PPA, too.
If you would like to use firebuild in your GitHub pipeline there is a GitHub Action to do just that.
For Ubuntu earlier than 21.04 (xxhash earlier than 0.8.0 or Valgrind earlier than 3.17.0):
sudo apt-add-repository ppa:firebuild/build-deps
Install the build dependencies:
sudo apt update
sudo apt install clang cmake bats bc libconfig++-dev libelf-dev node-d3 libxxhash-dev libjemalloc-dev libtsl-hopscotch-map-dev moreutils python3-jinja2 fakeroot
If you have qemu-user installed you also need a version that supports the -libc-syscalls option:
sudo apt-add-repository ppa:firebuild/qemu-backports
sudo apt install qemu-user
Build:
cmake . && make check
Install:
sudo make install
Install the build dependencies:
brew bundle
Build:
cmake -DCMAKE_OSX_SYSROOT=macosx .
HOMEBREW_PREFIX=$(ls -d /opt/homebrew /usr/local 2> /dev/null| head -n1)
export XML_CATALOG_FILES=${HOMEBREW_PREFIX}/etc/xml/catalog
export PYTHONPATH=$(ls -d ${HOMEBREW_PREFIX}/Cellar/jinja2-cli/*/libexec/lib/*/site-packages | tail -n1)
make check
Install:
sudo make install
Set up the system to allow intercepting builds: https://firebuild.com/setup-macos