C++ Build Systems - What to use? [closed]
I'm looking at starting a new project in C++ - just in my own time initially - and I'm investigating the build systems that are available. It would appear that the answer is "Many, and they're all awful".
The features that I specifically need for this are:
- C++11 support
- Cross platform (Linux as main target, but able to build on at least Windows as well)
- Decent unit testing support
- Support for multiple modules for separating code out
- Support for code generation (Using asn1c or protobuf - not 100% sure yet)
- Easy to maintain
Now, I know I can do 1-4 of those using CMake and Autotools easily enough. Probably also with SCons and Waf and the couple of others too. The problem is that I've never worked out how to correctly do code generation using them - that is source files that do not exist until the build process is first run, so source files that the build system must be able to convert into executable code but doesn't actually know about until the build starts... (ASN1C in particular generates dozens of header and source files that must be able to work together, and the actual set of files generates depends on the contents of your asn file) There's also the fact that none of these are especially easy to maintain - CMake and Autotools have their own huge set of scripts that you need to manage for them to work, and Waf and Scons require that anybody working with them has decent knowledge of python (I don't) to work with them...
So - what build systems are recommended for something like this? Or will I be stuck with make files and shell scripts for now?
Solution 1:
+1 for, "Many, and they're awful."
But, the "richest" and "most-scalable" is probably CMake, which is a Makefile-generator (also generates native MSVC++ *.proj
/*.sln
). Weird syntax, but once you learn it, it can allow you to nicely generate builds for different platforms. If I "started-fresh", I'd probably use CMake
. It should handle your list, although your "code-generation" could take on "a-life-of-its-own" beyond the build system depending on what you want to do. (See below.)
For simple projects, the QMake generator is ok (you don't need to use the Qt libraries to use QMake). But, you're not describing "simple" -- code generation and "extra-phases" means you probably want CMake
or something with a rich API for your own extensions, like Scons
(or Waf
).
We use Scons at work. It produces "bullet-proof-builds", but it's really slow. No other system will be as bullet-proof as Scons
. But, it's slow. It is written in Python and we've extended the interface for our "workspace-organization" (where we merely specify module dependencies), and that is part of the Scons
design intent (this type of extension through Python). Convenient, but builds are slow. You get bullet-proof builds (any developer box can make the final release), but it's slow. And, it's slow. Don't forget that if you use Scons
, though, that it's slow. And, it's slow.
It makes me ill to think that a decade after the Year 2000, we still don't have flying cars. We'll probably have to wait another hundred years or something to get them. And, we will then all probably be flying around in our flying cars that are still being constructed with crappy build systems.
Yes, they are all awful.
[ABOUT CODE GENERATION]
Scons
works on "phases", and they are "somewhat-static". It can build code that is generated as part of the build (people are doing this in a couple of different ways), but this has been described as, "something very un-Scons-like".
If it's simple "preprocess some files and generate source files", then no biggie (you have lots of options, and this is why qmake
was written -- for the moc
preprocessing of *.hpp/*.cpp
files).
However, if you are doing this in a "heavy-manner", you're going to need to script your own. For example, we had as-a-part-of-the-build scripts that queried the databases and generated C++ classes to interface between the "layers" (in traditional 3-tier application development). Similarly, we generated server/client source code through IDLs, and embedded version information to permit multiple clients/servers to run simultaneously with different versions (for the same "client" or "server"). Lots of generated source code. We could "pretend" that is "the-build-system", but really, it's a non-trivial-infrastructure for "configuration management", of which part of it is the "build-system". For example, this system had to, "take-down" and "start-up" servers as a part of this process. Similarly, the regression-tests were executed as a part of this process, with heavy "reporting" and "difference-testing" between versions -- all as a part of our "build-scripts".
Solution 2:
You can use Gradle now: https://docs.gradle.org/current/userguide/native_software.html
This seems to have matured quite a bit in the years since I originally posted this. The page saying that the project is "incubating" has disappeared, but I can't find any official announcement removing this status.
Solution 3:
I found these, I have not personally used all of them yet:
Ninja, a small build system focused on speed. Google now uses Ninja to build Android instead of Make: link.
Shake, a powerful and fast build system.
Tup, a high performance build system. Algorithmic based design. Analysis of Tup.
All are now cross-platform and support Windows. I'm not yet sure about the rest of your requirements as, again, I have yet to test them myself. They are being used in commercial development, CIG picked Ninja up. I've used and love ease and speed of Ninja with a project generator. First two are akin to Scons, Ant, etc.
Solution 4:
Scons is very friendly and flexible system, but you right, Lothar, it really slow.
But there is a way to increase the performance of programs written in Python. This use of the JIT. Of all known projects, PyPy is a very powerful, fast-growing and motivated JIT-backed - Python 2.7 implementation. PyPy compatibility with Python 2.7 is simply amazing. However, Scons declared as unsupported project on the PyPy compatibility wiki. Waf, on the other hand, modeled as python-based autotools sucessor, is fully supported by PyPy infrastructure. In my projects the speed of the assembly has increased 5-7 times in the transition to PyPy. You can see the performance reports from PyPy.
For modern and relatively fast build system Waf is good choice.
Solution 5:
Google build system is a good alternative: http://bazel.io/