The Meson build system

The main design point of Meson is that every moment a developer spends writing or debugging build definitions is a second wasted. So is every second spent waiting for the build system to actually start compiling code. - Meson

Prefer latest version >= 0.59 rather than prepackaged distrib version

Compiling a Meson project

The only thing to note is that you need to create a separate build directory. Meson will not allow you to build source code inside your source tree. All build artifacts are stored in the build directory.

meson.build file

$ mkdir test && cd test
$ meson init               # for creating project from scratch 
$ meson build && cd build
$ meson compile
$ meson test
project('tutorial', 'cpp')
gtkdep = dependency('gtk+-3.0')
executable('demo', 'main.cc', dependencies : gtkdep)

Subprojects

Meson allows you to take any other Meson project and make it a part of your build without (in the best case) any changes to its Meson setup. It becomes a transparent part of the project.

see also Subproject limitations

CMake based subprojects are also supported but not guaranteed to work.

# Configure the CMake project
cmake = import('cmake')

## folly CMake require https://github.com/fmtlib/fmt.git to be installed
libfolly = cmake.subproject('libfolly')

Wrap file tells Meson how to download it for you. If you then use this subproject in your build, Meson will automatically download and extract it during build. This makes subproject embedding extremely easy.

see Wrap DB/2, to automatically get them for known libs. For eg:

# get already existing wrap for imgui (which include the required patch to make it work with meson build system)
$ meson wrap install imgui

# use wrap to retrieve the dependancy and launch build
$ meson build .

Otherwise, they can be written manually. For eg: having in ./subprojects/libfolly.wrap, will have meson automatically get folly from git repos at url with proper revision.

[wrap-git]
url = https://github.com/facebook/folly.git
revision = v2021.06.14.00

.gitignore Meson subprojects - For Meson subprojects, using the negate .gitignore syntax Git will ignore subdirectories but track the subprojects/*.wrap files, by including in the project top-level .gitignore:

/subprojects/*
!/subprojects/*.wrap

Native config files

Meson has separation between project build descriptions in meson.build, and compilation environment / toolchain descriptions in native/cross files.

Native files (–native-file) are the counterpart to cross files (–cross-file), and allow specifying information about the build machine, both when cross compiling and when not.

# ~/.local/share/meson/cross/codingame
# meson builddir/ --native-file codingame
[binaries]               
cpp = 'g++-9'

Cross compilation

Meson requires you to write a cross build definition file. It defines various properties of the cross build environment. The cross file consists of different sections.

Let’s suppose you are on a 64 bit OSX machine and you are cross compiling a binary that will run on a 32 bit ARM Linux board. In this case your build machine is 64 bit OSX, your host machine is 32 bit ARM Linux and your target machine is irrelevant (but defaults to the same value as the host machine).

ARM Cross compilation

your host_machine is ARM Linux

# ~/.local/share/meson/cross/remarkable
# meson builddir/ --cross-file remarkable
[host_machine]               
system = 'linux'             
cpu_family = 'arm'           
cpu = 'armv7l'            
endian = 'little'

Meson vs X / SO

Why I’d choose Meson+Doctest tech stack to create a new C++ project with a reusable and easy-to-run example - Choosing a Modern C++ stack / The Rise of Meson

Typical build

$ meson build .  (1)
$ cd build
$ ninja build    (2)
$ ninja test     (3)
  1. First time you configure the project
  2. Each time you build it
  3. Each time you run tests

Install !!

Due to our frequent release cycle and development speed, distro packaged software may quickly become outdated.

To install with sudo ninja install you need to have meson & ninja available for root user. And you need root meson in the same version as the one having build the project.

# sudo -i   # for root install
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3 get-pip.py
$ python3 -m pip install meson

Features

  • multiplatform support for Linux, macOS, Windows, GCC, Clang, Visual Studio and others
  • supported languages include C, C++, D, Fortran, Java, Rust
  • build definitions in a very readable and user friendly non-Turing complete DSL
  • cross compilation for many operating systems as well as bare metal optimized for extremely fast full and incremental builds without sacrificing correctness
  • built-in multiplatform dependency provider that works together with distro packages

FAQ

Written on August 12, 2020, Last update on December 10, 2023
build-system dlang c++