1--- 2short-description: Build-time configuration options 3... 4 5# Configuration 6 7If there are multiple configuration options, passing them through 8compiler flags becomes very burdensome. It also makes the 9configuration settings hard to inspect. To make things easier, Meson 10supports the generation of configure files. This feature is similar to 11one found in other build systems such as CMake. 12 13Suppose we have the following Meson snippet: 14 15```meson 16conf_data = configuration_data() 17conf_data.set('version', '1.2.3') 18configure_file(input : 'config.h.in', 19 output : 'config.h', 20 configuration : conf_data) 21``` 22 23and that the contents of `config.h.in` are 24 25```c 26#define VERSION_STR "@version@" 27``` 28 29Meson will then create a file called `config.h` in the corresponding 30build directory whose contents are the following. 31 32```c 33#define VERSION_STR "1.2.3" 34``` 35 36More specifically, Meson will find all strings of the type `@varname@` 37and replace them with respective values set in `conf_data`. You can 38use a single `configuration_data` object as many times as you like, 39but it becomes immutable after being passed to the `configure_file` 40function. That is, after it has been used once to generate output the 41`set` function becomes unusable and trying to call it causes an error. 42Copy of immutable `configuration_data` is still immutable. 43 44For more complex configuration file generation Meson provides a second 45form. To use it, put a line like this in your configuration file. 46 47 #mesondefine TOKEN 48 49The replacement that happens depends on what the value and type of TOKEN is: 50 51```c 52#define TOKEN // If TOKEN is set to boolean true. 53#undef TOKEN // If TOKEN is set to boolean false. 54#define TOKEN 4 // If TOKEN is set to an integer or string value. 55/* undef TOKEN */ // If TOKEN has not been set to any value. 56``` 57 58Note that if you want to define a C string, you need to do the quoting 59yourself like this: 60 61```meson 62conf_data.set('TOKEN', '"value"') 63``` 64 65Since this is such a common operation, Meson provides a convenience 66method: 67 68```meson 69plain_var = 'value' 70conf_data.set_quoted('TOKEN', plain_var) # becomes #define TOKEN "value" 71``` 72 73Often you have a boolean value in Meson but need to define the C/C++ 74token as 0 or 1. Meson provides a convenience function for this use 75case. 76 77```meson 78conf_data.set10(token, boolean_value) 79# The line above is equivalent to this: 80if boolean_value 81 conf_data.set(token, 1) 82else 83 conf_data.set(token, 0) 84endif 85``` 86 87## Configuring without an input file 88 89If the input file is not defined then Meson will generate a header 90file all the entries in the configuration data object. The 91replacements are the same as when generating `#mesondefine` entries: 92 93```meson 94conf_data.set('FOO', '"string"') => #define FOO "string" 95conf_data.set('FOO', 'a_token') => #define FOO a_token 96conf_data.set('FOO', true) => #define FOO 97conf_data.set('FOO', false) => #undef FOO 98conf_data.set('FOO', 1) => #define FOO 1 99conf_data.set('FOO', 0) => #define FOO 0 100``` 101 102In this mode, you can also specify a comment which will be placed 103before the value so that your generated files are self-documenting. 104 105```meson 106conf_data.set('BAR', true, description : 'Set BAR if it is available') 107``` 108 109Will produce: 110 111```c 112/* Set BAR if it is available */ 113#define BAR 114``` 115 116## Dealing with file encodings 117 118The default meson file encoding to configure files is utf-8. If you need to 119configure a file that is not utf-8 encoded the encoding keyword will allow 120you to specify which file encoding to use. It is however strongly advised to 121convert your non utf-8 file to utf-8 whenever possible. Supported file 122encodings are those of python3, see [standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings). 123 124## Using dictionaries 125 126Since *0.49.0* `configuration_data()` takes an optional dictionary as first 127argument. If provided, each key/value pair is added into the 128`configuration_data` as if `set()` method was called for each of them. 129`configure_file()`'s `configuration` kwarg also accepts a dictionary instead of 130a configuration_data object. 131 132Example: 133```meson 134cdata = configuration_data({ 135 'STRING' : '"foo"', 136 'INT' : 42, 137 'DEFINED' : true, 138 'UNDEFINED' : false, 139}) 140 141configure_file(output : 'config1.h', 142 configuration : cdata, 143) 144 145configure_file(output : 'config2.h', 146 configuration : { 147 'STRING' : '"foo"', 148 'INT' : 42, 149 'DEFINED' : true, 150 'UNDEFINED' : false, 151 } 152) 153 154``` 155 156# A full example 157 158Generating and using a configuration file requires the following steps: 159 160 - generate the file 161 - create an include directory object for the directory that holds the file 162 - use it in a target 163 164We are going to use the traditional approach of generating a header 165file in the top directory. The common name is `config.h` but we're 166going to use an unique name. This avoids the problem of accidentally 167including the wrong header file when building a project with many 168subprojects. 169 170At the top level we generate the file: 171 172```meson 173conf_data = configuration_data() 174# Set data 175configure_file(input : 'projconfig.h.in', 176 output : 'projconfig.h', 177 configuration : conf_data) 178``` 179 180Immediately afterwards we generate the include object. 181 182```meson 183configuration_inc = include_directories('.') 184``` 185 186Finally we specify this in a target that can be in any subdirectory. 187 188```meson 189executable(..., include_directories : configuration_inc) 190``` 191 192Now any source file in this target can include the configuration 193header like this: 194 195```c 196#include<projconfig.h> 197``` 198