The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
5.1 KiB
203 lines
5.1 KiB
# 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. |
|
|
|
## Set compiler |
|
|
|
When first running Meson, set it in an environment variable. |
|
|
|
```console |
|
$ 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 |
|
(such as `/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 |
|
|
|
```meson |
|
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. |
|
|
|
```meson |
|
executable(..., override_options : ['c_std=c11']) |
|
``` |
|
|
|
## Enable threads |
|
|
|
Lots of people seem to do this manually with `find_library('pthread')` |
|
or something similar. Do not do that. It is not portable. Instead do |
|
this. |
|
|
|
```meson |
|
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. |
|
|
|
```console |
|
$ CFLAGS=-fsomething LDFLAGS=-Wl,--linker-flag meson <options> |
|
``` |
|
|
|
## Use an argument only with a specific compiler |
|
|
|
First check which arguments to use. |
|
|
|
```meson |
|
if meson.get_compiler('c').get_id() == 'clang' |
|
extra_args = ['-fclang-flag'] |
|
else |
|
extra_args = [] |
|
endif |
|
``` |
|
|
|
Then use it in a target. |
|
|
|
```meson |
|
executable(..., c_args : extra_args) |
|
``` |
|
|
|
If you want to use the arguments on all targets, then do this. |
|
|
|
```meson |
|
if meson.get_compiler('c').get_id() == 'clang' |
|
add_global_arguments('-fclang-flag', language : 'c') |
|
endif |
|
``` |
|
|
|
## Set a command's output to configuration |
|
|
|
```meson |
|
txt = run_command('script', 'argument').stdout().strip() |
|
cdata = configuration_data() |
|
cdata.set('SOMETHING', txt) |
|
configure_file(...) |
|
``` |
|
|
|
## Generate a runnable script with `configure_file` |
|
|
|
`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. |
|
|
|
```console |
|
$ meson <other flags> -Db_coverage=true |
|
``` |
|
|
|
Then issue the following commands. |
|
|
|
```console |
|
$ 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 |
|
compiler flag `-Og` for this. To enable its use, just issue the |
|
following command. |
|
|
|
```console |
|
$ 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 |
|
sanitizer](https://clang.llvm.org/docs/AddressSanitizer.html). Meson |
|
has native support for these with the `b_sanitize` option. |
|
|
|
```console |
|
$ 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: |
|
|
|
```console |
|
$ ninja scan-build |
|
``` |
|
|
|
You can use the `SCANBUILD` environment variable to choose the |
|
scan-build executable. |
|
|
|
```console |
|
$ 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. |
|
|
|
```console |
|
$ 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. |
|
|
|
```console |
|
$ meson configure -Db_pgo=use |
|
$ ninja |
|
``` |
|
|
|
After these steps the resulting binary is fully optimized. |
|
|
|
## Add math library (`-lm`) portably |
|
|
|
Some platforms (e.g. Linux) have a standalone math library. Other |
|
platforms (pretty much everyone else) do not. How to specify that `m` |
|
is used only when needed? |
|
|
|
```meson |
|
cc = meson.get_compiler('c') |
|
m_dep = cc.find_library('m', required : false) |
|
executable(..., dependencies : m_dep) |
|
``` |
|
|
|
## Install an executable to `libexecdir` |
|
|
|
```meson |
|
executable(..., install : true, install_dir : get_option('libexecdir')) |
|
```
|
|
|