CMake gets a lot of hate because a lot of large projects use it poorly and the syntax is strange, but I've found it invaluable for projects I've worked on. The first page of this site has a great list of reasons why someone would want to use CMake. I would recommend at least reading that far rather than reading "CMake" in the title and reflexively commenting something negative. I skimmed through and this seems like a nice resource to get people spun up on CMake, I'll recommend it to new users in the future.
> CMake gets a lot of hate because a lot of large projects use it poorly and the syntax is strange
Sounds like a ”you’re holding it wrong”[0] defense. In my experience, it’s exciting to start using it, then you start pushing it and it’s annoying or simply falls down. I’ll admit I’ve avoided it for years now (maybe it needs a revisit), but I bought the book, I drank the koolaid, and I tried to like it. But imo it really is problematic, and I’m one of those people who’s since settled on basic (BSD) Makefiles.
[0] https://www.cnn.com/2010/TECH/mobile/06/25/iphone.problems.r...
Well, cmake is there because people did the same thing to autoconf, so it’s hard to be too sympathetic. Cmake is useful, but also terrible, like most build systems.
The difference I see is that Autotools is mainly useful for handling differences between various Unix variants, which isn't a concern now that commercial Unix isn't really a thing besides Mac OS X. CMake doesn't have the years of arcane knowledge about dozens of Unix variants that Autotools does, but it lets you target Windows using the native tooling as opposed to having to do all your development in Cygwin, and it automatically generates IDE projects so you can use IDE provided tooling like debuggers and profilers. Personally, I think this is a more compelling value proposition than what Autotools offers. Obviously, if you're fine with using a text editor and GDB and for some reason need to target SunOS, SCO UnixWare, 386BSD, A/UX, etc but not Windows, Autotools is great for that use case and you should stick with it.
Pretty much all newer languages massively simplify their build processes by establishing a bunch of common-sense conventions: the output directory is always the same, all *.foo files in a directory are automatically considered source files, the output is identical to the directory name, things like that. They also include proper versioning of dependencies instead of "just assume /usr/include/foo/foo.h is the version we want, yolo".
In principle it's very much possible to do all of this in C or C++, which would massively simplify stuff. But both C and C++ being a "design by committee" affair there will be endless fighting over which conventions to choose so I'm not holding my breath.
My experience is that CMake is fine (even great) for small to medium sized projects. Including dependencies, automating tests, even packaging is all handled with not too much fuss.
If you think your project will have more than half a dozen developers then you should probably start thinking about something like Bazel. But both have their idiosyncrasies and Bazel for a small project is overkill.
> If you think your project will have more than half a dozen developers
https://github.com/llvm/llvm-project/blob/main/llvm/CMakeLis...
How many active contributors does LLVM have? Hmmm
https://github.com/pytorch/pytorch/blob/main/CMakeLists.txt
How many active contributors does PyTorch have? Hmmm
https://github.com/boostorg/boost/blob/master/CMakeLists.txt
How many active contributors does boost have? Hmmm
I could go on...
I never used bazel so I can't comment on it. But your argument is invalid. Just because some large scale codebases use cmake doesn't mean it's the better choice. It just means cmake is workable at these scales. But many things that are workable are very far from good
Technically CMake is still not official way to build Boost libraries. A link to latest docs: https://www.boost.org/doc/libs/1_88_0/more/getting_started/u...
While it might look like technicality the number of projects that kept their own build systems is substantial. I would say there are dozens open and many more not so open build systems out there that support large projects and organizations. I don't see anyone rushing to "rewrite it in CMake" anytime soon. At least in gamedev where I work.
> If you think your project will have more than half a dozen developers then you should probably start thinking about something like...
CMake was created in 2000 with large, cross-platform projects involving multiple organizations in mind. The development was funded by the National Library of Medicine (NLM) for the ITK project (https://github.com/InsightSoftwareConsortium/ITK). As of 2025, ITK consists of millions of lines of code and has received contributions from hundreds of developers. Other projects of similar scale include VTK and ParaView.
I would kill for all CMake internals but sane language syntax. I mean, it is ok for what's it is doing for now, but I cannot stand syntax, and reading it requires some efforts
Is there an open source project which uses CMake well and could be used as a reference for good CMake practices?
I've been using CMake for years and it's definitely not the worst solution for building multiplatform C++ projects. But I've never read a CMake script and thought what a clean solution, it's always a bit gnarly.
I don't know about "could be used as a reference for good practices", but here's a CMake file for a game project I've worked on if you're interested looking at how someone might use CMake for a smaller codebase (everything large I've used it for has been a work for hire unfortunately). It compiles on Linux with GCC, Mac OS X with Apple Clang, and Windows with MSVC, and supports multiple platform backends (currently SDL2 and SDL3). I've done development work on it with CLion, Xcode, and Visual Studio.
https://github.com/nfroggy/openmadoola/blob/master/CMakeList...
> But I've never read a CMake script and thought what a clean solution, it's always a bit gnarly.
I think using CMake for a cross-platform project that supports multiple compilers will always be a bit gnarly, mainly due to the differences between Windows and Unix-like platforms. MSVC is configured very differently to GCC and Clang so you have to list all your compiler flags twice, and there's no good option for doing system-wide installation of libraries (there's vcpkg, but a lot of stuff on there is missing or outdated) so you have to support both system-wide libraries on Unix-like platforms and user-provided DLLs on Windows.
https://github.com/ClickHouse/ClickHouse
We are trying to use CMake in a very limited fashion.
For example, any build time environment checks are forbidden (no "try_compile" scripts), and all configuration for all platforms is fixed.
We don't use it for installation and packaging; it is only used for builds. The builds have to be self-contained.
We also forbid using CMake files from third-party libraries. For every library, a new, clean CMake file is written, which contains the list of source files and nothing else.
From this standpoint, there should be no big difference between CMake, Bazel, Buck, GYP, GN, etc.
ParaView [0] and VTK [1] are big projects from the same shop that does CMake.
KDE's stuff (which is the original reason CMake became popular and adopted) remains updated and fairly clean.