Hey! I'm not in any way affiliated with the Meson team, but I've recently had a great experience with their build system and hope to spark some interest with those who think the current CMake build system could still be improved.
From what a quick search through the issue tracker yields, this discussion hasn't come up before. Basically, Meson is a relatively contemporary (≈ five years old) build system that shares many similarities with CMake, but has a notion of "objects" that can be used as expessions themselves.
For instance, the expression
executable('demo', 'main.c')
will not only add an executable named demo that requires main.c to the dependency tree, but also evaluates to an object of type buildtarget, which can then be used in other expressions, like in the integrated unit test runner using the test function:
demo = executable('demo', 'main.c')
test('Demo works', demo)
(Yeah, their syntax is pretty simple/pythonic.)
What's interesting is that it has some very notable/huge adopters; among which are
systemd,Xorg,gtk+,gstreamer,radare2, andSome of these projects have dropped their previous build systems in favor of Meson, others allow their projects to be built with Meson and their previous build system.
I'd like to ask and discuss what the current perspective among citra developers is regarding Meson, and if there is interest to explore this build system further, maybe even adopting it.
While there are most certainly issues with the CMake solution, I don't see how this will benefit us at all.
All of our dependencies use CMake as well (which would require us to rewrite that stack from scratch, which is nontrivial), would require shipping tool(s) not available on many platforms by default (esp. Windows, the main platform we target), and doesn't integrate well with many current development environments (Visual Studio, CLion, Android).
Appreciate the concern, but fixing up any apparent issues with CMake would make much more sense.
I somewhat echo @j-selby's comment as well. I also don't think a one-liner as an example is necessarily a decent display of a build system's introductory feature set, considering CMake's is slightly similar:
add_executable(SomeExecutable main.cpp)
which introduces a target SomeExecutable, which can be used by name in other commands that operate on targets.
How well does it handle cases like the following that can occur: Say I specify a project to be C++17:
project('SomeProject', 'cpp', default_options : ['cpp_std=c++17'])
is this guaranteed to work seamlessly with compilers that support both -std=c++17 and -std=c++1z and compilers that only currently support -std=c++1z? (which can happen on platforms where one compiler is more up to date than the other in a package manager, for example)
For build options how painless does it make working with dependent options? e.g. say we have both
Assume A can be enabled by itself but is disabled by default.
Assume B can be enabled, but would also imply the use of A.
Is there a way to enable both in one line if B is enabled but not A, or do both options' state need to be queried in an if-else conditional and be modified accordingly?
From a dependency point of view, this also introduces Python as a requirement for building the emulator on-top-of/underneath Meson (depending on how you look at it), while we only currently require a C++ compiler and CMake.
The following is mostly opinion-based, so this can be skipped if you want:
I'm also not particularly fond of how variables work in this build system. In particular, from the part on syntax on Meson's website:
Variables don't need to be predeclared, you can just assign to them and they appear.
This can lead to annoying to trace/debug issues if a variable is accidentally misspelled. It shouldn't happen often, but when it does it's still going to be a headache in a sufficiently large project depending on where it occurs. It's also unfortunate that Meson doesn't seem to have any means to make an introduced variable fully constant to avoid accidental assigning to the wrong variable as well. CMake doesn't have this either, but I'd have expected a newer build system to have a means to make fixed objects to make that entire logical error case a thing of the past. I guess what I'm saying here is this build system seems to encourage mutability more than necessary without a means of conditionally avoiding or preventing the potential class of errors that follow suit with it. Not that CMake is any better, mind; however the difference here is CMake is more or less known to the maintainers of the project, Meson isn't.
Very valid concerns; I'd like to address some.
is this guaranteed to work seamlessly with compilers that support both
-std=c++17and-std=c++1zand compilers that only currently support-std=c++1z?
From my understanding, your declaration should be identical to CMake's set(CMAKE_CXX_STANDARD 17). However, I also went through their source and saw that while they do handle the flags according to the compiler version for the Intel compiler, they don't do that for clang for some reason (maybe worth a PR…). Also, I couldn't find 1z → 17 transformations anywhere, though there was an interesting comment regarding that in their issue tracker back from when the project was started.
Other than that, their abstraction appears to be sane. For instance, warning_level is an integer-option within [0, 3] that adds corresponding flags (on gcc/clang, something like -Wall or -Wpedantic), which also works in VS.
They also allow to add an option based on whether the compiler has support for it or not, which can be handy and also offers a workaround until they get c++1z right:
legacyCpp17 = '-std=c++1z'
if cc.has_argument(legacyCpp17)
cflags += legacyCpp17
endif
Meson does have a Visual Studio back-end. They also have a page that explains how to use Meson with Visual Studio, though of course, it's not an integrated feature that Microsoft is working on.
When it comes to IDE integration for open-source editors, I'll just point the interested reader here for now.
Also have a look at https://github.com/mesonbuild/meson/issues/1300.
All of our dependencies use CMake as well (which would require us to rewrite that stack from scratch, which is nontrivial)
This is a pain point, yes. Similar to CMake, Meson offers a whole set of functions related to finding or declaring (system/subproject) dependencies. As far as I know, the automated search relies on pkg-config-style .pc files, but you can also declare dependencies manually.
They also offer native support for Qt and show how to tackle SDL2, GTest, Boost and a few more.
Currently, they don't offer a way to declare dependencies between options. Can't say if they feel that there's too much magic involved for their taste or if it simply hasn't been implemented yet; so yes, you would have to write:
option('A', type: 'boolean', value: false)
option('B', type: 'boolean', value: false)
a = get_option('A')
b = get_option('B')
if b
a = true
endif
Meson also offers a build-system converter that will roughly transform a CMake-based build system to a Meson build system; to be fair, it should be noted that they say that manual finalization is probably required.
No objections, I couldn't agree more. Since their project is heavily Python-based, their syntax looks a lot like Python, which comes with the same flaw…
The primary concern of this issue was to bring alternatives to CMake to the attention of the team.
I'll go ahead and close this for now. If the future shows that most problems raised above are addressed by the Meson team, we can still re-open this. Thanks, everyone!
Most helpful comment
While there are most certainly issues with the CMake solution, I don't see how this will benefit us at all.
All of our dependencies use CMake as well (which would require us to rewrite that stack from scratch, which is nontrivial), would require shipping tool(s) not available on many platforms by default (esp. Windows, the main platform we target), and doesn't integrate well with many current development environments (Visual Studio, CLion, Android).
Appreciate the concern, but fixing up any apparent issues with CMake would make much more sense.