How do I do X in Meson?
This page lists code snippets for common tasks. These are written mostly using the C compiler, but the same approach should work on almost all other compilers.
When first running Meson, set it in an environment variable.
$ CC=mycc meson <options>
Note that environment variables like
CC always refer to the native
compiler. That is, the compiler used to compile programs that run on
the current machine. The compiler used in cross compilation is set
with the cross file.
This behaviour is different from e.g. Autotools, where cross
compilation is done by setting
CC to point to the cross compiler
/usr/bin/arm-linux-gnueabihf-gcc). The reason for this is
that Meson supports natively the case where you compile helper tools
(such as code generators) and use the results during the
build. Because of this Meson needs to know both the native and the
cross compiler. The former is set via the environment variables and
the latter via the cross file only.
Set default C/C++ language version
project('myproj', 'c', 'cpp', default_options : ['c_std=c11', 'cpp_std=c++11'])
The language version can also be set on a per-target basis.
executable(..., override_options : ['c_std=c11'])
Lots of people seem to do this manually with
or something similar. Do not do that. It is not portable. Instead do
thread_dep = dependency('threads') executable(..., dependencies : thread_dep)
Set extra compiler and linker flags from the outside (when e.g. building distro packages)
The behavior is the same as with other build systems, with environment variables during first invocation.
$ CFLAGS=-fsomething LDFLAGS=-Wl,--linker-flag meson <options>
Use an argument only with a specific compiler
First check which arguments to use.
if meson.get_compiler('c').get_id() == 'clang' extra_args = ['-fclang-flag'] else extra_args =  endif
Then use it in a target.
executable(..., c_args : extra_args)
If you want to use the arguments on all targets, then do this.
if meson.get_compiler('c').get_id() == 'clang' add_global_arguments('-fclang-flag', language : 'c') endif
Set a command's output to configuration
txt = run_command('script', 'argument').stdout().strip() cdata = configuration_data() cdata.set('SOMETHING', txt) configure_file(...)
Generate a runnable script with
configure_file preserves metadata so if your template file has
execute permissions, the generated file will have them too.
Producing a coverage report
First initialize the build directory with this command.
$ meson <other flags> -Db_coverage=true
Then issue the following commands.
$ ninja $ ninja test $ ninja coverage-html (or coverage-xml)
The coverage report can be found in the meson-logs subdirectory.
Add some optimization to debug builds
By default the debug build does not use any optimizations. This is the
desired approach most of the time. However some projects benefit from
having some minor optimizations enabled. GCC even has a specific
-Og for this. To enable its use, just issue the
$ meson configure -Dc_args=-Og
This causes all subsequent builds to use this command line argument.
Use address sanitizer
Clang comes with a selection of analysis tools such as the address
has native support for these with the
$ meson <other options> -Db_sanitize=address
After this you just compile your code and run the test suite. Address sanitizer will abort executables which have bugs so they show up as test failures.
Use Clang static analyzer
Install scan-build and configure your project. Then do this:
$ ninja scan-build
You can use the
SCANBUILD environment variable to choose the
$ SCANBUILD=<your exe> ninja scan-build
Use profile guided optimization
Using profile guided optimization with GCC is a two phase operation. First we set up the project with profile measurements enabled and compile it.
$ meson <Meson options, such as --buildtype=debugoptimized> -Db_pgo=generate $ ninja -C builddir
Then we need to run the program with some representative input. This step depends on your project.
Once that is done we change the compiler flags to use the generated information and rebuild.
$ meson configure -Db_pgo=use $ ninja
After these steps the resulting binary is fully optimized.
Add math library (
Some platforms (e.g. Linux) have a standalone math library. Other
platforms (pretty much everyone else) do not. How to specify that
is used only when needed?
cc = meson.get_compiler('c') m_dep = cc.find_library('m', required : false) executable(..., dependencies : m_dep)
Install an executable to
executable(..., install : true, install_dir : get_option('libexecdir'))
The results of the search are