back
14 comments
Let me know when every project builds with cmake and maybe I'd agree. OpenSSL and Boost do not. They aren't alone in choosing other build systems. Nix is the only real sane choice in my mind unless you absolutely need win msvc. You can cache, securely and sanely, all build artifacts at a package level. You can target and build for multiple arch, compiler, libc combos. Repeating a dev env or build is dead simple since even the toolchain is included. You don't get that sort of repeatable build environment without extra work elsewhere. You get it almost for free with Nix. You can reuse the work with more than just cmake or C/C++ projects with is a reality of our new and growing language world.
Nix doesn't have win32/64 packages or I'm missing something?

Now you can use Conan + CMake to build a project with OpenSSL and Boost deps on Mac, Win, Linux. And it seems that Nix is very far from doing this.

Which is why I mentioned needing msvc, mingw and wsl are somewhat supported and there is interest in improving them
CMake is what made me realize that makefiles are too hard for humans to type. To this day, in my professional work, I've never seen a make based build system that didn't require the occasional "make clean" to generate a reliable build. The CMake generated makefiles showed me that this mythical text was possible, and the amount of time it saved was really appreciated.
CMake made me give up on C++ development. I actually liked C++ as a language, but it was exhausting and deeply uninteresting to write my own build system with a stringly-typed language that almost completely punts on package management (even the approach described in TFA is embarrassing to anyone who has used other mainstream languages) and has first-class support for certain dependencies (IIRC CMake has builtin functions for Qt and gtest and probably others). No doubt that CMake is a moderate improvement over Make, but it's still far, far worse than just about every other mainstream programming language's build tooling.

EDIT: I remember being amazed when Go came out circa 2011 that I could just "go build" a project and it just worked. One had to understand "GOPATH" which was slightly counterintuitive but not too bad, and of course it wasn't reproducible (both of those problems are pretty much addressed nowadays via modules), but I was blown away that I could actually just "go build" or "go test" and focus on my application code instead of my project tooling.

CMake tackles the unsexy challenge of cataloging every compiler on every platform. If things seem easier in Go, it's in part because Go mostly stays in its sandbox. Where Go interoperates, it's worse than CMake.

For example, Go's build system for C (cgo) is configured by stitching together environment variables and magical comments:

    // #cgo CFLAGS: -DPNG_DEBUG=1
    // #cgo amd64 386 CFLAGS: -DX86=1
    // #cgo LDFLAGS: -lpng
    // #include <png.h>
    import "C"
As bad as CMake is, that is even worse. Imagine making that stuff portable!

CMake has major problems (package management and language, as you say) but I don't know of any other tool that solves the problem that CMake solves.

https://golang.org/cmd/cgo/

That’s fine, but 99% of programs don’t need the things that CMake provides over Go or Cargo or whatever.
CMake quietly lifts heavy things behind the curtains. Cargo uses Rust, which uses LLVM, which builds with CMake.
The same is true for Autoconf and friends, but they're still pure evil and the world would be a much better place without them. :)
I've been coding c++ for nearly 20 years, still don't know how to write a Makefile. Thanks CMake!
Makefiles are actually great! Just not as a build system.

If you have a project where you need to do a thing, you can instead make a Makefile to do the thing:

    thing:
        some shell command
that's it, now you get to type `make thing`.

The power is the generality: it can wrap any command, from jq to curl to whatever. It's perfect for small, weird workflows which don't naturally fit into other build systems.

But don't use it for C++!

If that’s all you use make for just write a shell script with functions! Then you can take arguments and only have to worry about shells weird syntax instead of make + shells weird syntax.
If you run it in a directory that contains a file named `thing`, the command will not execute. You should be marking thing as `.PHONY`.

It's really easy to specify things incorrectly in a Makefile and not notice for a very long time.

Neither do use them for C.

Everyone that equates UNIX with Linux, apparently misses out how much fun (it was not) was writing portable makefiles across all major UNIXes and other non-UNIX platforms during the 90's up to the .COM first wave.