Allow setting built-in options from cross/native files

This is like the project options, but for meson builtin options.

The only real differences here have to do with the differences between
meson builtin options and project options. Some meson options can be set
on a per-machine basis (build.pkg_config_path vs pkg_config_path) others
can be set on a per-subproject basis, but should inherit the parent
setting.
pull/6597/head
Dylan Baker 5 years ago
parent af763e093a
commit bbba6a7f36
  1. 2
      cross/armcc.txt
  2. 5
      cross/armclang-linux.txt
  3. 2
      cross/armclang.txt
  4. 6
      cross/c2000.txt
  5. 2
      cross/ccrx.txt
  6. 6
      cross/iphone.txt
  7. 7
      cross/tvos.txt
  8. 6
      cross/ubuntu-armhf.txt
  9. 3
      cross/wasm.txt
  10. 2
      cross/xc16.txt
  11. 56
      docs/markdown/Machine-files.md
  12. 17
      docs/markdown/snippets/project_options_in_machine_files.md
  13. 49
      mesonbuild/coredata.py
  14. 28
      mesonbuild/environment.py
  15. 1
      mesonbuild/interpreter.py
  16. 153
      run_unittests.py

@ -7,7 +7,7 @@ cpp = 'armcc'
ar = 'armar' ar = 'armar'
strip = 'armar' strip = 'armar'
[properties] [built-in options]
# The '--cpu' option with the appropriate target type should be mentioned # The '--cpu' option with the appropriate target type should be mentioned
# to cross compile c/c++ code with armcc,. # to cross compile c/c++ code with armcc,.
c_args = ['--cpu=Cortex-M0plus'] c_args = ['--cpu=Cortex-M0plus']

@ -12,7 +12,7 @@
# Armcc is only available in toolchain version 5. # Armcc is only available in toolchain version 5.
# Armclang is only available in toolchain version 6. # Armclang is only available in toolchain version 6.
# Start shell with /opt/arm/developmentstudio-2019.0/bin/suite_exec zsh # Start shell with /opt/arm/developmentstudio-2019.0/bin/suite_exec zsh
# Now the compilers will work. # Now the compilers will work.
[binaries] [binaries]
# we could set exe_wrapper = qemu-arm-static but to test the case # we could set exe_wrapper = qemu-arm-static but to test the case
@ -24,8 +24,7 @@ ar = '/opt/arm/developmentstudio-2019.0/sw/ARMCompiler6.12/bin/armar'
#strip = '/usr/arm-linux-gnueabihf/bin/strip' #strip = '/usr/arm-linux-gnueabihf/bin/strip'
#pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' #pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'
[properties] [built-in options]
c_args = ['--target=aarch64-arm-none-eabi'] c_args = ['--target=aarch64-arm-none-eabi']
[host_machine] [host_machine]

@ -7,7 +7,7 @@ cpp = 'armclang'
ar = 'armar' ar = 'armar'
strip = 'armar' strip = 'armar'
[properties] [built-in options]
# The '--target', '-mcpu' options with the appropriate values should be mentioned # The '--target', '-mcpu' options with the appropriate values should be mentioned
# to cross compile c/c++ code with armclang. # to cross compile c/c++ code with armclang.
c_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus'] c_args = ['--target=arm-arm-none-eabi', '-mcpu=cortex-m0plus']

@ -12,8 +12,7 @@ cpu_family = 'c2000'
cpu = 'c28x' cpu = 'c28x'
endian = 'little' endian = 'little'
[properties] [built-in options]
needs_exe_wrapper = true
c_args = [ c_args = [
'-v28', '-v28',
'-ml', '-ml',
@ -24,3 +23,6 @@ c_link_args = [
'\f28004x_flash.cmd'] '\f28004x_flash.cmd']
cpp_args = [] cpp_args = []
cpp_link_args = [] cpp_link_args = []
[properties]
needs_exe_wrapper = true

@ -7,7 +7,7 @@ cpp = 'ccrx'
ar = 'rlink' ar = 'rlink'
strip = 'rlink' strip = 'rlink'
[properties] [built-in options]
# The '--cpu' option with the appropriate target type should be mentioned # The '--cpu' option with the appropriate target type should be mentioned
# to cross compile c/c++ code with ccrx,. # to cross compile c/c++ code with ccrx,.
c_args = ['-cpu=rx600'] c_args = ['-cpu=rx600']

@ -8,14 +8,14 @@ cpp = 'clang++'
ar = 'ar' ar = 'ar'
strip = 'strip' strip = 'strip'
[properties] [built-in options]
root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer'
c_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] c_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
cpp_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] cpp_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
c_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] c_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
cpp_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk'] cpp_link_args = ['-arch', 'armv7', '-miphoneos-version-min=8.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.4.sdk']
[properties]
root = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer'
has_function_printf = true has_function_printf = true
has_function_hfkerhisadf = false has_function_hfkerhisadf = false

@ -8,14 +8,15 @@ cpp = 'clang++'
ar = 'ar' ar = 'ar'
strip = 'strip' strip = 'strip'
[properties] [built-in options]
root = '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer'
c_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] c_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk']
cpp_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] cpp_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk']
c_link_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] c_link_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk']
cpp_link_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk'] cpp_link_args = ['-arch', 'arm64', '-mtvos-version-min=12.0', '-isysroot', '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk']
[properties]
root = '/Applications/Xcode.app/Contents/Developer/Platforms/AppleTVOS.platform/Developer'
has_function_printf = true has_function_printf = true
has_function_hfkerhisadf = false has_function_hfkerhisadf = false

@ -9,12 +9,14 @@ strip = '/usr/arm-linux-gnueabihf/bin/strip'
pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config' pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'
ld = '/usr/bin/arm-linux/gnueabihf-ld' ld = '/usr/bin/arm-linux/gnueabihf-ld'
[properties] [built-in options]
root = '/usr/arm-linux-gnueabihf'
# Used in unit test '140 get define' # Used in unit test '140 get define'
c_args = ['-DMESON_TEST_ISSUE_1665=1'] c_args = ['-DMESON_TEST_ISSUE_1665=1']
cpp_args = '-DMESON_TEST_ISSUE_1665=1' cpp_args = '-DMESON_TEST_ISSUE_1665=1'
[properties]
root = '/usr/arm-linux-gnueabihf'
has_function_printf = true has_function_printf = true
has_function_hfkerhisadf = false has_function_hfkerhisadf = false

@ -3,8 +3,7 @@ c = '/home/jpakkane/emsdk/fastcomp/emscripten/emcc'
cpp = '/home/jpakkane/emsdk/fastcomp/emscripten/em++' cpp = '/home/jpakkane/emsdk/fastcomp/emscripten/em++'
ar = '/home/jpakkane/emsdk/fastcomp/emscripten/emar' ar = '/home/jpakkane/emsdk/fastcomp/emscripten/emar'
[properties] [built-in options]
c_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1'] c_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1']
c_link_args = ['-s','EXPORT_ALL=1'] c_link_args = ['-s','EXPORT_ALL=1']
cpp_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1'] cpp_args = ['-s', 'WASM=1', '-s', 'EXPORT_ALL=1']

@ -14,6 +14,8 @@ endian = 'little'
[properties] [properties]
needs_exe_wrapper = true needs_exe_wrapper = true
[built-in options]
c_args = [ c_args = [
'-c', '-c',
'-mcpu=33EP64MC203', '-mcpu=33EP64MC203',

@ -13,6 +13,7 @@ The following sections are allowed:
- paths - paths
- properties - properties
- project options - project options
- built-in options
### constants ### constants
@ -158,17 +159,23 @@ command line will override any options in the native file. For example, passing
In addition to special data that may be specified in cross files, this In addition to special data that may be specified in cross files, this
section may contain random key value pairs accessed using the section may contain random key value pairs accessed using the
`meson.get_external_property`, or `meson.get_cross_property`. `meson.get_external_property()`, or `meson.get_cross_property()`.
*Changed in 0.55.0* putting `<lang>_args` and `<lang>_link_args` in the
properties section has been deprecated, and should be put in the built-in
options section.
### Project specific options ### Project specific options
*New in 0.54.0* *New in 0.55.0*
Path options are not allowed, those must be set in the `[paths]` section.
Being able to set project specific options in a native or cross files can be Being able to set project specific options in a cross or native file can be
done using the `[project options]` section of the specific file (if doing a done using the `[project options]` section of the specific file (if doing a
cross build the options from the native file will be ignored) cross build the options from the native file will be ignored)
For setting options in supbprojects use the `<subproject>:project options` For setting options in subprojects use the `[<subproject>:project options]`
section instead. section instead.
```ini ```ini
@ -179,6 +186,47 @@ build-tests = true
build-tests = false build-tests = false
``` ```
### Meson built-in options
Meson built-in options can be set the same way:
```ini
[built-in options]
c_std = 'c99'
```
You can set some meson built-in options on a per-subproject basis, such as
`default_library` and `werror`. The order of precedence is:
1) Command line
2) Machine file
3) Build system definitions
```ini
[zlib:built-in options]
default_library = 'static'
werror = false
```
Options set on a per-subproject basis will inherit the
option from the parent if the parent has a setting but the subproject
doesn't, even when there is a default set meson language.
```ini
[built-in options]
default_library = 'static'
```
will make subprojects use default_library as static.
Some options can be set on a per-machine basis (in other words, the value of
the build machine can be different than the host machine in a cross compile).
In these cases the values from both a cross file and a native file are used.
An incomplete list of options is:
- pkg_config_path
- cmake_prefix_path
## Loading multiple machine files ## Loading multiple machine files
Native files allow layering (cross files can be layered since meson 0.52.0). Native files allow layering (cross files can be layered since meson 0.52.0).

@ -1,4 +1,4 @@
## Project options can be set in native or cross files ## Project and built-in options can be set in native or cross files
A new set of sections has been added to the cross and native files, `[project A new set of sections has been added to the cross and native files, `[project
options]` and `[<subproject_name>:project options]`, where `subproject_name` options]` and `[<subproject_name>:project options]`, where `subproject_name`
@ -35,3 +35,18 @@ Subproject options are assigned like this:
[zlib:project options] [zlib:project options]
foo = 'some val' foo = 'some val'
``` ```
Additionally meson level options can be set in the same way, using the
`[built-in options]` section.
```ini
[built-in options]
c_std = 'c99'
```
These options can also be set on a per-subproject basis, although only
`default_library` and `werror` can currently be set:
```ini
[zlib:built-in options]
default_library = 'static'
```

@ -361,15 +361,15 @@ class CoreData:
self.install_guid = str(uuid.uuid4()).upper() self.install_guid = str(uuid.uuid4()).upper()
self.target_guids = {} self.target_guids = {}
self.version = version self.version = version
self.builtins = {} # : OptionDictType self.builtins = {} # type: OptionDictType
self.builtins_per_machine = PerMachine({}, {}) self.builtins_per_machine = PerMachine({}, {})
self.backend_options = {} # : OptionDictType self.backend_options = {} # type: OptionDictType
self.user_options = {} # : OptionDictType self.user_options = {} # type: OptionDictType
self.compiler_options = PerMachine( self.compiler_options = PerMachine(
defaultdict(dict), defaultdict(dict),
defaultdict(dict), defaultdict(dict),
) # : PerMachine[T.defaultdict[str, OptionDictType]] ) # : PerMachine[T.defaultdict[str, OptionDictType]]
self.base_options = {} # : OptionDictType self.base_options = {} # type: OptionDictType
self.cross_files = self.__load_config_files(options, scratch_dir, 'cross') self.cross_files = self.__load_config_files(options, scratch_dir, 'cross')
self.compilers = PerMachine(OrderedDict(), OrderedDict()) self.compilers = PerMachine(OrderedDict(), OrderedDict())
@ -743,19 +743,28 @@ class CoreData:
mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. ' mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. '
'Using both is redundant since they override each other. ' 'Using both is redundant since they override each other. '
'See: https://mesonbuild.com/Builtin-options.html#build-type-options') 'See: https://mesonbuild.com/Builtin-options.html#build-type-options')
cmd_line_options = OrderedDict() cmd_line_options = OrderedDict()
# Set project default_options as if they were passed to the cmdline. # Set default options as if they were passed to the command line.
# Subprojects can only define default for user options and not yielding # Subprojects can only define default for user options and not yielding
# builtin option. # builtin option.
from . import optinterpreter from . import optinterpreter
for k, v in default_options.items(): for k, v in chain(default_options.items(), env.meson_options.host.get('', {}).items()):
if subproject: if subproject:
if (k not in builtin_options or builtin_options[k].yielding) \ if (k not in builtin_options or builtin_options[k].yielding) \
and optinterpreter.is_invalid_name(k, log=False): and optinterpreter.is_invalid_name(k, log=False):
continue continue
k = subproject + ':' + k
cmd_line_options[k] = v cmd_line_options[k] = v
# IF the subproject options comes from a machine file, then we need to
# set the option as subproject:option
if subproject:
for k, v in env.meson_options.host.get(subproject, {}).items():
if (k not in builtin_options or builtin_options[k].yielding) \
and optinterpreter.is_invalid_name(k, log=False):
continue
cmd_line_options['{}:{}'.format(subproject, k)] = v
# load the values for user options out of the appropriate machine file, # load the values for user options out of the appropriate machine file,
# then overload the command line # then overload the command line
for k, v in env.user_options.get(subproject, {}).items(): for k, v in env.user_options.get(subproject, {}).items():
@ -768,8 +777,32 @@ class CoreData:
if v is not None: if v is not None:
cmd_line_options[k] = v cmd_line_options[k] = v
from .compilers import all_languages
# Report that [properties]c_args
for lang in all_languages:
for args in ['{}_args'.format(lang), '{}_link_args'.format(lang)]:
msg = ('{} in the [properties] section of the machine file is deprecated, '
'use the [built-in options] section.')
if args in env.properties.host or args in env.properties.build:
mlog.deprecation(msg.format(args))
# Currently we don't support any options that are both per-subproject
# and per-machine, but when we do this will need to account for that.
# For cross builds we need to get the build specifc options
if env.meson_options.host != env.meson_options.build and subproject in env.meson_options.build:
for k in builtin_options_per_machine.keys():
if k in env.meson_options.build[subproject]:
cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k]
# compiler options are always per-machine
for lang in all_languages:
prefix = '{}_'.format(lang)
for k in env.meson_options.build[subproject]:
if k.startswith(prefix):
cmd_line_options['build.{}'.format(k)] = env.meson_options.build[subproject][k]
# Override all the above defaults using the command-line arguments # Override all the above defaults using the command-line arguments
# actually passed to us # actually passed to use
cmd_line_options.update(env.cmd_line_options) cmd_line_options.update(env.cmd_line_options)
env.cmd_line_options = cmd_line_options env.cmd_line_options = cmd_line_options

@ -556,6 +556,9 @@ class Environment:
# We only need one of these as project options are not per machine # We only need one of these as project options are not per machine
user_options = {} user_options = {}
# meson builtin options, as passed through cross or native files
meson_options = PerMachineDefaultable()
## Setup build machine defaults ## Setup build machine defaults
# Will be fully initialized later using compilers later. # Will be fully initialized later using compilers later.
@ -568,14 +571,15 @@ class Environment:
## Read in native file(s) to override build machine configuration ## Read in native file(s) to override build machine configuration
def load_user_options(): def load_options(tag: str, store: T.Dict[str, T.Any]) -> None:
for section in config.keys(): for section in config.keys():
if section.endswith('project options'): if section.endswith(tag):
if ':' in section: if ':' in section:
project = section.split(':')[0] project = section.split(':')[0]
else: else:
project = '' project = ''
user_options[project] = config.get(section, {}) store[project] = config.get(section, {})
if self.coredata.config_files is not None: if self.coredata.config_files is not None:
config = coredata.parse_machine_files(self.coredata.config_files) config = coredata.parse_machine_files(self.coredata.config_files)
@ -586,7 +590,9 @@ class Environment:
# Don't run this if there are any cross files, we don't want to use # Don't run this if there are any cross files, we don't want to use
# the native values if we're doing a cross build # the native values if we're doing a cross build
if not self.coredata.cross_files: if not self.coredata.cross_files:
load_user_options() load_options('project options', user_options)
meson_options.build = {}
load_options('built-in options', meson_options.build)
## Read in cross file(s) to override host machine configuration ## Read in cross file(s) to override host machine configuration
@ -599,7 +605,9 @@ class Environment:
if 'target_machine' in config: if 'target_machine' in config:
machines.target = MachineInfo.from_literal(config['target_machine']) machines.target = MachineInfo.from_literal(config['target_machine'])
paths.host = Directories(**config.get('paths', {})) paths.host = Directories(**config.get('paths', {}))
load_user_options() load_options('project options', user_options)
meson_options.host = {}
load_options('built-in options', meson_options.host)
## "freeze" now initialized configuration, and "save" to the class. ## "freeze" now initialized configuration, and "save" to the class.
@ -608,6 +616,16 @@ class Environment:
self.properties = properties.default_missing() self.properties = properties.default_missing()
self.paths = paths.default_missing() self.paths = paths.default_missing()
self.user_options = user_options self.user_options = user_options
self.meson_options = meson_options.default_missing()
# Ensure that no paths are passed via built-in options:
if '' in self.meson_options.host:
for each in coredata.BUILTIN_DIR_OPTIONS.keys():
# These are not per-subdirectory and probably never will be
if each in self.meson_options.host['']:
raise EnvironmentException(
'Invalid entry {} in [built-in options] section. '
'Use the [paths] section instead.'.format(each))
exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper') exe_wrapper = self.lookup_binary_entry(MachineChoice.HOST, 'exe_wrapper')
if exe_wrapper is not None: if exe_wrapper is not None:

@ -2791,6 +2791,7 @@ external dependencies (including libraries) must go to "dependencies".''')
default_options = mesonlib.stringlistify(kwargs.get('default_options', [])) default_options = mesonlib.stringlistify(kwargs.get('default_options', []))
default_options = coredata.create_options_dict(default_options) default_options = coredata.create_options_dict(default_options)
if dirname == '': if dirname == '':
raise InterpreterException('Subproject dir name must not be empty.') raise InterpreterException('Subproject dir name must not be empty.')
if dirname[0] == '.': if dirname[0] == '.':

@ -7672,8 +7672,10 @@ class NativeFileTests(BasePlatformTests):
for section, entries in values.items(): for section, entries in values.items():
f.write('[{}]\n'.format(section)) f.write('[{}]\n'.format(section))
for k, v in entries.items(): for k, v in entries.items():
if isinstance(v, bool): if isinstance(v, (bool, int, float)):
f.write("{}={}\n".format(k, v)) f.write("{}={}\n".format(k, v))
elif isinstance(v, list):
f.write("{}=[{}]\n".format(k, ', '.join(["'{}'".format(w) for w in v])))
else: else:
f.write("{}='{}'\n".format(k, v)) f.write("{}='{}'\n".format(k, v))
return filename return filename
@ -8047,6 +8049,108 @@ class NativeFileTests(BasePlatformTests):
else: else:
self.fail('Did not find werror in build options?') self.fail('Did not find werror in build options?')
def test_option_integer(self):
# Bools are allowed to be unquoted
testcase = os.path.join(self.common_test_dir, '1 trivial')
config = self.helper_create_native_file({'built-in options': {'unity_size': 100}})
self.init(testcase, extra_args=['--native-file', config])
configuration = self.introspect('--buildoptions')
for each in configuration:
# Test that no-per subproject options are inherited from the parent
if 'unity_size' in each['name']:
self.assertEqual(each['value'], 100)
break
else:
self.fail('Did not find unity_size in build options?')
def test_builtin_options(self):
testcase = os.path.join(self.common_test_dir, '2 cpp')
config = self.helper_create_native_file({'built-in options': {'cpp_std': 'c++14'}})
self.init(testcase, extra_args=['--native-file', config])
configuration = self.introspect('--buildoptions')
for each in configuration:
if each['name'] == 'cpp_std':
self.assertEqual(each['value'], 'c++14')
break
else:
self.fail('Did not find werror in build options?')
def test_builtin_options_subprojects(self):
testcase = os.path.join(self.common_test_dir, '102 subproject subdir')
config = self.helper_create_native_file({'built-in options': {'default_library': 'both', 'c_args': ['-Dfoo']}, 'sub:built-in options': {'default_library': 'static'}})
self.init(testcase, extra_args=['--native-file', config])
configuration = self.introspect('--buildoptions')
found = 0
for each in configuration:
# Test that no-per subproject options are inherited from the parent
if 'c_args' in each['name']:
# This path will be hit twice, once for build and once for host,
self.assertEqual(each['value'], ['-Dfoo'])
found += 1
elif each['name'] == 'default_library':
self.assertEqual(each['value'], 'both')
found += 1
elif each['name'] == 'sub:default_library':
self.assertEqual(each['value'], 'static')
found += 1
self.assertEqual(found, 4, 'Did not find all three sections')
def test_builtin_options_subprojects_overrides_buildfiles(self):
# If the buildfile says subproject(... default_library: shared), ensure that's overwritten
testcase = os.path.join(self.common_test_dir, '230 persubproject options')
config = self.helper_create_native_file({'sub2:built-in options': {'default_library': 'shared'}})
with self.assertRaises(subprocess.CalledProcessError) as cm:
self.init(testcase, extra_args=['--native-file', config])
self.assertIn(cm.exception.stdout, 'Parent should override default_library')
def test_builtin_options_subprojects_inherits_parent_override(self):
# If the buildfile says subproject(... default_library: shared), ensure that's overwritten
testcase = os.path.join(self.common_test_dir, '230 persubproject options')
config = self.helper_create_native_file({'built-in options': {'default_library': 'both'}})
with self.assertRaises(subprocess.CalledProcessError) as cm:
self.init(testcase, extra_args=['--native-file', config])
self.assertIn(cm.exception.stdout, 'Parent should override default_library')
def test_builtin_options_compiler_properties(self):
# the properties section can have lang_args, and those need to be
# overwritten by the built-in options
testcase = os.path.join(self.common_test_dir, '1 trivial')
config = self.helper_create_native_file({
'built-in options': {'c_args': ['-DFOO']},
'properties': {'c_args': ['-DBAR']},
})
self.init(testcase, extra_args=['--native-file', config])
configuration = self.introspect('--buildoptions')
for each in configuration:
if each['name'] == 'c_args':
self.assertEqual(each['value'], ['-DFOO'])
break
else:
self.fail('Did not find c_args in build options?')
def test_builtin_options_compiler_properties_legacy(self):
# The legacy placement in properties is still valid if a 'built-in
# options' setting is present, but doesn't have the lang_args
testcase = os.path.join(self.common_test_dir, '1 trivial')
config = self.helper_create_native_file({
'built-in options': {'default_library': 'static'},
'properties': {'c_args': ['-DBAR']},
})
self.init(testcase, extra_args=['--native-file', config])
configuration = self.introspect('--buildoptions')
for each in configuration:
if each['name'] == 'c_args':
self.assertEqual(each['value'], ['-DBAR'])
break
else:
self.fail('Did not find c_args in build options?')
class CrossFileTests(BasePlatformTests): class CrossFileTests(BasePlatformTests):
@ -8266,9 +8370,54 @@ class CrossFileTests(BasePlatformTests):
testcase = os.path.join(self.common_test_dir, '43 options') testcase = os.path.join(self.common_test_dir, '43 options')
config = self.helper_create_cross_file({'project options': {'testoption': 'some other value'}}) config = self.helper_create_cross_file({'project options': {'testoption': 'some other value'}})
with self.assertRaises(subprocess.CalledProcessError) as cm: with self.assertRaises(subprocess.CalledProcessError) as cm:
self.init(testcase, extra_args=['--native-file', config]) self.init(testcase, extra_args=['--cross-file', config])
self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option') self.assertRegex(cm.exception.stdout, r'Incorrect value to [a-z]+ option')
def test_builtin_options(self):
testcase = os.path.join(self.common_test_dir, '2 cpp')
config = self.helper_create_cross_file({'built-in options': {'cpp_std': 'c++14'}})
self.init(testcase, extra_args=['--cross-file', config])
configuration = self.introspect('--buildoptions')
for each in configuration:
if each['name'] == 'cpp_std':
self.assertEqual(each['value'], 'c++14')
break
else:
self.fail('No c++ standard set?')
def test_builtin_options_per_machine(self):
"""Test options that are allowed to be set on a per-machine basis.
Such options could be passed twice, once for the build machine, and
once for the host machine. I've picked pkg-config path, but any would
do that can be set for both.
"""
testcase = os.path.join(self.common_test_dir, '2 cpp')
cross = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/cross/path', 'cpp_std': 'c++17'}})
native = self.helper_create_cross_file({'built-in options': {'pkg_config_path': '/native/path', 'cpp_std': 'c++14'}})
self.init(testcase, extra_args=['--cross-file', cross, '--native-file', native])
configuration = self.introspect('--buildoptions')
found = 0
for each in configuration:
if each['name'] == 'pkg_config_path':
self.assertEqual(each['value'], ['/cross/path'])
found += 1
elif each['name'] == 'cpp_std':
self.assertEqual(each['value'], 'c++17')
found += 1
elif each['name'] == 'build.pkg_config_path':
self.assertEqual(each['value'], ['/native/path'])
found += 1
elif each['name'] == 'build.cpp_std':
self.assertEqual(each['value'], 'c++14')
found += 1
if found == 4:
break
self.assertEqual(found, 4, 'Did not find all sections.')
class TAPParserTests(unittest.TestCase): class TAPParserTests(unittest.TestCase):
def assert_test(self, events, **kwargs): def assert_test(self, events, **kwargs):

Loading…
Cancel
Save