I recently had to build a couple of external packages that had switched to meson for internal deployment - I wasn't left _terribly_ impressed. Almost all the dependencies either required pkg-config support (which lots of the standard builds of said packages didn't deploy), or leaned heavily on CMake to actually resolve the dependencies (except for the one package with a custom meson dependency resolver - which couldn't use either and needed to be hacked).
Am I thinking of it wrong, and using it as a "layer" above CMake to do the heavy dependency lifting is an intended part of Meson? Cmake has _huge_ support and mindshare in terms of third party packages and dependencies, even if it is somewhat difficult to learn "good" methods of writing CMakeLists.
I feel like spending the effort to learn a complete new build configuration metalanguage - and having to rewrite dependency discovery/builds, would be better spent on something like Bazel and it's mass-distributed compile capabilities, rather than something that looks just like cmake but with a new and unique language that to general approximation nobody else uses.
This is admittedly a rather uncharitable and possibly unfair way of looking at it - and I don't begrudge anyone trying to find a way of writing builds that fits better with them. Perhaps It's just a personal bias and I'm just getting to the age where learning a tool thoroughly and writing stuff that other people have a higher chance of experience in becomes more important than chasing... whatever it is that people value in this. (Or perhaps I have been too burnt by insanely complex badly implemented fragile SCons systems and not enough bad CMake systems).
I really wish we saw wider adoption of Bazel, or something Bazel-like, from the OSS space. The main benefits Bazel-like systems bring to the table, in my mind, are structuring libraries, binaries, and tests in a way a software engineer thinks about those things in code. It makes it very natural and also provides public/private visibility to libraries all while also giving you reproducible builds.
If you are in a larger company, or something like an OS distribution, you can even further benefit from RBE. Imagine a Linux distro just being built like this:
Or something like that which would produce an iso and cpio (for PXE) automatically for you. You could then very quickly compile and test all of this on every arch you have access to using RBE.
Such packages and exports are really just simple config files that I think can be safely treated as declarative — they become a perhaps uglier, but portable alternative to pkg-config. As such, having meson read them would be a smart move, and would be quite simple.
Unfortunately, CMake doesn’t have a culture of creating/installing/using exports IME, and so you end up with enormous, complicated Find packages that do fancy bespoke dynamic search logic. THAT isn’t something I’d like a project like meson to lean on, but only because the goal should be to remove the need for such things, not depend on them further. CMake doesn’t help matters by making exports fiddly.
Why this packages doesn't provide pkg-config after so many years? On Linux literally every library comes with pkg-config readily available and the same is possible on Windows (MSYS2) and MacOS (that beer thing).
Maybe if you are installing from a distro-provided central repository like debian and only using system package-managed sources, and nothing exotic.
On a cursory check, the conda environment that we build off has 250 packages in, and only 60 .pc files.
And to be fair, only 50 entries in lib/cmake, but a lot of the CMake dependency resolution is built into CMake (and does pkg-config support separated components as part of a package, like e.g. Boost which apparently has a 14-year-old unresolved ticket to add pkg-config support). All our "build from source" HDF5 installs don't have this either. Nor does debian have .pc files for their distribution of one of our key libraries (which we don't use via debian, but still....).
This seems a very, very long way from "literally every library comes with pkg-config".
Thanks. It's a fairly new feature, I didn't know about it. It's certainly annoying that distros don't have good pkg-config support, it would be so much nicer than writing detection logic or reusing CMake.
In my experience, it's that pkg-config assumes that everything needed to consume a library can be communicated via flags spelled as GCC spells them. There are many compilers which don't speak GCC on the command line. Some are popular (Intel and MSVC come to mind).
Good point. I have always been thinking that the practical way with MSVC is to just embed everything into the project because everything else is too much work. Perhaps it's time to change that now.
The only reason Meson exists is that the gnome developers really, really, really couldn't stomach using CMake because KDE ported to it in 2005, 2006. That made it so toxic to them that they simply had to come up with alternatives, all of which turned out to be as warty as CMake when they finally came close to reaching -- not even a bit of feature parity or cross-platformity.
They could have worked with the CMake people to improve CMake, they could have accepted that CMake has improved a ton since then, but no, CMake has cooties. They had to go and fragment again -- just when we were getting out of autohell.
There is no reason for Meson to exist: it should not exist. We were finally coming to a point where we could build any library on any OS using one and the same build system -- and now there's Meson.
Which is completely not relevant to what I tried to make clear. Yeah, Meson started out as "we do build systems better" and these days they compare themselves to CMake because Meson is not winning, but that's got nothing to do with what I said.
Build system fragmentation is bad. Autohell is bad. If CMake was bad, CMake could, and has been, improved. People choosing Meson over CMake, especially if they're working on libraries contribute to wanton fragmentation that makes cross-platform development a lot harder.
There is no reason, whatsoever, for Meson to exist, other than parochialism, not-invented-here-ism.
Even if you would take Meson over CMake any day, you should not do that.
>Which is completely not relevant to what I tried to make clear.
It is. You wrote:
>>There is no reason for Meson to exist: it should not exist.
I responded that there is. Namely that it's better.
>and these days they compare themselves to CMake because Meson is not winning
Meson is winning just fine, given that every new C project I find these days seems to be using it. None of these projects are gnome-specific either, btw. This strawman of meson developers / users feeling insecure is entirely of your construction (and ironic).
>If CMake was bad, CMake could, and has been, improved.
Nothing stops its developers from improving it now. But my biggest problem with cmake is not the missing features (there aren't any) but the absolute PITA macro-hell syntax, and I doubt there's anything they can improve in that regard.
> There is no reason for Meson to exist: it should not exist.
> If CMake was bad, CMake could, and has been, improved.
> Even if you would take Meson over CMake any day, you should not do that.
Are you seriously believing this, or are you just trolling? Because you are basically saying:
* There is no reason for car to exist because if horse wagons are bad, they could have been improved. Fragmenting the transportation means is atrocious. Look at all the extra cost on the paved roads.
* There is no reason for C++/Java/Python/Rust to exist because if C is bad, it could have been improved. If everyone just reads and writes C, we would have built the tower of babel.
* There is no reason for Fedora/Ubuntu/BSD to exist because if Debian is bad, it could have been improved. Imagine a world where Linux = Debian and all shells, utils, libraries are written for this one OS and apps can be distributed in binary form just as Windows and Mac.
Distros already have to deal with several build systems. Makefiles, Autotools, CMake, scons, waf, and yes meson. The fragmentation is not that bad. Especially since meson has seemed to push out autoconf more than anything else.
Happy to see people trying to improve on the state of the art for build systems - I certainly despise SCons and CMake - but in practice so far every time I've encountered a project using meson it's just meant I get to puzzle through a new maze of weird build system quirks and I have fewer sources to rely on for guidance since nobody knows meson. I wasn't impressed by the tooling for debugging and troubleshooting builds, either.
In practice I gave up after spending a day trying to get usable builds out of harfbuzz entirely because meson made it a nightmare. At some point I'll probably pay some expert to figure it out for me so I can ship free software using it.
I have yet to encounter an alternative build system with debug tooling comparable to msbuild (https://msbuildlog.com/ is incredible) or even 'remake' for makefiles.
Props to the meson folks for trying to write good documentation, though - the stuff on their website is very detailed.
When qemu adopted Meson they spent a lot of developer effort extending Meson, so I guess that's the answer. Unfortunately it means you need Meson >= some high version to compile qemu which had some knock-on effects elsewhere (like not being able to use older distros).
QEMU can be built on older distros even though it requires fairly new Meson, because Meson is easy to embed in the QEMU tarbell's (and in the repo as a submodule).
The port only required two custom-developed features, though. Contributing those was a minor piece of the whole effort.
As someone who still mostly uses make and looks warily at cmake, the proliferation of new build systems makes me nervous. Nervous because there are so many choices and the number seems to grow by the day and it's hard to tell what the next big build tool will end up being.
If make is good enough for you, by all means use it. I also use it for a variety of projects that don't need anything more complicated.
People bring in autotools / cmake / meson when they have more complicated requirements than just "one target to build, one target to install" and don't want to write that logic by hand. Feature flags, optional dependencies, dependency compatibility tests, those sorts of things.
A bunch of tools I work with have recently adopted Meson - things like qemu and libvirt. It's obviously better than autotools, but almost anything is. It also generates Ninja files which makes very parallel builds by default, which is great. Some downsides: I really don't like the configuration. I think using a (sort of) general purpose imperative language was probably a mistake. (Either go all-Python, or do something declarative). I also really dislike out of tree builds and wish it just let you do an in-tree build. So for me it's a mix of good and bad, with the parallel performance being the best thing.
I like to see a complex build system as a data flow setup where the configuration is the input and the build artifacts are the output. Meson supports that model nicely, and it hides (mostly) what happens at configuration time from what happens at build time. Future versions of Meson could move bits from Meson-time to ninja-time transparently.
This, plus the fact that there is no aliasing (objects are either immutable or copied on assignment), means the imperative nature is mostly hidden. Heavily macroized Makefiles can have much more of an imperative style than meson.build files.
I like when a project I downloaded uses CMake because then I already know how to build it. Just the same old "mkdir;cd;cmake ..;build" I always do, maybe with some custom option flags.
But using CMake for my own projects? Hell no. The concept of a DSL for build systems just seems awful to me. A shitty build system is one where you have to rely on "magic" commands/flags/options to get it to do what you want. A DSL is an entire language dedicated to magic commands. Why would I want to go through the pain of mastering that, even if the documentation were decent?
My current go-to build system for non trivial projects is waf. It's got some really interesting ideas (like describing builds using aspect-oriented programming), but most importantly it has you use straight up Python to write your build scripts. No DSL or special formats.
There are other build systems that use general purpose languages to describe builds like premake/xmake which use Lua, Gradle which uses Groovy and Kotlin, or Scons which uses Python (and inspired waf). Personally, I think Python is much more comfortable for working with strings and files, but I'd prefer any of those build systems over something like CMake or Meson.
From my point of view waf is just a different set of magic that happens to be hosted inside a python VM.
Now, admittedly, it looks like a rather nice set of magic and I'm glad you've mentioned it but the execution is still inside the tool, not in the user provided code, so it's still a DSL, just an internal rather than external one.
Honestly the main problem with external DSLs for this sort of work is the authors tend to underestimate how much programmability they'll need so the language ends up a bit pants, but waf is still a DSL just like chef is a DSL so your specific criticism seems a bit misplaced.
Also, "not being Turing complete" can absolutely have its advantages - depends on your environment and your team.
It was admittedly a decade ago at this point, but I used waf before I used CMake. The thing about CMake is that it has an ugly language, but a fairly simple model of the compilation process.
The first week I started using CMake, I set up a project that built a program, then used that program to generate some code from an input file, then compiled that code as part of a library, then included that library as part of a larger application.
I'd previously spent much longer trying to get that working in waf. I just couldn't figure out how to properly define dependency relationships for anything besides the built-in languages. It looked like it would be simple, but I could never get it to actually work (correctly handling incremental builds and parallel compilation).
Waf has probably improved significantly since I last tried it, but the point of this story is that I agree with you. Learning a build system is more than just learning a language. You have to learn a data model and the functions that manipulate it. In my case, that was more difficult than learning a crufty macro language.
> the execution is still inside the tool, not in the user provided code, so it's still a DSL, just an internal rather than external one.
That seems like a weird way to frame it. Waf is just a python API bundled with a command line interface, all packaged as a self-extracting zip file of python scripts.
The code that runs is the code that you write using that API. Calling that magic would be a stretch I think because its pretty hard to use an API if you dont know how it works. Plus, the Waf core is tiny and always in your source tree.
I guess one could argue that all APIs are DSLs, but I think thats a stretch.
> Also, "not being Turing complete" can absolutely have its advantages - depends on your environment and your team.
This is true, and a very relevant example of that is when the Amazon Lumberyard team switched from waf to CMake a few months back. Their waf(fork)-based build system was an unholy mess inherited from Crytek, and a common pain point for end users who just wanted to compile their games.
Not sure if CMake will help them maintain discipline among the build team, but it certainly will make the project more friendly to their external customers.
> and now I'm going to read more waf docs
RIP your sanity. The waf docs are written for people who already know waf. The only way to really learn it is to dig through the source. I became the unfortunate victim of Lumberyard’s build system a few years ago and that was what drove me to learn it (I dont like to lose to software). Luckily, I ended up loving it.
So unless you have extra motivation and/or time, I wouldnt recommend it (even though I love it)
Meson is amazing. I find that when I bootstrap with it, I write actual code than a wrestling match getting what I need set. I recently discovered it’d ability to wrap cmake subprojects with the cmake module. It just works, and opens up a neat way to mix in packages from the cmake ecosystem instead of relying on pkg-config (or as a fallback).
Better to stick with CMake due to broad range of IDEs supporting CMake, including, Visual Studio, Visual Studio Code editor, Jetbrain's CLion, QtCreator, KDevelop IDE and also Eclipse IDE via plugin. Other building systems may even be better than CMake, but they may lack widespread IDE support. By using CMake a project can make it easier to other people contribute as all they need to do in order to navigate across a C or C++ project is opening a directory containing a CMakeLists.txt file.
Another advantage of CMake over Meson is that CMake is Turing-complete, supports user-defined functions and macros, and has capabilities to download other packages and sub-projects by itself. It is also worth mentioning the CMake ability to deal cross-platform annoyances such as, exporting DLL symbols, making symbols private, installing to a directory, compiling resources on Windows and so on.
Gstreamer uses it. Those are some smart guys and I trust their choices.
It's not an easy as make. But, it certainly is nice to specify different build directories with different settings and experiment in a clean way with each build. And you can incrementally update your config and only recompile that part.
I've used meson a decent amount and it's not bad. I really like the flexibility of cmake, though, but I'm sure meson can do most of the things I want I just don't know how yet.
I think a combination of - CMake has been around a _long_ time now, anything is slow to adopt in the C++ system, and people (rightly or wrongly) expect their build systems to be somewhat arcane - whilst CMake is in many cases magnitudes simpler and more portable than plain Makefiles/autoconf.
In short, I think it's hard-won, and hard to let go of.
Edit to add: Also, the "generates project files in multiple flavors/IDE format" makes it a very easy to sell as a path of migration, rather than a complete change.
In spite of being very hampered by a bad bespoke programming language tacked on to its model, it does most of the things a meta-build system needs to do and it does them well, and it does them without needing java or python or basically a TSR server component running in the background to make it fast.
I think a lot of that can be chalked up to the fact that the minds behind CMake are pretty consistently top-notch--most of the Kitware folks have at least one post-grad CS degree and have not insignificant levels of experience approaching design problems from a more abstract/academic POV than your average dev team. I think over the years it's kept them from making the truly awful implementation blunders that send projects scrambling for another alternative just to 'never have to do THAT again.' Hence, CMake has had the time to seep into the way projects organize themselves in ways the "flavor of the month" build systems (qmake, scons, et al.) couldn't.
What I'd like to know is where this supposedly excellent documentation for Meson is that the author refers to. The times that I've needed to use Meson have been uniformly unpleasant precisely because I found the official docs to have a ton of holes and also assumed an unrealistic level of familiarity with their underlying logic. Give me the CMake docs anyday; at least I can be relatively sure the answer's in there instead of hiding in a GitHub issue regarding some design flaw that'll be solved in the next release.
I'm somewhat new to using C++ often enough to care about this. At times, it genuinely feels harder to link a project, than write the code.
Having come from a webdev background, where well publicised package managers have effectively directed how a project should be built, C++'s ecosystem looks to have created the opposite situation, where the utility of a project or library appears to dictate which build manager is used, in most cases.
Either you go with the grain and adopt your chosen library/environment's build system, or you increase the work you have to do.
I liked GYP a lot, and when starting out, was trying to stick with it, naively thinking that would be all I need to do. But soon enough realised that sticking with any one single package manager is impractical, unless you're prepared to effectively narrow your choice of libraries to a subset of what's available.
It seems like such an obvious problem, that I find it strange that the domain is still so fragmented.
At the very least, you'd wonder why potential rivals wouldn't aim to make their products CMake compatible to start, and then work from there.
It would be very hard, mostly. At least without just embedding cmake to begin with. The language is so quirky and the quirks even vary by version (if you have a cmake project long enough you'll start to see warnings about quirks you're relying on from old versions that you can flag on or off).
And at that point, your user's probably just gonna be asking "well I guess I may as well just use cmake."
CMake is the only build system with first class support for all of the major platforms - and those platforms' default tooling.
I can't tell you how much Visual Studio adding CMake support reduced the barrier to support cross platform C++ projects.
I'm a Linux user myself, but I interact with a lot of Windows developers and telling them to leave Visual Studio and use command line tools usually just means they won't be happy about working on a project.
One of my main use cases for CMake is that it works very well as a Windows, Mac, Linux cross-platform busybox. It allows to download files from the internet, unzip / untar, compute SHA hashes, do file system operations, ... in a very shell-like way (https://cmake.org/cmake/help/v3.21/manual/cmake.1.html#run-a...).
It's also been very useful in allowing to implement simple code parsing and generation thanks to its regex support, without having to install Perl (a pain on Win32), Bash (a pain on Win32), Python (same) and without requiring to build another binary doing the code parsing / code generation step (which generally causes a ton of problems as soon as you want to cross-compile since the code generation binary should be built with the host toolset - e.g. what if I want to run a code generator for a WASM target or some kind of VM as part of my build and don't want to have to run multiple build passes ?).
Finally I like that I don't have to put all my strings in "" unlike other build systems, I find it much more readable.
The Qt GUI has also been a very appreciated features of some of my users who:
- want to build of my software on their machine
- are technical enough to follow instructions on a GUI
- are not technical enough to use a terminal
which, from my experience, is a surprisingly large amount of people.
CMake is pretty good. However I have seen meson displacing autotools on several high profile projects, which is easy because autotools is horrible and full of footguns[1], and even those like me who use autotools all the time really don't like it very much.
[1] Edit: An example of an autoconf footgun: We recently discovered that --disable-<FEATURE> for several features in nbdkit didn't work because we didn't use the AC_ARG_ENABLE macro correctly. When you used --disable-foo it actually enabled foo. How is it possible to design something like AC_ARG_ENABLE which is so easy to use incorrectly! https://gitlab.com/nbdkit/nbdkit/-/commit/be1fe9abb8e3a3448b...
Am I thinking of it wrong, and using it as a "layer" above CMake to do the heavy dependency lifting is an intended part of Meson? Cmake has _huge_ support and mindshare in terms of third party packages and dependencies, even if it is somewhat difficult to learn "good" methods of writing CMakeLists.
I feel like spending the effort to learn a complete new build configuration metalanguage - and having to rewrite dependency discovery/builds, would be better spent on something like Bazel and it's mass-distributed compile capabilities, rather than something that looks just like cmake but with a new and unique language that to general approximation nobody else uses.
This is admittedly a rather uncharitable and possibly unfair way of looking at it - and I don't begrudge anyone trying to find a way of writing builds that fits better with them. Perhaps It's just a personal bias and I'm just getting to the age where learning a tool thoroughly and writing stuff that other people have a higher chance of experience in becomes more important than chasing... whatever it is that people value in this. (Or perhaps I have been too burnt by insanely complex badly implemented fragile SCons systems and not enough bad CMake systems).