⚠ Work in progress ⚠


Many existing build tools fall into the category of build script generators. These are not build systems in their own right. They rely on an existing build system in place to do the hard job of maintaining dependencies, executing the tools, parallelizing or distributing the builds, handling the logs, etc. As such they inherit the shortcomings present in the underling build system and necessitate an extra build step, while solving only the portability issue to some extent.

For example MSBuild can't parallelize files within one project thus impacting build times in some circumstances. Using CMake does not lift that limitation.

Offenders: autoconf, CMake, premake.


Many build systems (e.g. Make) don't store any state of their own between the runs, and rely entirely on the filesystem metadata of the generated files.

This comes with a shortcoming: Modified files cannot be reliably detected. For example: if a file is rolled-back, Make won't detect that it was changed and won't rebuild the dependents.

Directory hierarchies

Language agnostic

Many build systems come with their own DSL to describe the build. These range from those that minimize the size (in bytes) of the script (e.g. Boost.Build) to those using verbose XML documents (e.g. MSBuild).

It was decided in Brix's design phase that it shouldn't introduce yet another DSL at the moment. We also don't want to lock on scripting languages that suck. Therefore brix was designed so that its core is separate from the language bindings, and for the time being Lua was chosen as a lightweight (though not ideal) scripting language.


Makes of all sorts and kinds are very limited in their abilities: handling tree hierarchies, out-of-tree builds and dynamic dependencies are all impossible to properly achieve in any of them, yet none of them is truly portable. For a good in-depth article about Make flaws see What’s Wrong With GNU make?. Brix tries to address every single point raised in that article.


MSBuild teaches developers to think of build systems in a harmful and terrible way. It has a notion of 'projects' and is incapable of parallelizing the build of files within a single project. This encourages fracturing the codebase into lots of tiny projects, then forces you to manually specify the dependencies between them. Too few projects and changing one file relinks everything that might not even truly depend on it. Too many projects and you'll drown in specifying all the dependencies by hand. In the limit you would need a separate project for every file to achieve the degrees of parallelism provided by other build systems.

Items sets are harmful -- those will be built as many times as they are referenced, exploding the build times on the way.

Brix solves this by specifying link dependencies per file, then taking a transitive closure of those. Moreover, those dependencies can be automatically detected based on the includes. And the mechanism isn't specific to headers or C++ in any way.

See also