I wonder if this whole post is just me being too picky with something so often dismissed as an after thought.
What build system to use?
There certainly are no shortage of choices, and that abundance tends to make finding the right answer though!
This dilemma makes me loose more time than I’d wish pondering about what build system to use on any new non trivial project.
What I’m looking for
These are the characteristics I normally look for in a build system:
The tool should be able to run on multiple operating systems. Or at the very least support Linux and Windows. Mac OS support here is, for me, still only a plus, since I’m not using that platform (yet).
Support cross compilation
Cross compilation is when you compile a binary for a platform or cpu architecture different from the one you are currently using on your development machine.
A great example is when you want to compile a windows binary, using mingw (a gcc port for windows) running under linux.
If the notion of multiple compilers is supported by the build system, then there is a big possibility the build tool will also support cross-compilation smoothly.
Make dependency management hassle free
This is a problem, specially for large projects in C++, where the module system is, sadly, aching from its reliance on the C preprocessor.
Some tools call the compiler and ask for a mapping between source files and their dependencies (make and gcc can cooperate this way), while others support parsers that extract this information directly from the source files.
Either way, these dependencies should preferably be calculated automatically, and fast enough so that they don’t add too much time to a simple check, where little or no changes were made to the source code files (very common if you are doing small incremental changes to your code).
The build system should support multiple programming languages, at least for dependency calculations.
While I personally favor C++ for my projects, I tend to use Java a lot, and also like to learn new languages.
Having to learn a new language can be fun, but also takes its mental toll, as you try to map existing concepts into a new (possibly similar) syntax, understand how to use new language features elegantly, and from time to time, learn a whole new programming paradigm. Having to learn all this while having to switch to a new build system, with (most likely) new syntax of its own, just seems like unneeded work.
Support custom pre and post processors
Some libraries rely on extra pre or post processors running on the source code, or the produced binaries.
From the top of my head, the best examples are:
Qt , that alters the source code you write to add the notion of “slot:” and “signal:” sections to a C++ class (adding to the standard “public:”, “protected:” and “private:” sections).
Play well with other make systems
There is no reasonable way to avoid using at least one external project as an external dependency (library). With this abundance of build systems, chances are, you will not share the same build system with your external dependencies.
While for most stable libraries, using a binary distribution can be enough, in some cases you will want to be using a cutting edge development version.
While this point is not important as the above, I would like to find a tool that makes it easy for me to clean the whole project and rebuild it completely with one or two simple commands.
Integrate well with both an IDE and the command line
If you rely on an IDE for your build system, you typically loose the ability to easily do automated builds on a server (I’m thinking about jenkins/hudson for continuous integration for example).
I like to be able to use Eclipse, and command line / Vim intermittently for the same project, and under windows, I will likely need Visual Studio at some point and XCode under MacOS.
The build tool should make my life easier by integrating or cooperating smoothly with the IDE of choice at the time.
Should be actively developed and supported
It is normal that with such an abundance of choice, some tools will be more actively used, supported and developed than others.
Choosing one that is updated regularly seems like a good idea to me.
- GNU Make – http://www.gnu.org/software/make/
- CMake – http://www.cmake.org/
- GNU Autoconf / Automake (autotools) – http://www.gnu.org/software/automake/
- Apache Ant – http://ant.apache.org/
- Apache Buildr – http://buildr.apache.org/
- Apache Ivy – http://ant.apache.org/ivy/
- Maven – http://maven.apache.org/
- Boost.Build – http://www.boost.org/boost-build2/
- Scons – http://www.scons.org/
- A-A-P – http://www.a-a-p.org/
- Ninja – http://neugierig.org/software/chromium/notes/2011/02/ninja.html
- WAF – http://code.google.com/p/waf/
I have tried to list the tools I knew, plus a few I recommended or found out while looking for better alternatives.
Have I forgotten something? Any suggestions?
In future posts I will go over these tools and try to decide on one that suits my needs.