Merge pull request #5263 from Ericson2314/per-machine-cli-args

Per machine 'build_' and '' options
pull/4421/merge
Jussi Pakkanen 6 years ago committed by GitHub
commit 09a722c4bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 55
      docs/markdown/Builtin-options.md
  2. 15
      docs/markdown/snippets/per-machine-options.md
  3. 195
      mesonbuild/coredata.py
  4. 17
      mesonbuild/dependencies/base.py
  5. 25
      mesonbuild/interpreter.py
  6. 13
      mesonbuild/mconf.py
  7. 12
      mesonbuild/mesonlib.py
  8. 14
      mesonbuild/mintro.py
  9. 7
      mesonbuild/rewriter.py
  10. 27
      run_unittests.py
  11. 2
      test cases/unit/50 std remains/meson.build
  12. 1
      test cases/unit/50 std remains/prog.c
  13. 7
      test cases/unit/55 pkg_config_path option/build_extra_path/totally_made_up_dep.pc
  14. 0
      test cases/unit/55 pkg_config_path option/host_extra_path/totally_made_up_dep.pc
  15. 11
      test cases/unit/55 pkg_config_path option/meson.build

@ -52,31 +52,36 @@ on Linux platforms.
### Core options
Options that have a separate cross option will be prefixed with
cross\_, for example, "cross_pkg_config_path" controls the paths
pkg-config will search for host dependencies in a cross compile.
They have no effect when the host and build machines are the same.
| Option | Default value | Description | Has Separate cross |
| ------ | ------------- | ----------- | ------------------ |
| auto_features {enabled, disabled, auto} | auto | Override value of all 'auto' features | no |
| backend {ninja, vs,<br>vs2010, vs2015, vs2017, xcode} | ninja | Backend to use | no |
| buildtype {plain, debug,<br>debugoptimized, release, minsize, custom} | debug | Build type to use | no |
| debug | true | Debug | no |
| default_library {shared, static, both} | shared | Default library type | no |
| errorlogs | true | Whether to print the logs from failing tests. | no |
| install_umask {preserve, 0000-0777} | 022 | Default umask to apply on permissions of installed files | no |
| layout {mirror,flat} | mirror | Build directory layout | no |
| optimization {0, g, 1, 2, 3, s} | 0 | Optimization level | no |
| pkg_config_path | [] | Additional paths for pkg-config to search before builtin paths | yes |
| cmake_prefix_path | [] | Additional prefixes for cmake to search before builtin paths | yes |
| stdsplit | true | Split stdout and stderr in test logs | no |
| strip | false | Strip targets on install | no |
| unity {on, off, subprojects} | off | Unity build | no |
| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no |
| werror | false | Treat warnings as errors | no |
| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no |
Options that are labled "per machine" in the table are set per machine.
Prefixing the option with `build.` just affects the build machine configuration,
while unprefixed just affects the host machine configuration, respectively.
Using the option as-is with no prefix affects all machines. For example:
- `build.pkg_config_path` controls the paths pkg-config will search for just
`native: true` dependencies (build machine).
- `pkg_config_path` controls the paths pkg-config will search for just
`native: false` dependencies (host machine).
| Option | Default value | Description | Is per machine |
| ------ | ------------- | ----------- | -------------- |
| auto_features {enabled, disabled, auto} | auto | Override value of all 'auto' features | no |
| backend {ninja, vs,<br>vs2010, vs2015, vs2017, xcode} | ninja | Backend to use | no |
| buildtype {plain, debug,<br>debugoptimized, release, minsize, custom} | debug | Build type to use | no |
| debug | true | Debug | no |
| default_library {shared, static, both} | shared | Default library type | no |
| errorlogs | true | Whether to print the logs from failing tests. | no |
| install_umask {preserve, 0000-0777} | 022 | Default umask to apply on permissions of installed files | no |
| layout {mirror,flat} | mirror | Build directory layout | no |
| optimization {0, g, 1, 2, 3, s} | 0 | Optimization level | no |
| pkg_config_path {OS separated path} | '' | Additional paths for pkg-config to search before builtin paths | yes |
| cmake_prefix_path | [] | Additional prefixes for cmake to search before builtin paths | yes |
| stdsplit | true | Split stdout and stderr in test logs | no |
| strip | false | Strip targets on install | no |
| unity {on, off, subprojects} | off | Unity build | no |
| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no |
| werror | false | Treat warnings as errors | no |
| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no |
## Base options

@ -0,0 +1,15 @@
## Specifying options per mer machine
Previously, no cross builds were controllable from the command line.
Machine-specific options like the pkg-config path and compiler options only
affected native targets, that is to say all targets in native builds, and
`native: true` targets in cross builds. Now, prefix the option with `build.` to
affect build machine targets, and leave it unprefixed to affect host machine
targets.
For those trying to ensure native and cross builds to the same platform produced
the same result, the old way was frustrating because very different invocations
were needed to affect the same targets, if it was possible at all. Now, the same
command line arguments affect the same targets everwhere --- Meson is closer to
ignoring whether the "overall" build is native or cross, and just caring about
whether individual targets are for the build or host machines.

@ -26,7 +26,9 @@ from .wrap import WrapMode
import ast
import argparse
import configparser
from typing import Optional, Any, TypeVar, Generic, Type, List, Union
from typing import (
Any, Dict, Generic, Iterable, List, Optional, Type, TypeVar, Union
)
import typing
import enum
@ -275,20 +277,16 @@ class DependencyCache:
successfully lookup by providing a simple get/put interface.
"""
def __init__(self, builtins: typing.Dict[str, UserOption[typing.Any]], cross: bool):
def __init__(self, builtins_per_machine: PerMachine[typing.Dict[str, UserOption[typing.Any]]], for_machine: MachineChoice):
self.__cache = OrderedDict() # type: typing.MutableMapping[CacheKeyType, DependencySubCache]
self.__builtins = builtins
self.__is_cross = cross
self.__builtins_per_machine = builtins_per_machine
self.__for_machine = for_machine
def __calculate_subkey(self, type_: DependencyCacheType) -> typing.Tuple[typing.Any, ...]:
if type_ is DependencyCacheType.PKG_CONFIG:
if self.__is_cross:
return tuple(self.__builtins['cross_pkg_config_path'].value)
return tuple(self.__builtins['pkg_config_path'].value)
return tuple(self.__builtins_per_machine[self.__for_machine]['pkg_config_path'].value)
elif type_ is DependencyCacheType.CMAKE:
if self.__is_cross:
return tuple(self.__builtins['cross_cmake_prefix_path'].value)
return tuple(self.__builtins['cmake_prefix_path'].value)
return tuple(self.__builtins_per_machine[self.__for_machine]['cmake_prefix_path'].value)
assert type_ is DependencyCacheType.OTHER, 'Someone forgot to update subkey calculations for a new type'
return tuple()
@ -339,6 +337,9 @@ class DependencyCache:
def clear(self) -> None:
self.__cache.clear()
# Can't bind this near the class method it seems, sadly.
_V = TypeVar('_V')
# This class contains all data that must persist over multiple
# invocations of Meson. It is roughly the same thing as
# cmakecache.
@ -359,19 +360,16 @@ class CoreData:
self.target_guids = {}
self.version = version
self.init_builtins()
self.backend_options = {}
self.user_options = {}
self.backend_options = {} # : Dict[str, UserOption]
self.user_options = {} # : Dict[str, UserOption]
self.compiler_options = PerMachine({}, {})
self.base_options = {}
self.base_options = {} # : Dict[str, UserOption]
self.cross_files = self.__load_config_files(options.cross_file, 'cross')
self.compilers = OrderedDict()
self.cross_compilers = OrderedDict()
build_cache = DependencyCache(self.builtins, False)
if self.cross_files:
host_cache = DependencyCache(self.builtins, True)
else:
host_cache = build_cache
build_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD)
host_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD)
self.deps = PerMachine(build_cache, host_cache) # type: PerMachine[DependencyCache]
self.compiler_check_cache = OrderedDict()
@ -462,8 +460,10 @@ class CoreData:
self.builtins = {}
for key, opt in builtin_options.items():
self.builtins[key] = opt.init_option()
if opt.separate_cross:
self.builtins['cross_' + key] = opt.init_option()
self.builtins_per_machine = PerMachine({}, {})
for for_machine in iter(MachineChoice):
for key, opt in builtin_options_per_machine.items():
self.builtins_per_machine[for_machine][key] = opt.init_option()
def init_backend_options(self, backend_name):
if backend_name == 'ninja':
@ -479,28 +479,40 @@ class CoreData:
'')
def get_builtin_option(self, optname):
if optname in self.builtins:
v = self.builtins[optname]
for opts in self._get_all_builtin_options():
v = opts.get(optname)
if v is None:
continue
if optname == 'wrap_mode':
return WrapMode.from_string(v.value)
return v.value
raise RuntimeError('Tried to get unknown builtin option %s.' % optname)
def set_builtin_option(self, optname, value):
if optname == 'prefix':
value = self.sanitize_prefix(value)
elif optname in self.builtins:
prefix = self.builtins['prefix'].value
value = self.sanitize_dir_option_value(prefix, optname, value)
def _try_set_builtin_option(self, optname, value):
for opts in self._get_all_builtin_options():
opt = opts.get(optname)
if opt is None:
continue
if optname == 'prefix':
value = self.sanitize_prefix(value)
else:
prefix = self.builtins['prefix'].value
value = self.sanitize_dir_option_value(prefix, optname, value)
break
else:
raise RuntimeError('Tried to set unknown builtin option %s.' % optname)
self.builtins[optname].set_value(value)
return False
opt.set_value(value)
# Make sure that buildtype matches other settings.
if optname == 'buildtype':
self.set_others_from_buildtype(value)
else:
self.set_buildtype_from_others()
return True
def set_builtin_option(self, optname, value):
res = self._try_set_builtin_option(optname, value)
if not res:
raise RuntimeError('Tried to set unknown builtin option %s.' % optname)
def set_others_from_buildtype(self, value):
if value == 'plain':
@ -541,29 +553,42 @@ class CoreData:
mode = 'custom'
self.builtins['buildtype'].set_value(mode)
def get_all_compiler_options(self):
# TODO think about cross and command-line interface. (Only .build is mentioned here.)
yield self.compiler_options.build
def _get_all_nonbuiltin_options(self):
@staticmethod
def get_prefixed_options_per_machine(
options_per_machine # : PerMachine[Dict[str, _V]]]
) -> Iterable[Dict[str, _V]]:
for for_machine in iter(MachineChoice):
prefix = for_machine.get_prefix()
yield {
prefix + k: v
for k, v in options_per_machine[for_machine].items()
}
def _get_all_nonbuiltin_options(self) -> Iterable[Dict[str, UserOption]]:
yield self.backend_options
yield self.user_options
yield from self.get_all_compiler_options()
yield from self.get_prefixed_options_per_machine(self.compiler_options)
yield self.base_options
def get_all_options(self):
return chain([self.builtins], self._get_all_nonbuiltin_options())
def _get_all_builtin_options(self) -> Dict[str, UserOption]:
yield from self.get_prefixed_options_per_machine(self.builtins_per_machine)
yield self.builtins
def get_all_options(self) -> Dict[str, UserOption]:
yield from self._get_all_nonbuiltin_options()
yield from self._get_all_builtin_options()
def validate_option_value(self, option_name, override_value):
for opts in self.get_all_options():
if option_name in opts:
opt = opts[option_name]
opt = opts.get(option_name)
if opt is not None:
try:
return opt.validate_value(override_value)
except MesonException as e:
raise type(e)(('Validation failed for option %s: ' % option_name) + str(e)) \
.with_traceback(sys.exc_into()[2])
raise MesonException('Tried to validate unknown option %s.' % option_name)
else:
raise MesonException('Tried to validate unknown option %s.' % option_name)
def get_external_args(self, for_machine: MachineChoice, lang):
return self.compiler_options[for_machine][lang + '_args'].value
@ -593,17 +618,17 @@ class CoreData:
unknown_options = []
for k, v in options.items():
if k == 'prefix':
pass
elif k in self.builtins:
self.set_builtin_option(k, v)
continue
if self._try_set_builtin_option(k, v):
continue
for opts in self._get_all_nonbuiltin_options():
tgt = opts.get(k)
if tgt is None:
continue
tgt.set_value(v)
break
else:
for opts in self._get_all_nonbuiltin_options():
if k in opts:
tgt = opts[k]
tgt.set_value(v)
break
else:
unknown_options.append(k)
unknown_options.append(k)
if unknown_options and warn_unknown:
unknown_options = ', '.join(sorted(unknown_options))
sub = 'In subproject {}: '.format(subproject) if subproject else ''
@ -645,7 +670,9 @@ class CoreData:
if subproject:
if not k.startswith(subproject + ':'):
continue
elif k not in builtin_options:
elif k not in builtin_options.keys() \
and 'build.' + k not in builtin_options_per_machine.keys() \
and k not in builtin_options_per_machine.keys():
if ':' in k:
continue
if optinterpreter.is_invalid_name(k, log=False):
@ -666,7 +693,7 @@ class CoreData:
if cross_comp is not None:
new_options_for_host = cross_comp.get_and_default_options(env.properties.host)
else:
new_options_for_host = new_options_for_build
new_options_for_host = comp.get_and_default_options(env.properties.host)
opts_machines_list = [
(new_options_for_build, MachineChoice.BUILD),
@ -678,10 +705,10 @@ class CoreData:
for k, o in new_options.items():
if not k.startswith(optprefix):
raise MesonException('Internal error, %s has incorrect prefix.' % k)
if (env.machines.matches_build_machine(for_machine) and
k in env.cmd_line_options):
# TODO think about cross and command-line interface.
o.set_value(env.cmd_line_options[k])
# prefixed compiler options affect just this machine
opt_prefix = for_machine.get_prefix()
if opt_prefix + k in env.cmd_line_options:
o.set_value(env.cmd_line_options[opt_prefix + k])
self.compiler_options[for_machine].setdefault(k, o)
enabled_opts = []
@ -794,7 +821,10 @@ def save(obj, build_dir):
def register_builtin_arguments(parser):
for n, b in builtin_options.items():
b.add_to_argparse(n, parser)
b.add_to_argparse(n, parser, '', '')
for n, b in builtin_options_per_machine.items():
b.add_to_argparse(n, parser, '', ' (just for host machine)')
b.add_to_argparse(n, parser, 'build.', ' (just for build machine)')
parser.add_argument('-D', action='append', dest='projectoptions', default=[], metavar="option",
help='Set the value of an option, can be used several times to set multiple options.')
@ -812,19 +842,19 @@ def parse_cmd_line_options(args):
args.cmd_line_options = create_options_dict(args.projectoptions)
# Merge builtin options set with --option into the dict.
for name, builtin in builtin_options.items():
names = [name]
if builtin.separate_cross:
names.append('cross_' + name)
for name in names:
value = getattr(args, name, None)
if value is not None:
if name in args.cmd_line_options:
cmdline_name = BuiltinOption.argparse_name_to_arg(name)
raise MesonException(
'Got argument {0} as both -D{0} and {1}. Pick one.'.format(name, cmdline_name))
args.cmd_line_options[name] = value
delattr(args, name)
for name in chain(
builtin_options.keys(),
('build.' + k for k in builtin_options_per_machine.keys()),
builtin_options_per_machine.keys(),
):
value = getattr(args, name, None)
if value is not None:
if name in args.cmd_line_options:
cmdline_name = BuiltinOption.argparse_name_to_arg(name)
raise MesonException(
'Got argument {0} as both -D{0} and {1}. Pick one.'.format(name, cmdline_name))
args.cmd_line_options[name] = value
delattr(args, name)
_U = TypeVar('_U', bound=UserOption[_T])
@ -837,13 +867,12 @@ class BuiltinOption(Generic[_T, _U]):
"""
def __init__(self, opt_type: Type[_U], description: str, default: Any, yielding: Optional[bool] = None, *,
choices: Any = None, separate_cross: bool = False):
choices: Any = None):
self.opt_type = opt_type
self.description = description
self.default = default
self.choices = choices
self.yielding = yielding
self.separate_cross = separate_cross
def init_option(self) -> _U:
"""Create an instance of opt_type and return it."""
@ -882,7 +911,7 @@ class BuiltinOption(Generic[_T, _U]):
pass
return self.default
def add_to_argparse(self, name: str, parser: argparse.ArgumentParser) -> None:
def add_to_argparse(self, name: str, parser: argparse.ArgumentParser, prefix: str, help_suffix: str) -> None:
kwargs = {}
c = self._argparse_choices()
@ -895,13 +924,10 @@ class BuiltinOption(Generic[_T, _U]):
if c and not b:
kwargs['choices'] = c
kwargs['default'] = argparse.SUPPRESS
kwargs['dest'] = name
kwargs['dest'] = prefix + name
cmdline_name = self.argparse_name_to_arg(name)
parser.add_argument(cmdline_name, help=h, **kwargs)
if self.separate_cross:
kwargs['dest'] = 'cross_' + name
parser.add_argument(self.argparse_name_to_arg('cross_' + name), help=h + ' (for host in cross compiles)', **kwargs)
cmdline_name = self.argparse_name_to_arg(prefix + name)
parser.add_argument(cmdline_name, help=h + help_suffix, **kwargs)
# Update `docs/markdown/Builtin-options.md` after changing the options below
builtin_options = OrderedDict([
@ -929,8 +955,6 @@ builtin_options = OrderedDict([
('errorlogs', BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True)),
('install_umask', BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022')),
('layout', BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [], separate_cross=True)),
('cmake_prefix_path', BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [], separate_cross=True)),
('optimization', BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's'])),
('stdsplit', BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
@ -940,6 +964,11 @@ builtin_options = OrderedDict([
('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
])
builtin_options_per_machine = OrderedDict([
('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [])),
('cmake_prefix_path', BuiltinOption(UserArrayOption, 'List of additional prefixes for cmake to search', [])),
])
# Special prefix-dependent defaults for installation directories that reside in
# a path outside of the prefix in FHS and common usage.
builtin_dir_noprefix_options = {

@ -665,11 +665,15 @@ class PkgConfigDependency(ExternalDependency):
else:
env = env.copy()
if self.want_cross:
extra_paths = self.env.coredata.get_builtin_option('cross_pkg_config_path')
if not self.want_cross and self.env.is_cross_build():
for_machine = MachineChoice.BUILD
else:
extra_paths = self.env.coredata.get_builtin_option('pkg_config_path')
env['PKG_CONFIG_PATH'] = ':'.join([p for p in extra_paths])
for_machine = MachineChoice.HOST
extra_paths = self.env.coredata.builtins_per_machine[for_machine]['pkg_config_path'].value
new_pkg_config_path = ':'.join([p for p in extra_paths])
mlog.debug('PKG_CONFIG_PATH: ' + new_pkg_config_path)
env['PKG_CONFIG_PATH'] = new_pkg_config_path
fenv = frozenset(env.items())
targs = tuple(args)
cache = PkgConfigDependency.pkgbin_cache
@ -1134,10 +1138,7 @@ class CMakeDependency(ExternalDependency):
if cm_path:
cm_args.append('-DCMAKE_MODULE_PATH=' + ';'.join(cm_path))
if environment.is_cross_build() and self.want_cross:
pref_path = self.env.coredata.builtins['cross_cmake_prefix_path'].value
else:
pref_path = self.env.coredata.builtins['cmake_prefix_path'].value
pref_path = self.env.coredata.builtins_per_machine[for_machine]['cmake_prefix_path'].value
if pref_path:
cm_args.append('-DCMAKE_PREFIX_PATH={}'.format(';'.join(pref_path)))

@ -2097,12 +2097,12 @@ class Interpreter(InterpreterBase):
def get_non_matching_default_options(self):
env = self.environment
for def_opt_name, def_opt_value in self.project_default_options.items():
for option_type in env.coredata.get_all_options():
for cur_opt_name, cur_opt_value in option_type.items():
if def_opt_name == cur_opt_name:
def_opt_value = env.coredata.validate_option_value(def_opt_name, def_opt_value)
if def_opt_value != cur_opt_value.value:
yield (def_opt_name, def_opt_value, cur_opt_value)
for opts in env.coredata.get_all_options():
cur_opt_value = opts.get(def_opt_name)
if cur_opt_value is not None:
def_opt_value = env.coredata.validate_option_value(def_opt_name, def_opt_value)
if def_opt_value != cur_opt_value.value:
yield (def_opt_name, def_opt_value, cur_opt_value)
def build_func_dict(self):
self.funcs.update({'add_global_arguments': self.func_add_global_arguments,
@ -2519,13 +2519,14 @@ external dependencies (including libraries) must go to "dependencies".''')
return self.subprojects[dirname]
def get_option_internal(self, optname):
for d in chain(
for opts in chain(
[self.coredata.base_options, compilers.base_options, self.coredata.builtins],
self.coredata.get_all_compiler_options()):
try:
return d[optname]
except KeyError:
pass
self.coredata.get_prefixed_options_per_machine(self.coredata.builtins_per_machine),
self.coredata.get_prefixed_options_per_machine(self.coredata.compiler_options),
):
v = opts.get(optname)
if v is not None:
return v
raw_optname = optname
if self.is_subproject():

@ -181,10 +181,16 @@ class Conf:
core_options = {k: o for k, o in self.coredata.builtins.items() if k in core_option_names}
self.print_options('Core options', core_options)
self.print_options('Core options (for host machine)', self.coredata.builtins_per_machine.host)
self.print_options(
'Core options (for build machine)',
{'build.' + k: o for k, o in self.coredata.builtins_per_machine.build.items()})
self.print_options('Backend options', self.coredata.backend_options)
self.print_options('Base options', self.coredata.base_options)
# TODO others
self.print_options('Compiler options', self.coredata.compiler_options.build)
self.print_options('Compiler options (for host machine)', self.coredata.compiler_options.host)
self.print_options(
'Compiler options (for build machine)',
{'build.' + k: o for k, o in self.coredata.compiler_options.build.items()})
self.print_options('Directories', dir_options)
self.print_options('Project options', self.coredata.user_options)
self.print_options('Testing options', test_options)
@ -207,9 +213,6 @@ def run(options):
save = False
if len(options.cmd_line_options) > 0:
c.set_options(options.cmd_line_options)
if not c.build.environment.is_cross_build():
# TODO think about cross and command-line interface.
c.coredata.compiler_options.host = c.coredata.compiler_options.build
coredata.update_cmd_line_file(builddir, options)
save = True
elif options.clearcache:

@ -323,6 +323,12 @@ class MachineChoice(OrderedEnum):
BUILD = 0
HOST = 1
def get_lower_case_name(self):
return PerMachine('build', 'host')[self]
def get_prefix(self):
return PerMachine('build.', '')[self]
class PerMachine(typing.Generic[_T]):
def __init__(self, build: _T, host: _T):
@ -336,11 +342,7 @@ class PerMachine(typing.Generic[_T]):
}[machine]
def __setitem__(self, machine: MachineChoice, val: _T) -> None:
key = {
MachineChoice.BUILD: 'build',
MachineChoice.HOST: 'host',
}[machine]
setattr(self, key, val)
setattr(self, machine.get_lower_case_name(), val)
def miss_defaulting(self) -> "PerMachineDefaultable[typing.Optional[_T]]":
"""Unset definition duplicated from their previous to None

@ -227,10 +227,20 @@ def list_buildoptions(coredata: cdata.CoreData) -> List[dict]:
core_options = {k: o for k, o in coredata.builtins.items() if k in core_option_names}
add_keys(optlist, core_options, 'core')
add_keys(optlist, coredata.builtins_per_machine.host, 'core (for host machine)')
add_keys(
optlist,
{'build.' + k: o for k, o in coredata.builtins_per_machine.build.items()},
'core (for build machine)',
)
add_keys(optlist, coredata.backend_options, 'backend')
add_keys(optlist, coredata.base_options, 'base')
# TODO others
add_keys(optlist, coredata.compiler_options.build, 'compiler')
add_keys(optlist, coredata.compiler_options.host, 'compiler (for host machine)')
add_keys(
optlist,
{'build.' + k: o for k, o in coredata.compiler_options.build.items()},
'compiler (for build machine)',
)
add_keys(optlist, dir_options, 'directory')
add_keys(optlist, coredata.user_options, 'user')
add_keys(optlist, test_options, 'test')

@ -465,10 +465,13 @@ class Rewriter:
cdata = self.interpreter.coredata
options = {
**cdata.builtins,
**cdata.builtins_per_machine.host,
**{'build.' + k: o for k, o in cdata.builtins_per_machine.build.items()},
**cdata.backend_options,
**cdata.base_options,
**cdata.compiler_options.build,
**cdata.user_options
**cdata.compiler_options.host,
**{'build.' + k: o for k, o in cdata.compiler_options.build.items()},
**cdata.user_options,
}
for key, val in sorted(cmd['options'].items()):

@ -1088,7 +1088,10 @@ class DataTests(unittest.TestCase):
found_entries |= arches
break
self.assertEqual(found_entries, set(mesonbuild.coredata.builtin_options.keys()))
self.assertEqual(found_entries, set([
*mesonbuild.coredata.builtin_options.keys(),
*mesonbuild.coredata.builtin_options_per_machine.keys()
]))
def test_cpu_families_documented(self):
with open("docs/markdown/Reference-tables.md") as f:
@ -5193,8 +5196,15 @@ endian = 'little'
@skipIfNoPkgconfig
def test_pkg_config_option(self):
testdir = os.path.join(self.unit_test_dir, '55 pkg_config_path option')
self.init(testdir, extra_args=['-Dpkg_config_path=' + os.path.join(testdir, 'extra_path')])
self.init(testdir, extra_args=['-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path')])
def test_std_remains(self):
# C_std defined in project options must be in effect also when native compiling.
testdir = os.path.join(self.unit_test_dir, '50 std remains')
self.init(testdir)
compdb = self.get_compdb()
self.assertRegex(compdb[0]['command'], '-std=c99')
self.build()
def should_run_cross_arm_tests():
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
@ -5247,6 +5257,14 @@ class LinuxCrossArmTests(BasePlatformTests):
return
self.assertTrue(False, 'Option libdir not in introspect data.')
def test_std_remains(self):
# C_std defined in project options must be in effect also when cross compiling.
testdir = os.path.join(self.unit_test_dir, '50 std remains')
self.init(testdir)
compdb = self.get_compdb()
self.assertRegex(compdb[0]['command'], '-std=c99')
self.build()
def should_run_cross_mingw_tests():
return shutil.which('x86_64-w64-mingw32-gcc') and not (is_windows() or is_cygwin())
@ -5294,7 +5312,10 @@ class LinuxCrossMingwTests(BasePlatformTests):
@skipIfNoPkgconfig
def test_cross_pkg_config_option(self):
testdir = os.path.join(self.unit_test_dir, '55 pkg_config_path option')
self.init(testdir, extra_args=['-Dcross_pkg_config_path=' + os.path.join(testdir, 'extra_path')])
self.init(testdir, extra_args=[
'-Dbuild.pkg_config_path=' + os.path.join(testdir, 'build_extra_path'),
'-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path'),
])
class PythonTests(BasePlatformTests):

@ -0,0 +1,2 @@
project('std_remains', 'c', default_options: ['c_std=c99'])
executable('prog', 'prog.c')

@ -0,0 +1 @@
int main(int argc, char **argv) { return 0; }

@ -0,0 +1,7 @@
prefix=/
libdir=${prefix}/lib
includedir=${prefix}/include
Name: totally_made_up_dep
Description: completely and totally made up for a test case
Version: 4.5.6

@ -1,3 +1,12 @@
project('pkg_config_path option')
dependency('totally_made_up_dep', method : 'pkg-config')
build = dependency('totally_made_up_dep', native: true, method : 'pkg-config')
host = dependency('totally_made_up_dep', native: false, method : 'pkg-config')
# TODO always test we can do this separately
if meson.is_cross_build()
assert(build.version() == '4.5.6', 'wrong version for build machine dependency')
else
assert(host.version() == '1.2.3', 'wrong version for host machine dependency')
endif
assert(host.version() == '1.2.3', 'wrong version for host machine dependency')

Loading…
Cancel
Save