A simple cmake/sconcs build file will be as simple as the one shown (or even simpler !) and it will definitively will be easier to integrate external dependencies if you have to.
A simple cmake/sconcs build file will be as simple as the one shown (or even simpler !) and it will definitively will be easier to integrate external dependencies if you have to.
SCons has many issues that negatively affect packagers. Some are listed on the Gentoo wiki here: https://wiki.gentoo.org/wiki/SCons
As an OpenBSD packager, I hit many of those issues and a few more. For example, scons’s C preprocessor support is not great, and often brings in header dependencies that should be #ifdef'd out; when those unnecessary headers are removed during build (happens often on a machine bulk building packages), the build breaks.
I’ve replaced SConstructs with Makefiles before. Typically it makes the build faster, simpler, and more portable, and is popular with other OS packagers. Example: https://github.com/sinamas/gambatte/pull/6
CMake is almost great, but I have no idea why they went ahead and designed the _language_ the way they did. (Lists are concatenated strings, everything is basically macro expanded, etc..) I mean, if they were trying to improve on m4 and shell script, I wouldn't exactly say they succeeded.
I realize that CMake has better cross-platform support, but I can't stand using it. For small projects it's fine, but for medium- to large-sized projects it's a bigger headache than autotools imho.
(That said, I explicitly don't care about Windows support, which is the only place where it really matters to have something different than autotools, and even that is not so bad with MingW and will be even better, it seems, with the coming "linux-compatible subsystem")
1. Linux target: "Wow this is a breeze!"
2. Mac target: "Ahh, a little learning curve, but no problem!"
3. Windows/VC target: "Jeez, I hope I don't have to hand-edit this monstrous vcproj this thing generates..."
4. iOS: "WTF!! Simulator targets, device targets, provisioning profiles, code signing.. This stuff was all just hacked into cmake and barely made to work wasn't it??"
5. Android+NDK: "Kill me now"
6. Other obscure mobile targets with toolchains themselves that barely worked: "La La La, I'm ready for the funny farm. The cucumbers! They're dancing! And glowing!! The room is getting hazy and dark.. Where's my vodka?"
It sounds fun to read.
Most of the difficulty to be honest was with: 1. third party libraries, and 2 the Android NDK.
For third party libraries, every one was slightly different in some frustrating way. Some of them used bog-standard makefiles (thank you, third party developers who do this!), so they basically just worked. Some of them used autoconf/automake, which makes me sad but you can generally get cmake to mate successfully with them. Some of them helpfully had their own CMakeLists.txt, which would build the library, but invariably could never be successfully integrated into a larger project. Some non-open-source libraries came with just one platform's build support, so you'd have to hand-build CMake support for them, and guess which files actually needed to be built/linked. Some of them cleverly generated some of their own source files during the build process ("This is fun to maintain" said nobody ever).
The Android NDK seems to be some Googler's frankenstein hobby project that got accidentally electrified into life and set loose on the world. Like Donald Trump, the NDK is kind of an embarrassing offshoot from the "mainstream Android development story," one that Google would like to pretend doesn't exists. They, in fact, tell you in their docs "Yea, you can use native C and C++ to write Android apps with this thing, but you really shouldn't!" [1] Seriously, their "Getting Started" guide spends a paragraph or so trying to convince you not to get started. Convincing Google's own development tools to build C++/NDK is pretty frustrating itself, so you can imagine how difficult it is to convince cmake to do it.
In short, if you are working on a project that targets desktop, embedded, and mobile platforms and has lots of third party code, and one day that little voice in your head starts saying "Hey we waste a lot of time maintaining separate Makefile, .xcodeproj, .vcproj, etc. Why don't we switch to a single glorious build system that lets us list our source files in one place!?" IGNORE THAT VOICE. Go play some foosball, fix a few bugs, have a cup of coffee, but by no means try to use cmake for this.
Thanks for the write up.
It's not perfect, as others have touched on. But it overall satisfies my requirements and I can usually get things done with it.
Being a Google employee, I'm somewhat partial to Bazel (https://bazel.io/) which is based on what we use internally. I've started to ponder what it would take to write a CMakeLists.txt generator for it.
make hello
Easier?
I mean, a "hello world" CMakeLists.txt can be literally just this:
add_executable(hello hello.c)
And it's cross-platform, can generate Visual Studio/Xcode/... projects, etc. all: hello
That's not really complicated either.This is a good criteria for languages as well.
Program("main", ["main.cpp"])
The problems start once you want configure stages, build directories, portability and install targets, as all of those aspects are extremely lackluster and incomplete in `scons` and you have to reinvent large parts of the build system yourself essentially for anything even mildly complex.`cmake` is much better. The language itself is ugly and takes some getting used to, so it's a little more complicated to get started with then `scons`. `cmake` generating `Makefile`s instead of actually building the project itself also adds a layer of complexity. But once you understand the basics it's much easier to get a fully functioning build going, including configure stages, build directories, portability and all that, as cmake has all of that integrated and working right out of the box.
`cmake` feels like a complete build system, while `scons` feels like a good start for a build system that was abandoned at the halfway point.
I still use plain `make` for some Python projects (mostly .PHONY targets to run `pylint`, `autopep` and friends), but for everything that needs to get compiled `cmake` is much easier to use than plain `make`, as you don't need to reinvent a build system yourself, it already comes with almost everything you need.
demo.cxx demo_b.cxx CMakeLists.txt
$ cat src/CMakeLists.txt
cmake_minimum_required (VERSION 2.8.11)
project (HELLO)
add_executable (helloDemo demo.cxx demo_b.cxx)
$ mkdir bin
$ cd bin
$ cmake ../src
SNIP
$ make
$ ./helloDemo
$ scons