configure_file: Support taking values from a dict

Closes #4218
pull/4354/head
Xavier Claessens 6 years ago committed by Jussi Pakkanen
parent 1e7aea65e6
commit 38a6582145
  1. 32
      docs/markdown/Configuration.md
  2. 9
      docs/markdown/Reference-manual.md
  3. 22
      mesonbuild/interpreter.py
  4. 24
      test cases/common/14 configure file/meson.build
  5. 18
      test cases/common/14 configure file/prog9.c

@ -121,6 +121,38 @@ you to specify which file encoding to use. It is however strongly advised to
convert your non utf-8 file to utf-8 whenever possible. Supported file
encodings are those of python3, see [standard-encodings](https://docs.python.org/3/library/codecs.html#standard-encodings).
## Using dictionaries
Since *0.49.0* `configuration_data()` takes an optional dictionary as first
argument. If provided, each key/value pair is added into the
`configuration_data` as if `set()` method was called for each of them.
`configure_file()`'s `configuration` kwarg also accepts a dictionary instead of
a configuration_data object.
Example:
```meson
cdata = configuration_data({
'STRING' : '"foo"',
'INT' : 42,
'DEFINED' : true,
'UNDEFINED' : false,
})
configure_file(output : 'config1.h',
configuration : cdata,
)
configure_file(output : 'config2.h',
configuration : {
'STRING' : '"foo"',
'INT' : 42,
'DEFINED' : true,
'UNDEFINED' : false,
}
)
```
# A full example
Generating and using a configuration file requires the following steps:

@ -167,13 +167,17 @@ methods section](#build-target-object) below.
### configuration_data()
``` meson
configuration_data_object = configuration_data()
configuration_data_object = configuration_data(...)
```
Creates an empty configuration object. You should add your
configuration with [its method calls](#configuration-data-object) and
finally use it in a call to `configure_file`.
Since *0.49.0* takes an optional dictionary as first argument. If provided, each
key/value pair is added into the `configuration_data` as if `set()` method was
called for each of them.
### configure_file()
``` meson
@ -187,7 +191,8 @@ When a [`configuration_data()`](#configuration_data) object is passed
to the `configuration:` keyword argument, it takes a template file as
the `input:` (optional) and produces the `output:` (required) by
substituting values from the configuration data as detailed in [the
configuration file documentation](Configuration.md).
configuration file documentation](Configuration.md). Since *0.49.0* a dictionary
can be passed instead of a [`configuration_data()`](#configuration_data) object.
When a list of strings is passed to the `command:` keyword argument,
it takes any source or configured file as the `input:` and assumes

@ -2372,9 +2372,18 @@ external dependencies (including libraries) must go to "dependencies".''')
@noKwargs
def func_configuration_data(self, node, args, kwargs):
if args:
raise InterpreterException('configuration_data takes no arguments')
return ConfigurationDataHolder(self.subproject)
if len(args) > 1:
raise InterpreterException('configuration_data takes only one optional positional arguments')
elif len(args) == 1:
initial_values = args[0]
if not isinstance(initial_values, dict):
raise InterpreterException('configuration_data first argument must be a dictionary')
else:
initial_values = {}
cdata = ConfigurationDataHolder(self.subproject)
for k, v in initial_values.items():
cdata.set_method([k, v], {})
return cdata
def set_options(self, default_options):
# Set default options as if they were passed to the command line.
@ -3552,7 +3561,12 @@ root and issuing %s.
# Perform the appropriate action
if 'configuration' in kwargs:
conf = kwargs['configuration']
if not isinstance(conf, ConfigurationDataHolder):
if isinstance(conf, dict):
cdata = ConfigurationDataHolder(self.subproject)
for k, v in conf.items():
cdata.set_method([k, v], {})
conf = cdata
elif not isinstance(conf, ConfigurationDataHolder):
raise InterpreterException('Argument "configuration" is not of type configuration_data')
mlog.log('Configuring', mlog.bold(output), 'using configuration')
if inputfile is not None:

@ -246,3 +246,27 @@ test('configure-file', test_file)
cdata = configuration_data()
cdata.set('invalid_value', ['array'])
# Dictionaries
cdata = configuration_data({
'A_STRING' : '"foo"',
'A_INT' : 42,
'A_DEFINED' : true,
'A_UNDEFINED' : false,
})
configure_file(output : 'config9a.h',
configuration : cdata,
)
configure_file(output : 'config9b.h',
configuration : {
'B_STRING' : '"foo"',
'B_INT' : 42,
'B_DEFINED' : true,
'B_UNDEFINED' : false,
}
)
test('test9', executable('prog9', 'prog9.c'))

@ -0,0 +1,18 @@
#include <string.h>
#include <config9a.h>
#include <config9b.h>
#if defined(A_UNDEFINED) || defined(B_UNDEFINED)
#error "Should not be defined"
#endif
#if !defined(A_DEFINED) || !defined(B_DEFINED)
#error "Should be defined"
#endif
int main(int argc, char **argv) {
return strcmp(A_STRING, "foo")
|| strcmp(B_STRING, "foo")
|| A_INT != 42
|| B_INT != 42;
}
Loading…
Cancel
Save