God awful ugly abomination of a language, but it does the work, and is almost universally supported.
I kinda get the rationale that no abstraction primitive should drive common patterns into the standard Meson distribution (an approach which has problems too, but at least it makes sense to me).
However, seeing function definitions rejected on the basis of Turing-completeness raised serious doubts about the project at the time, and things haven't changed much on this front apparently[1]
[1]: https://mesonbuild.com/Syntax.html#userdefined-functions-and...
I think there are a lot of exaggerations around here. I have been a Meson user for long moving from CMake. CMake is quite more frustrating.
Nothing, when applicable this works and we're doing it already, thank you.
But it doesn't as soon as one needs to abstract over CMake commands themselves (like add this target, set that target property, add this test and so on). Of course we could try to generate CMake files in wrapper scripts, but this is another level of CMake juggling entirely.
> CMake is quite more frustrating.
Could not agree more.
But even more frustrating than CMake programming is Meson checking almost all the boxes yet refusing to provide that last one bit of functionality that would make me switch to it (and giving a wrong justification for it).
Take waf for example: it’s effectively a Python framework for creating a custom build system, with every single internal feature accessible (and documented) with good design instead of abstractions. In waf, you can do things like:
* define custom build Tasks
* have those Tasks spawn other Tasks dynamically (e.g. by parsing the stdout of a compiler to find output files)
* Extend/modify the behavior of existing Task classes (e.g. the C/C++ linker)
* Modify the task scheduler to control execution order
* Implement commands that analyze your build scripts (e.g. to generate a compile_commands.json file, or anything else)
* cache any serializable Python types between build invications
* create reusable project-agnostic build scripts
* wrap everything in a nice API so that build scripts are manageable
* rich debugging features
Not to mention the expressive syntax of Python and the full power of the standard library.
And all you need is a Python interpreter (2.7 and 3+ both work), as Waf has zero dependencies.
The learning curve is high, but it’s worth it for projects that have a lot of build complexity. In my case, I use CMake until a project needs custom functions, or needs to support multiple languages, then I switch to waf.
In waf, it's possible to implement everything you need for that in a highly efficient way: the 'scanner' method that parses XML files to find linked resources to setup dependencies, the task that generates the header file with optional decompression API, etc. Because the task scheduler is flexible and programmable, you can implement it so that nothing runs unless it absolutely has to. Even the dependency scanner can cache data between builds so that it doesn't need to re-scan for dependencies unless any of the files it found in a previous invocation changed (hash, timestamp, etc)
For example: MyData.xml links to CoolStuff.xml; user modifies the whitespace of CoolStuff.xml, so MyData.xml needs to be rebuilt; the Task that converts it into a new representation runs, but since whitespace didn't affect the output of that task, the output file's hash is identical to what it was before, so the other tasks don't detect a change, and the build ends immediately.
In CMake, it would be impossible to implement something comparable. With custom functions/external scripts you can technically do anything, but there's a lot of inefficiency both in runtime and development effort. Since CMake doesn't actually perform builds itself, it's limited in what you can directly do, and the DSL isn't powerful enough to take advantage of more flexible CMake internals even if they existed.
But if you only need to compile C and C++ files with some light scripting, CMake is far superior for a lot of reasons.
At the end of the day, I don't want to have to know any build system let alone CMake. Period. Full stop.
I want my build system to be declarative. That way, when it breaks, and it will break, I can fix the dumb thing. (Here's an example of the kind of breakage that CMake has: I can't compile with "zig cc" and friends, because there's a space in that compile command and CMake has baked-in parsing. Whoops. Yeah, CMake is slowly fixing that, but it's going to take forever to roll out a fix for something that shouldn't be in scope of the build system.)
The fact that your project's build system needs complex features should be treated as a gigantic red klaxon to me, as a user, to stay far, far away from it. Needing to use complex features for build means that you need to reorganize your project and/or your "build system" needs to be broken apart into phases that are containing the complexity.
I am picking on CMake here, but this is a failure of any build system that tries to do "too much". Cargo, from Rust, has similar problems.