Merged array option branch.

pull/2615/head
Jussi Pakkanen 7 years ago
commit 2cf1e8da15
  1. 57
      docs/markdown/Build-options.md
  2. 102
      docs/markdown/Running-Meson.md
  3. 5
      docs/markdown/snippets/option-array-type.md
  4. 7
      mesonbuild/coredata.py
  5. 20
      mesonbuild/optinterpreter.py
  6. 19
      run_unittests.py
  7. 1
      test cases/common/47 options/meson_options.txt

@ -16,32 +16,38 @@ Here is a simple option file.
option('someoption', type : 'string', value : 'optval', description : 'An option')
option('other_one', type : 'boolean', value : false)
option('combo_opt', type : 'combo', choices : ['one', 'two', 'three'], value : 'three')
option('free_array_opt', type : 'array', value : ['one', 'two'])
option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one', 'two'])
```
All types allow a `description` value to be set describing the option, if no
option is set then the name of the option will be used instead.
All types allow a `description` value to be set describing the option,
if no option is set then the name of the option will be used instead.
### Strings
The string type is a free form string. If the default value is not set then an
empty string will be used as the default.
The string type is a free form string. If the default value is not set
then an empty string will be used as the default.
### Booleans
Booleans may have values of either `true` or `false`. If not default value is
supplied then `true` will be used as the default.
Booleans may have values of either `true` or `false`. If not default
value is supplied then `true` will be used as the default.
### Combos
A combo allows any one of the values in the `choices` parameter to be selected.
If no default value is set then the first value will be the default.
A combo allows any one of the values in the `choices` parameter to be
selected. If no default value is set then the first value will be the
default.
### Arrays
Arrays allow one or more of the values in the `choices` parameter to be selected.
If the `value` parameter is unset then the values of `choices` will be used as
the default.
Arrays represent an array of strings. By default the array can contain
arbitrary strings. To limit the possible values that can used set the
`choices` parameter. Meson will then only allow the value array to
contain strings that are in the given list. The array may be
empty. The `value` parameter specifies the default value of the option
and if it is unset then the values of `choices` will be used as the
default.
This type is new in version 0.44.0
@ -61,9 +67,9 @@ prefix = get_option('prefix')
```
It should be noted that you can not set option values in your Meson
scripts. They have to be set externally with the `meson configure` command
line tool. Running `meson configure` without arguments in a build dir shows
you all options you can set.
scripts. They have to be set externally with the `meson configure`
command line tool. Running `meson configure` without arguments in a
build dir shows you all options you can set.
To change their values use the `-D`
option:
@ -72,5 +78,26 @@ option:
$ meson configure -Doption=newvalue
```
Setting the value of arrays is a bit special. If you only pass a
single string, then it is considered to have all values separated by
commas. Thus invoking the following command:
**NOTE:** If you cannot call `meson configure` you likely have a old version of Meson. In that case you can call `mesonconf` instead, but that is deprecated in newer versions
```console
$ meson configure -Darray_opt=foo,bar
```
would set the value to an array of two elements, `foo` and `bar`.
If you need to have commas in your string values, then you need to
pass the value with proper shell quoting like this:
```console
$ meson configure "-Doption=['a,b', 'c,d']"
```
The inner values must always be single quotes and the outer ones
double quotes.
**NOTE:** If you cannot call `meson configure` you likely have a old
version of Meson. In that case you can call `mesonconf` instead, but
that is deprecated in newer versions

@ -1,17 +1,26 @@
---
short-description: Building a project with meson
short-description: Building a project with Meson
...
# Running meson
# Running Meson
There are two different ways of invoking Meson. First, you can run it directly from the source tree with the command `/path/to/source/meson.py`. Meson may also be installed in which case the command is simply `meson`. In this manual we only use the latter format for simplicity.
There are two different ways of invoking Meson. First, you can run it
directly from the source tree with the command
`/path/to/source/meson.py`. Meson may also be installed in which case
the command is simply `meson`. In this manual we only use the latter
format for simplicity.
At the time of writing only a command line version of Meson is available. This means that Meson must be invoked using the terminal. If you wish to use the MSVC compiler, you need to run Meson under "Visual Studio command prompt".
At the time of writing only a command line version of Meson is
available. This means that Meson must be invoked using the
terminal. If you wish to use the MSVC compiler, you need to run Meson
under "Visual Studio command prompt".
Configuring the source
==
Let us assume that we have a source tree that has a Meson build system. This means that at the topmost directory has a file called `meson.build`. We run the following commands to get the build started.
Let us assume that we have a source tree that has a Meson build
system. This means that at the topmost directory has a file called
`meson.build`. We run the following commands to get the build started.
cd /path/to/source/root
@ -19,13 +28,22 @@ Let us assume that we have a source tree that has a Meson build system. This mea
cd builddir
meson ..
First we create a directory to hold all files generated during the build. Then we go into it and invoke Meson, giving it the location of the source root.
First we create a directory to hold all files generated during the
build. Then we go into it and invoke Meson, giving it the location of
the source root.
Hint: The syntax of meson is `meson [options] [srcdir] [builddir]`, but you may omit either `srcdir` or `builddir`. Meson will deduce the `srcdir` by the location of `meson.build`. The other one will be your `pwd`.
Hint: The syntax of meson is `meson [options] [srcdir] [builddir]`,
but you may omit either `srcdir` or `builddir`. Meson will deduce the
`srcdir` by the location of `meson.build`. The other one will be your
`pwd`.
Meson then loads the build configuration file and writes the corresponding build backend in the build directory. By default Meson generates a *debug build*, which turns on basic warnings and debug information and disables compiler optimizations.
Meson then loads the build configuration file and writes the
corresponding build backend in the build directory. By default Meson
generates a *debug build*, which turns on basic warnings and debug
information and disables compiler optimizations.
You can specify a different type of build with the `--buildtype` command line argument. It can have one of the following values.
You can specify a different type of build with the `--buildtype`
command line argument. It can have one of the following values.
| value | meaning |
| ------ | -------- |
@ -34,42 +52,78 @@ You can specify a different type of build with the `--buildtype` command line ar
| `debugoptimized` | debug info is generated and the code is optimized (on most compilers this means `-g -O2`) |
| `release` | full optimization, no debug info |
The build directory is mandatory. The reason for this is that it simplifies the build process immensely. Meson will not under any circumstances write files inside the source directory (if it does, it is a bug and should be fixed). This means that the user does not need to add a bunch of files to their revision control's ignore list. It also means that you can create arbitrarily many build directories for any given source tree. If we wanted to test building the source code with the Clang compiler instead of the system default, we could just type the following commands.
The build directory is mandatory. The reason for this is that it
simplifies the build process immensely. Meson will not under any
circumstances write files inside the source directory (if it does, it
is a bug and should be fixed). This means that the user does not need
to add a bunch of files to their revision control's ignore list. It
also means that you can create arbitrarily many build directories for
any given source tree. If we wanted to test building the source code
with the Clang compiler instead of the system default, we could just
type the following commands.
cd /path/to/source/root
mkdir buildclang
cd buildclang
CC=clang CXX=clang++ meson ..
This separation is even more powerful if your code has multiple configuration options (such as multiple data backends). You can create a separate subdirectory for each of them. You can also have build directories for optimized builds, code coverage, static analysis and so on. They are all neatly separated and use the same source tree. Changing between different configurations is just a question of changing to the corresponding directory.
This separation is even more powerful if your code has multiple
configuration options (such as multiple data backends). You can create
a separate subdirectory for each of them. You can also have build
directories for optimized builds, code coverage, static analysis and
so on. They are all neatly separated and use the same source
tree. Changing between different configurations is just a question of
changing to the corresponding directory.
Unless otherwise mentioned, all following command line invocations are meant to be run in the build directory.
Unless otherwise mentioned, all following command line invocations are
meant to be run in the build directory.
By default Meson will use the Ninja backend to build your project. If you wish to use any of the other backends, you need to pass the corresponding argument during configuration time. As an example, here is how you would use Meson to generate a Visual studio solution.
By default Meson will use the Ninja backend to build your project. If
you wish to use any of the other backends, you need to pass the
corresponding argument during configuration time. As an example, here
is how you would use Meson to generate a Visual studio solution.
meson <source dir> <build dir> --backend=vs2010
You can then open the generated solution with Visual Studio and compile it in the usual way. A list of backends can be obtained with `meson --help`.
You can then open the generated solution with Visual Studio and
compile it in the usual way. A list of backends can be obtained with
`meson --help`.
Building the source
==
If you are not using an IDE, Meson uses the [Ninja build system](https://ninja-build.org/) to actually build the code. To start the build, simply type the following command.
If you are not using an IDE, Meson uses the [Ninja build
system](https://ninja-build.org/) to actually build the code. To start
the build, simply type the following command.
ninja
The main usability difference between Ninja and Make is that Ninja will automatically detect the number of CPUs in your computer and parallelize itself accordingly. You can override the amount of parallel processes used with the command line argument `-j <num processes>`.
It should be noted that after the initial configure step `ninja` is the only command you ever need to type to compile. No matter how you alter your source tree (short of moving it to a completely new location), Meson will detect the changes and regenerate itself accordingly. This is especially handy if you have multiple build directories. Often one of them is used for development (the "debug" build) and others only every now and then (such as a "static analysis" build). Any configuration can be built just by `cd`'ing to the corresponding directory and running Ninja.
The main usability difference between Ninja and Make is that Ninja
will automatically detect the number of CPUs in your computer and
parallelize itself accordingly. You can override the amount of
parallel processes used with the command line argument `-j <num
processes>`.
It should be noted that after the initial configure step `ninja` is
the only command you ever need to type to compile. No matter how you
alter your source tree (short of moving it to a completely new
location), Meson will detect the changes and regenerate itself
accordingly. This is especially handy if you have multiple build
directories. Often one of them is used for development (the "debug"
build) and others only every now and then (such as a "static analysis"
build). Any configuration can be built just by `cd`'ing to the
corresponding directory and running Ninja.
Running tests
==
Meson provides native support for running tests. The command to do that is simple.
Meson provides native support for running tests. The command to do
that is simple.
ninja test
Meson does not force the use of any particular testing framework. You are free to use GTest, Boost Test, Check or even custom executables.
Meson does not force the use of any particular testing framework. You
are free to use GTest, Boost Test, Check or even custom executables.
Installing
==
@ -78,13 +132,17 @@ Installing the built software is just as simple.
ninja install
By default Meson installs to `/usr/local`. This can be changed by passing the command line argument `--prefix /your/prefix` to Meson during configure time. Meson also supports the `DESTDIR` variable used in e.g. building packages. It is used like this:
By default Meson installs to `/usr/local`. This can be changed by
passing the command line argument `--prefix /your/prefix` to Meson
during configure time. Meson also supports the `DESTDIR` variable used
in e.g. building packages. It is used like this:
DESTDIR=/path/to/staging ninja install
Command line help
==
Meson has a standard command line help feature. It can be accessed with the following command.
Meson has a standard command line help feature. It can be accessed
with the following command.
meson --help

@ -3,8 +3,9 @@
Previously to have an option that took more than one value a string value would
have to be created and split, but validating this was difficult. A new array type
has been added to the meson_options.txt for this case. It works like a 'combo', but
allows more than one option to be passed. When used on the command line (with -D),
values are passed as a comma separated list.
allows more than one option to be passed. The values can optionally be validated
against a list of valid values. When used on the command line (with -D), values
are passed as a comma separated list.
```meson
option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one'])

@ -132,7 +132,7 @@ class UserStringArrayOption(UserOption):
def validate(self, value, user_input):
# User input is for options defined on the command line (via -D
# options). Users should put their input in as a comma separated
# options). Users can put their input in as a comma separated
# string, but for defining options in meson_options.txt the format
# should match that of a combo
if not user_input:
@ -144,7 +144,10 @@ class UserStringArrayOption(UserOption):
newvalue = value
else:
assert isinstance(value, str)
newvalue = [v.strip() for v in value.split(',')]
if value.startswith('['):
newvalue = ast.literal_eval(value)
else:
newvalue = [v.strip() for v in value.split(',')]
if not isinstance(newvalue, list):
raise MesonException('"{0}" should be a string array, but it is not'.format(str(newvalue)))
for i in newvalue:

@ -86,15 +86,17 @@ def ComboParser(name, description, kwargs):
@permitted_kwargs({'value', 'choices'})
def string_array_parser(name, description, kwargs):
if 'choices' not in kwargs:
raise OptionException('Array option missing "choices" keyword.')
choices = kwargs['choices']
if not isinstance(choices, list):
raise OptionException('Array choices must be an array.')
for i in choices:
if not isinstance(i, str):
raise OptionException('Array choice elements must be strings.')
value = kwargs.get('value', choices)
if 'choices' in kwargs:
choices = kwargs['choices']
if not isinstance(choices, list):
raise OptionException('Array choices must be an array.')
for i in choices:
if not isinstance(i, str):
raise OptionException('Array choice elements must be strings.')
value = kwargs.get('value', choices)
else:
choices = None
value = kwargs.get('value', [])
if not isinstance(value, list):
raise OptionException('Array choices must be passed as an array.')
return coredata.UserStringArrayOption(name, description, value, choices=choices)

@ -1614,6 +1614,25 @@ int main(int argc, char **argv) {
changed = get_opt()
self.assertDictEqual(changed, expected)
def opt_has(self, name, value):
res = self.introspect('--buildoptions')
found = False
for i in res:
if i['name'] == name:
self.assertEqual(i['value'], value)
found = True
break
self.assertTrue(found, "Array option not found in introspect data.")
def test_free_stringarray_setting(self):
testdir = os.path.join(self.common_test_dir, '47 options')
self.init(testdir)
self.opt_has('free_array_opt', [])
self.setconf('-Dfree_array_opt=foo,bar', will_build=False)
self.opt_has('free_array_opt', ['foo', 'bar'])
self.setconf("-Dfree_array_opt=['a,b', 'c,d']", will_build=False)
self.opt_has('free_array_opt', ['a,b', 'c,d'])
class FailureTests(BasePlatformTests):
'''

@ -2,3 +2,4 @@ option('testoption', type : 'string', value : 'optval', description : 'An option
option('other_one', type : 'boolean', value : false)
option('combo_opt', type : 'combo', choices : ['one', 'two', 'combo'], value : 'combo')
option('array_opt', type : 'array', choices : ['one', 'two', 'three'], value : ['one', 'two'])
option('free_array_opt', type : 'array')

Loading…
Cancel
Save