Meson

Meson is an open source build system for C, C++, Rust, Fortran, and other compiled languages, designed to be fast and pleasant to use. You describe targets in a declarative meson.build file; Meson configures the project in a separate build directory and generates files for a backend — almost always Ninja — that performs the actual compilation.

Meson's language is deliberately not Turing-complete: no user-defined functions, no arbitrary file manipulation in the configuration step. That restriction keeps builds readable and reliable. GNOME, systemd, Mesa, GStreamer, QEMU, and PostgreSQL (as an alternative to its traditional build) use Meson, and meson-python has made it a common backend for Python packages with compiled extensions such as NumPy and SciPy.

TL;DR

Quick Example

A meson.build for a small C program with a library, an external dependency, a fallback subproject, and a test:

Configuring, building, testing, and installing:

Core Concepts

The Build Definition

Variables, arrays, dictionaries, if, and foreach are available, but there are no user-defined functions, which keeps every build file understandable without tracing abstractions.

Build Directories and Backends

Meson never builds in the source tree. Each meson setup <dir> creates an independent configuration — debug, release, sanitizer, or cross builds side by side. The default backend generates Ninja files; Visual Studio and Xcode backends exist for IDE workflows. Reconfiguration happens automatically when build files change, and meson configure <dir> shows or changes options.

Dependencies

dependency() tries pkg-config, CMake package files, and built-in system lookups. When a dependency is missing, subprojects provide it: wrap files in subprojects/ describe how to download and build another project, and WrapDB hosts maintained wraps for many common libraries. Control fallback behavior with --wrap-mode (for example nofallback for distribution packaging, forcefallback for fully vendored builds).

Options and Build Types

Project-specific options live in meson.options (or the older meson_options.txt) and are read with get_option(). Built-in options include buildtype (debug, debugoptimized, release, minsize), b_sanitize, b_lto, warning_level, and werror:

Testing

meson test runs registered tests in parallel with timeouts, supports test suites, repeats (--repeat), and wrappers such as Valgrind (--wrapper), and writes JUnit-compatible logs for CI. meson test --gdb runs a failing test under a debugger.

Cross-Compilation

A cross file describes the target machine and toolchain:

Meson distinguishes the build machine (where compilation runs) from the host machine (where the result runs), so code generators that must run during the build are compiled natively with native : true.

Packaging and Distribution

Best Practices

Keep Build Logic Declarative

Use the built-in functions and modules instead of shelling out to scripts; Meson's restrictions exist to keep builds predictable.

Use Separate Build Directories per Configuration

Keep debug, release, sanitizer, and cross builds in different directories instead of reconfiguring one back and forth.

Prefer System Dependencies, With Wrap Fallbacks

Find dependencies through pkg-config first and use WrapDB fallbacks for developers and CI, while letting distributions disable fallbacks.

Run Tests and Sanitizers in CI

Build a sanitizer configuration and run meson test in CI to catch memory errors early.

Common Mistakes

Hard-Coding Compiler Flags

Manually Listing Include and Link Flags

Rebuilding One Directory for Every Configuration

FAQ

What is Meson?

An open source build system for compiled languages that uses a declarative, non-Turing-complete configuration language and generates build files for Ninja or IDE backends.

How is Meson different from CMake?

Both generate builds for backends such as Ninja. Meson has a smaller, stricter language with built-in conventions and focuses on simplicity; CMake has a larger ecosystem, broader IDE integration, and more flexibility. See CMake.

Does Meson replace Ninja?

No. Meson configures the project and generates Ninja build files; Ninja executes the build. See Ninja.

How do I handle missing dependencies?

Declare a fallback subproject using a wrap file, often installed from WrapDB with meson wrap install, so Meson can build the dependency when it is not available on the system.

Can Meson build Python packages?

Yes. The meson-python build backend builds Python wheels that contain compiled extensions; projects such as NumPy and SciPy use it.

Related Topics

References