| # 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. Do not use these when you need to rebuild |
| the source |
| |
| ```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')) |
| ``` |
| |
| ## Use existing `Find<name>.cmake` files |
| |
| Meson can use the CMake `find_package()` ecosystem if CMake is installed. |
| To find a dependency with custom `Find<name>.cmake`, set the `cmake_module_path` |
| property to the path in your project where the CMake scripts are stored. |
| |
| Example for a `FindCmakeOnlyDep.cmake` in a `cmake` subdirectory: |
| |
| ```meson |
| cm_dep = dependency('CmakeOnlyDep', cmake_module_path : 'cmake') |
| ``` |
| |
| The `cmake_module_path` property is only needed for custom CMake scripts. System |
| wide CMake scripts are found automatically. |
| |
| More information can be found [here](Dependencies.md#cmake) |