Meson
Meson project setup, build options, the wrap dependency system, and cross-compilation. Grounded against Meson 1.12.0; Meson drives Ninja as its backend.
Contract
| Field | Bound contract |
|---|---|
| Trigger | The task sets up a Meson project, writes meson.build or meson.options, manages wrap dependencies, configures build options, cross-compiles with a cross file, or migrates from CMake or Autotools. |
| Authority | Reversible local: writes only meson.build, meson.options/meson_options.txt, cross and native files, subprojects/, and the build directory; rollback is version control plus deleting the build directory. No remote mutation. |
| Side effect | meson compile and meson test write local build outputs; meson wrap install downloads wrap files into subprojects/. |
| Done | meson setup, meson compile, and meson test run clean on the configured build directory, or the failing command is reported. |
Inputs
- Project layout (required): sources and the root
meson.buildlocation. - Meson version (required if not inferrable): run
meson --version.meson.optionsneeds Meson 1.1 or newer; older trees usemeson_options.txt. - Dependencies (optional): system libraries or wrap names from WrapDB.
- Cross target (optional): a cross file describing the host machine.
Procedure
- Configure the build directory. Done when:
meson setup builddirsucceeds.
meson setup builddir
meson setup builddir \
--buildtype=release \
--prefix=/usr/local \
-Db_lto=true \
-Db_sanitize=address
meson configure builddir -Dbuildtype=debug # reconfigure in place
meson configure builddir # list all options
--buildtype |
Flags added |
|---|---|
debug (default) |
-O0 -g |
debugoptimized |
-O2 -g |
release |
-O3 -DNDEBUG |
minsize |
-Os -DNDEBUG |
plain |
none |
custom |
user-supplied flags only |
- Build, test, and install. Done when: compile and test pass in the build directory.
meson compile -C builddir
meson test -C builddir
meson test -C builddir --verbose
meson test -C builddir -t 5 # 5x timeout multiplier
meson test -C builddir --suite unit # one suite only
meson install -C builddir
meson install -C builddir --dry-run
- Write
meson.build. Done when: every target declares its sources, includes, and dependencies.
project('myapp', 'c', 'cpp',
version : '1.0.0',
default_options : [
'c_std=c23',
'cpp_std=c++23',
'warning_level=2',
]
)
glib_dep = dependency('glib-2.0', version : '>=2.68')
threads_dep = dependency('threads')
inc = include_directories('include')
mylib = static_library('mylib',
sources : ['src/lib.c', 'src/util.c'],
include_directories : inc,
)
executable('myapp',
sources : ['src/main.c'],
include_directories : inc,
link_with : mylib,
dependencies : [glib_dep, threads_dep],
install : true,
)
test('basic', executable('test_basic',
sources : ['tests/test_basic.c'],
link_with : mylib,
))
- Manage dependencies with wrap. Done when:
dependency()resolves from the system or falls back to the wrap.
meson wrap search zlib
meson wrap install zlib
meson wrap list
meson wrap update
# System first, wrap as fallback
zlib_dep = dependency('zlib', fallback : ['zlib', 'zlib_dep'])
# Force the wrap for reproducible builds
zlib_dep = dependency('zlib',
fallback : ['zlib', 'zlib_dep'],
default_options : ['default_library=static'],
)
- Define project options in
meson.options(Meson 1.1+) ormeson_options.txt. Done when:meson configurelists the option andget_optionreads it.
option('with_tests', type : 'boolean', value : true,
description : 'Build unit tests')
option('backend', type : 'combo',
choices : ['opengl', 'vulkan', 'software'],
value : 'opengl')
option('max_connections', type : 'integer',
min : 1, max : 1024, value : 64)
if get_option('with_tests')
subdir('tests')
endif
- Cross-compile with a cross file. Use
pkg-configas the key name;pkgconfigis deprecated. Done when:meson setup --cross-fileconfigures for the host machine.
# cross/arm-linux.ini
[binaries]
c = 'arm-linux-gnueabihf-gcc'
cpp = 'arm-linux-gnueabihf-g++'
ar = 'arm-linux-gnueabihf-ar'
strip = 'arm-linux-gnueabihf-strip'
pkg-config = 'arm-linux-gnueabihf-pkg-config'
[properties]
sys_root = '/path/to/sysroot'
[host_machine]
system = 'linux'
cpu_family = 'arm'
cpu = 'cortex-a9'
endian = 'little'
meson setup builddir-arm --cross-file cross/arm-linux.ini
meson compile -C builddir-arm
- Migrate from CMake with this mapping. Done when: each CMake construct has its Meson equivalent.
| CMake | Meson |
|---|---|
add_executable |
executable() |
add_library |
library(), static_library(), shared_library() |
target_include_directories |
include_directories kwarg |
target_link_libraries |
dependencies and link_with kwargs |
find_package |
dependency() |
option() |
option() in meson.options |
add_subdirectory |
subdir() |
install(TARGETS ...) |
install : true kwarg |
For wrap file types, subproject patching, and compiler checks see references/meson-wrap.md.
Failure and recovery
dependency()fails and no wrap exists: runmeson wrap search <name>; if WrapDB lacks it, vendor the source undersubprojects/with its ownmeson.build.meson setuprejects an option: the option lives inmeson.optionsor is a built-in-Dname; runmeson configure builddirto list valid names.- Cross build picks up host libraries: the cross file needs
sys_rootunder[properties]and correctpkg-configunder[binaries]. - Wrap download fails offline: pre-seed
subprojects/packagecache/with the archive named in the wrap'ssource_url. - Reconfigure does not take: some options are read once at setup; wipe the build directory with
meson setup --wipe builddiror delete it and reconfigure.
Output
A working meson.build with declared targets and dependencies, a configured build directory that compiles and tests clean, and for cross tasks a cross file verified by meson setup --cross-file.