Recently the Meson Build System gained some momentum. It is time to stop that.
Not that Meson is a bad piece of software – on the contrary, it is quite well designed.
Still it makes building C/C++ applications worse, by (quoting xkcd) basically creating this:
It sets out to create a cross-platform, more readable and faster alternative to autotools. But there is already CMake that solves this.
You might say that CMake is ugly, but note that the CMake 2.x you might have tried is not the same CMake 3.x that is available today. Many patterns have improved and are now both more logical and more readable.
Nowadays the difference between Meson and CMake is just a matter of syntactic preference. The Meson authors seem to agree here.
The actual criterion for selecting a build system however should be tooling support and community spread. CMake easily wins here:
After the introduction of the server mode it got native support by QtCreator, CLion, Android Studio (NDK) and even Microsofts Visual Studio. Native means that you do not have to generate any intermediate project files, but the CMakeLists.txt is used directly by the IDE.
On the community spread side we got e.g. KDE, OpenCV, zlib, libpng, freetype and as of recently Boost. These projects using CMake not only guarantees that you can easily use them, but that you can also include them in your build via add_subdirectory such that they become part of your project. This is especially useful if you are cross-compiling – for instance to a Raspberry Pi.
On the other hand, reinventing a wheel that is tailored to the needs of a specific community (Gnome), means that it will fall behind and eventually die. This is what is currently happening to the Vala language that had a similar birth to Meson.
The meson devs might object that Meson generates build files that run faster on a Raspberry Pi. However if your cross compiling is working you do not need that. And honestly, that particular improvement could have been also achieved by providing a patch to the CMake Ninja generator..
Addendum 27-11-2018
Stumbled over another great guide to modern CMake.
Addendum 15-06-2018
A new guide for CMake called CGold can be found here, which is of comparable quality to the Meson docs.
Addendum 4-1-2018
Some comments (rightfully) note that Meson has generally a better documentation and avoids some of its pitfalls. However this is mostly due to Meson not being around long enough such that the way you do things in Meson changed. Neither did it see such a widespread use like CMake yet. (think of corner-cases)
But even if you argue that this is precisely the point why you should use Meson, I would argue that improving the existing documentation in CMake and adding more educational warnings is easier then writing something from scratch.
Addendum 29-02-2019
Part of the perceived superiority of Meson, was that it just was not in use for long enough to notice its flaws – contrary to long lasting legacy of CMake.
With its adaptation, things like only one global namespace start to get attention – things that are already solved in CMake..
When there are good guides and examples on CMake, I’ll switch to that one. There aren’t you say? And hasn’t been, and even CMake’s own tutorial, courseware, examples etc… are for 2.8? What’s that, you’re saying… just keep trying? Wasting more and more time, days, weeks, on something that shouldn’t take more than a few hours?
I’d rather just have something quick and simple, so I can spend my actual time building code and writing unit tests, which is what I wanted to in the first place.
I tend to agree with you that the CMake documentation is far from intuitive and it is hard to tell what is the right way to do stuff.
But I guess this is true for any technology that has been around long enough (e.g. C++, OpenGL).
Then again what is easier to achieve: improve the existing documentation for CMake or write the documentation and the build system from scratch (Meson)?
There is Reference documentation, and then there’s outdated examples, guides and courseware that Kitware still shamelessly charges money for, which teach you to do things, everyone is telling me is no longer industry standard. And all for 2.8. Since that’s the only things that there are guides for, and I’m the only C++ coder on the team, guess what kind I’m making?
Can you really blame me, if I look over at Meson and bang: Guides, examples, workable things I can easily jury-rig into what I need. Its no longer a mess of why a flag I specifically set in a CMakeLists.txt file is missing in the Makefile, or when a setting is going to be applied.
I think its a bit farfetched that you have to compare CMake with C++ and OpenGL. Its not a programming language (if its somehow Turing-Complete then add that to what is wrong with it), and its not a Graphical User Interface, it’s a build-system for crying out loud. Its job is to make little scripts, that compiles your C/C++ files, sets the flags and includes and slaps them all together into libraries, create installers and setsup native debug tests, and maybe run some scripts based on hooks at various stages. All without you having to worry about whether its Windows, or Linux, or iOS you’re on.
As for the documentation issue you kinda handwave away.
If its easy, then why isn’t it being achieved? If CMake is so important, why aren’t you calling for better documentation? Why scold guys like me for using what I can learn to use?
It’s like the Umbraco Community where many of their documentation pages look like this “TODO FIXME: Add a description here.”.
If Kitware had that, at least it would be honest.
“Our book is out free now, its a whole generation outdated, but can be a valuable guide still, just know that new ways of doing things are the standard now”.
Nope it’s still on sale as “Mastering CMake”
Rust, in contrast, which is a full programming language, has brilliant documentation, both on the new, and the old code style. It has an active and friendly community that encourages playfulness and experimentation. And its all for free, and a lot more detailed that CMake is now, or ever will be at this rate.
If CMake is so important, then there’s no excuse for it lacking documentation.
Do you really disagree? I’m being honest with you as a really frustrated programmer. A newcomer. Do you understand why I’m frustrated? Nobody sells a tool by saying “Just hang around these usenets, ask around, mess around, jury-rig and try to get it working.”
As for CMake being good enough. I can’t judge. I only know v2.8 as per their guides remember? As per 90% of guides I can find.
And v2.8 is clunky in comparison with Meson.
Outside of baby examples featuring one or a few files, in a flat src tree, compiled to one single library/executable, no tests, no debug version, no valgrind, no gdb… Everyone, and I do mean everyone agrees that the syntax is clunky. Most people agree that treating all variables as global across all the CMakeLists.txt file is a bit of a mistake. Then there’s the stale build errors because CMake for some unknown reason doesn’t fail when you have require another library, and it isn’t there, it’ll just still create Makefiles by default (unless you always carefully specify that REQUIRED setting so it’ll explicitly fail if it doesn’t find them), or Ninja files if you force it to this, which again out to be standard because Makefile is a relic from bygone era. Then those builds, quite often, might still work, resulting in that library or executable and all you know is that some feature that should be working isn’t, all because a library is missing somewhere.
This shouldn’t happen, but it does, its reported as a bug, has been for years, Kitware doesn’t care and stated explicitly that they felt it would be too difficult to fix. And they have that attitude lately about a lot of the errors in CMake. They won’t fix it, we have to learn to work around it, accept it, the bug is just a feature, etc…
Meson fixes stuff that. Call it syntax preference if you will, or tell me that CMake 3.9 actually pretty much fixes everything I say. Fine, beam that knowledge to me. Stop whining and start writing guides on CMake, instead of telling newbies to it like me that I’m doing wrong stuff for doing that it takes get stuff done.
Time spent setting up a build system is time wasted. Period. End of sentence.
There are two arguments CMake have in its favor: Its better than Autotools (anything other than writing Makefiles yourself for crosscompilatoin is better than Autotools). And on many IDE’s its standard.
So what your article should really be saying is “CMake is like PHP, its ugly, its messy, it fails silently… and to top it off the documentation is not really a priority at this point, just trust us CMake gurus that whatever you’re struggling with can be done better and take consolation in that.”
That to me seems to be a sales pitch for “Use CMake if you have to, or you’re being paid to.”
That’s what we say about PHP anyway.
You seem to be making an argument against starting the Meson project that might make sense if Meson were just a proposal, but it’s already written. Sure, there are still things to improve, but for many people Meson is already a better build system than CMake. It already has better documentation than CMake. It already has adoption from major projects, and consuming those projects now becomes easier from Meson. I understand that adding dependencies can be simplified in some cases if those dependencies are using the same build system, but trying to force everyone to use the same build system seems like an exercise in futility. (Ultimately something similar to Conan seems a more general/realistic long-term approach to this dependency issue.)
Even if you do think we should have one true build system, I’m not so sure the argument shouldn’t be “Meson is already better than CMake — why waste the effort trying to prop up CMake when we can just improve Meson?” CMake is horrible for the image/accessibility of C++ to people coming from other languages, and I think that’s a way bigger problem than dependencies or tool integration.
I wrote this half a year ago, and guess what, the CMAKE documentation is still awful. CMake is an argument against C++ and why Rust should be used instead.
I don’t think meson authors think Meson and CMake are differents only on a syntax point of view. See https://github.com/mesonbuild/meson/issues/668#issuecomment-237958292
Meson author has been a user of CMake, who just was annoyed by its imperfections:
http://voices.canonical.com/jussi.pakkanen/2013/03/26/a-list-of-common-cmake-antipatterns/
Your argument of habing too many standards is irrelevant. Otherwise CMake would never have existed, as autotools already existed. If there’s a new competitor in the game, that’s because there’s some gap to be filled. Saying “don’t use Meson” in your rant is basically saying “hey guys, I spent a lot of time learning the quirks in CMake, I don’t want to learn another build system”.
You say “the actual criterion for selecting [a build system] however should be tooling support and community spread”. Oh, well, replace “build system” by OS and go back working on Windows then. No, the real criteria are: ease of use, documentation, maintenance, performance.
On the community spread side, well, here’s a list: http://mesonbuild.com/Users.html
Meson has GTK+, GNOME, GStreamer, Systemd, and Xorg and Mesa are on their way. Those aren’t small projects, mind you?
And no, Meson is not “tailored to the needs of a specific community (Gnome)”. Just that the GNOME community (mostly using autotools) was interested in what meson could give to them: good syntax and docs, enormous build speedups on Windows (where autotools is a nightmare), better dependency management, and friendly developpers and community ready to fix bugs GNOME could encounter in a migration. If kde wanted to switch to Meson there would be a module written to ease KDE-specific use cases. This is in no way comparable to Vala that has remained a niche language, that still has problem (builds reproducibility is what comes first) and that didn’t get enough traction.
That bug report, just emphasizes my point: CMake is the de-facto standard when it comes to tool support and the only specific complaint in that comment is again “CMake’s syntax is .. unpleasant”.
The second link is again not about concrete deficiencies but about antipatterns i.e. wrong usage.
Adding some warnings if users try to e.g. set CMAKE_CXX_FLAGS would certainly be easier then writing meson from scratch.
Windows is actually good OS today. The only problem is that it is proprietary so you can not just fix the parts that you particularly do not like. You do not have this issue with CMake though.
GTK+ is GNOME nowadays (which is an issue on its own). Also I see GStreamer and systemd under the GNOME umbrella. Xorg and Mesa are evaluating, so they still can do better.
except that Vala was also picked up & praised by GTK and GStreamer people first:
https://thegnomejournal.wordpress.com/2010/02/05/writing-multimedia-applications-with-vala/
https://blogs.gnome.org/juergbi/2009/09/18/closures-and-asynchronous-methods-in-vala/
I must admit that I hated CMake from the beginning. The de facto standard (working also with autotools) is to set CFLAGS and other variables, get the build configured with some options and run make. This never worked with CMake as it seems to be different just for the sake of being different. Also if meson and CMake devs so much agreed on having little differences, why don’t they simply merge the projects?
Its not that I deliberately want to defend CMake, but
https://cmake.org/cmake/help/latest/envvar/CFLAGS.html
while it only appeared in the latest docs, I found some references to this from 2009..
Therefore I cannot rely on the same behavior that was present with good old autotools where I didn’t need to care about the configurations of the previous runs. I see that CMake’s philosophy differs from classic configure scripts but I can’t say it’s not tempting to use a tool that does exactly what autotools did but without the burden of autotools configuration.
CMake has awful syntax which makes doing brain dead trivial things like adding strings or lists a long quest for documentation (CMake’s documentation is awful) and examples (that DON’T come with CMake’s documentation).
I argue you should absolutely adopt anything that’s ready for real work and stop using CMake as soon as possible.
I’d also don’t recommend using Meson because it has serious design flaws.
Could you elaborate on Meson’s design flaws?
For example it requires you to manually add individual files into the build instead of using pattern matching because it’s “slow”, while they could’ve just implemented a caching system that only re-scans directories when they’re changed, instead of letting a human manually populate the cache which is much slower, tedious, error prone, and requires maintanence.
Also it repeats CMake’s mistake of rolling its own scripting language, which is pretty much always a bad decision because:
1. They’re not professional language designers. That language won’t be as good as properly designed ones.
2. It’s a lot of work that isn’t needed, pointlessly increasing the project’s cost.
3. It doesn’t have any ecosystem, while existing general purpose scripting languages do, including libraries, tutorials, and people who already know them.
4. It’s a waste of the user’s time to learn a language which is only used for a single tool, and is completely useless elsewhere.
I didn’t look into it any further after seeing those big red flags, so it’s possible it has more design flaws.
I started to type a reply a few days ago, but it got lost 🙁
I’m pretty torn on manually listing files vs using a scripting language (or any cleverness), because it’s usually not the hard part of “Makefile maintenance” (at least for a lot of big projects, like systemd: https://github.com/systemd/systemd/blob/master/meson.build ), but on the other hand, build system logs are pretty explicit, it’s easy to see what gets compiled, linked, so that part is easy to debug.
But also, speed is king, and good, and caching is hard. So maybe later they’ll add caching and globbing?
Furthermore, there should be a resident/background process to help tracking the modification to source files. That’d help a lot more than path caching, because then the build system could skip all those unnecessary stat syscalls.
Speaking of language, I think using Rust could help with both expressiveness and sanity. At first I was flabbergasted by cargo’s use of Rust to build Rust crates, but .. it’s pretty handy. ( https://github.com/jmesmon/rust-systemd/blob/master/libsystemd-sys/build.rs here it decides what flags to emit to cargo/rustc )
That said, all of these flaws of Meson seem to vanish compared to how braindead CMake is.
saving and loading a list of strings to disk and comparing last change dates isn’t hard, it’s trivial, and it’s orders of magnitude faster than letting a human populate the list manually. The problem is that the people behind Meson aren’t good enough.
Oh this is hillarious, especially because CMake in fact now advices developers NOT to use file globbing but to avoid it like the plague.
CMake is fundamentally flawed. I welcome Meson (and to some extent Bazel) as serious alternatives to it.
Problems with CMake:
1) the language is a full blown programming language with no debugger and very bad syntax (space inside variable names, any undefined variables just evaluate to empty string…)
2) No standard way to actually export dependencies (some developers define INCLUDE_DIR, some INCLUDE_DIRS, some define LIBRARY_DIR some LIBRARIES_DIR, most projects end up coding from scratch their own FindSOMETHING.cmake each of them with some bug or other.
3) Unintuitive behavior everywhere (SET will not actually do anything if the variable was present in the cache)
4) Completely ignores pkg-config (it’s not on windows so bring all platforms down)
5) Every project re-implements the same wheel (MYPROJECT_ADD_TEST)
Sure CMake made it possible to go from “manually edit the visual studio/xcode files” to “generate VS/Xcode files” but it is such a pain to use it’s wasting too much developers time.
I appreciate the “15 competing standards” argument, but switching from CMake to Meson actually feels like an upgrade.
Meson is also fundamentally flawed.
So far Premake is the best tool I came across.
Here’s my redhot question for you rojtberg. If it is so easy to write new documentation, why don’t you write a guide that accomplishes the following goals:
Starts by introducing all the things you shouldn’t read: In other words “Avoid all online guides, avoid the KitWare book, avoid the KitWare Wiki (they themselves warn you not to use it) and avoid the mailings lists because KitWare doesn’t care anymore – posts are about a few times per month now”
After that introduce what it is that CMake hopes to accomplish. How it tries to do that. And how it ended up having its own scripting language.
Then describe what is the difference between CMake Version 2.8 and 3.11, what improvements have been introduced and why, and what are the net benefits.
Big Project Example – More than six dependences, one of the dependencies must have its own dependency, to cover the example of when you’ve written a library yourself and you want to include it. Or you’re including someone else’s library.
Test Code Setup.
Valgrind Setup
Cache Flushing – Understanding the Cache – How the Cache sometimes overwrites your variables, why this is okay, and how to live with it.
Environmental Flags vs CMake
How CMake finds dependencies.
How to make CMake avoid making dead builds, and instead error if a dependency is missing.
How to avoid CMake making empty strings out of constants when they’re typed wrong.
The example must cover both the compilation of a library, and a executable.
At the moment, at the very best you either have a Google talk (now down) who’s examples doesn’t work, or you have examples that features a single lone .cpp file, for which you in reality neither need Makefile or CMake, but just a single gcc command.
Meson, Pre-Make, heck just about any modern build system on any language tries to have something workable here. With most of what a development needs to start from, even the skeleton as a working example.
Rust has Cargo.
Cargo is everything CMake can never become. Want a new package ‘cargo add ‘, wanna set the settings for compilation? Then edit the toml files. Easy documentation, good examples. And yes. A tutorial.
If what you’re saying is true, that it’s so much easier to add all that, than to invent a new build system. How come the KitWare guys have got it down yet?
I mean if you
After all, the only thing needed is to inspire a positive non-elitist community amongst C++ developers, making sure the documentation helps new people into the field and make sure the features are adequately described?
You’d also just merely have to get the KitWare guys to treat this as an urgency, and get your fork of the documentation merged in, and convince them that they need to update their books and not rely on expensive courses on a distant remote office somewhere as the sole way to learn CMake other than hardheaded experimentation, or being lucky enough to have a guru on access.
I mean how hard can that be?
I don’t think I’d use meson, because the main languages and development environments I use don’t include python. It’s a little annoying to have to install a large programming environment to run a tool rather than installing and using just the tool.
That said, I can’t see any defense of CMake. I’ve used it to generate makefiles and Visual Studio project files. In both cases, those files are not standalone. They actively call cmake to take care of things that make, msbuild, and the VS IDE can easily handle. The result is an unnecessarily complicated build that is difficult to reason about and debug. In the case of VS projects, it is wholly impractical to use the VS IDE to reason about build dependencies and ensure a reliable build.
You're a fucking idiot.