Why does the build take so long?
Building Brainiac on my Mac took too long. Long enough that working on two things in parallel was no fun at all. So I had a look at what my machine was actually doing all that time.
55 times the same
Brainiac has about 120 source files and 55 test executables. And every single test compiled all of the sources again. Every new test got its own add_executable with the complete source list. Fine for three tests. Not for 55.
add_executable(
test_pose tst_pose.cpp brainfixture.h
${SOURCE_FILES}
)
The numbers:
- 6,852 object files for the tests alone, where about 250 are enough for everything
- a build directory of 21 GB
- change a header like
scene.h, and it is compiled 56 times: once for the app, once for every test
The fix
Three small changes:
- All sources except
main.cppgo into a static library. The app and every test link against it, so each file is compiled once. - ccache caches the compiler output. Switching branches or deleting the build directory doesn’t mean starting from scratch anymore.
- Ninja instead of Unix Makefiles.
add_library(brainiac_core STATIC
src/gui/mainwindow.cpp
...
)
qt_add_executable(Brainiac
src/core/main.cpp
)
target_link_libraries(Brainiac PUBLIC brainiac_core)
The catch
The 3D viewer uses a few C++ classes in QML (QML_ELEMENT). Qt registers them with the app’s QML module, but only the ones compiled into the app itself. Moved into the library, the build would still be green, and the viewer would fail at runtime. Qt has a function for exactly this case:
qt_generate_foreign_qml_types(brainiac_core Brainiac)
Plus two include paths and one CMake policy (CMP0071), because the project still says cmake_minimum_required(VERSION 3.5). That’s why I didn’t stop at the tests: I also rendered some frames and opened the app to check that the agents and the ground still show up.

Frame 40 of the flocking example, rendered headless with the new build. Still birds, still ground.
Result
| Before | After | |
|---|---|---|
| Object files | ~6,900 | ~250 |
| Build directory | 21 GB | 837 MB |
A clean build now take about a minute, that is about 10x faster. With a warm ccache it’s 10 seconds. All 55 tests are still green.
Lesson learned
Before blaming the machine, look at what the build is doing. Mine was busy compiling the same files 55 times.