C++ Build Systems - What to use?

C++Build

C++ Problem Overview


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:

  1. C++11 support
  2. Cross platform (Linux as main target, but able to build on at least Windows as well)
  3. Decent unit testing support
  4. Support for multiple modules for separating code out
  5. Support for code generation (Using asn1c or protobuf - not 100% sure yet)
  6. 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?

C++ Solutions


Solution 1 - C++

+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 - C++

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 - C++

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 - C++

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 - C++

Google build system is a good alternative: http://bazel.io/

Solution 6 - C++

I used SCons and am impressed by this build system. SCons is extensible by python and python itself - it's great, because Python has all that you need, just code the logic, all the low-level functionality is already implemented in SCons and Python and is crossplatform. If have good programming skills then your build scripts will be looking perfect and easy.

Make, CMake and similar build systems seems as trash of macroses. Waf is SCons analog. I'm trying Waf but SCons will be more friendly and so I stayed with SCons.

By crowd opinion SCons is too slow, but in the middle of a project I didn't see any difference between make and SCons by build speed. Instead, SCons has well worked with parallel builds, while make has big troubles with it.

Also, SCons allows you to get - configure, build, deploy, generate configuration from templates, run tests and do any other task that can be done can coding with python and SCons - all in one. That is a very big advantage.

For a simple project CMake is also a good choice.

Solution 7 - C++

just to add my cents: premake

http://industriousone.com/premake

there is also a dedicated webpage on the wiki.

Solution 8 - C++

You can use Ceedling. Note, however it only supports C at the moment and it is tightly coupled to the author's Unity and CMock testing frameworks.

It can be forked and modified to work with a C++ compiler and unit testing / mocking framework fairly easily.

Also Tup is a worthy mention. It is extremely fast but it knows nothing about testing frameworks etc. which means you'll have to write your own build system using Tup. If you plan on doing TDD, Tup is probably the way to go.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGrahamView Question on Stackoverflow
Solution 1 - C++charleyView Answer on Stackoverflow
Solution 2 - C++Nate GlennView Answer on Stackoverflow
Solution 3 - C++leetNightshadeView Answer on Stackoverflow
Solution 4 - C++aegorView Answer on Stackoverflow
Solution 5 - C++Mike BView Answer on Stackoverflow
Solution 6 - C++TorstenView Answer on Stackoverflow
Solution 7 - C++user827992View Answer on Stackoverflow
Solution 8 - C++thegreendroidView Answer on Stackoverflow