aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Builtin-options.md55
-rw-r--r--docs/markdown/snippets/per-machine-options.md15
-rw-r--r--mesonbuild/coredata.py195
-rw-r--r--mesonbuild/dependencies/base.py12
-rw-r--r--mesonbuild/interpreter.py25
-rw-r--r--mesonbuild/mconf.py13
-rw-r--r--mesonbuild/mesonlib.py12
-rw-r--r--mesonbuild/mintro.py14
-rw-r--r--mesonbuild/rewriter.py7
-rwxr-xr-xrun_unittests.py13
-rw-r--r--test cases/unit/55 pkg_config_path option/build_extra_path/totally_made_up_dep.pc7
-rw-r--r--test cases/unit/55 pkg_config_path option/host_extra_path/totally_made_up_dep.pc (renamed from test cases/unit/55 pkg_config_path option/extra_path/totally_made_up_dep.pc)0
-rw-r--r--test cases/unit/55 pkg_config_path option/meson.build11
13 files changed, 233 insertions, 146 deletions
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index 9c87aef..77f8db1 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -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
diff --git a/docs/markdown/snippets/per-machine-options.md b/docs/markdown/snippets/per-machine-options.md
new file mode 100644
index 0000000..d19c68e
--- /dev/null
+++ b/docs/markdown/snippets/per-machine-options.md
@@ -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.
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index e1dd74b..173bdc7 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -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 = {
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index a191f07..a6fb0b6 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -665,11 +665,12 @@ 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')
+ 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
@@ -1137,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)))
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 83fc2f1..a945f70 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -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():
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index 6e0d2d0..84c41d0 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -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:
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index ec4aa9f..e3ddf28 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -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
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 7975684..b700b00 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -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')
diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py
index a6860d5..e700718 100644
--- a/mesonbuild/rewriter.py
+++ b/mesonbuild/rewriter.py
@@ -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()):
diff --git a/run_unittests.py b/run_unittests.py
index b8f0bf2..ff623b9 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -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,7 @@ 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 should_run_cross_arm_tests():
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
@@ -5294,7 +5296,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):
diff --git a/test cases/unit/55 pkg_config_path option/build_extra_path/totally_made_up_dep.pc b/test cases/unit/55 pkg_config_path option/build_extra_path/totally_made_up_dep.pc
new file mode 100644
index 0000000..5b149f6
--- /dev/null
+++ b/test cases/unit/55 pkg_config_path option/build_extra_path/totally_made_up_dep.pc
@@ -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
diff --git a/test cases/unit/55 pkg_config_path option/extra_path/totally_made_up_dep.pc b/test cases/unit/55 pkg_config_path option/host_extra_path/totally_made_up_dep.pc
index 6d08687..6d08687 100644
--- a/test cases/unit/55 pkg_config_path option/extra_path/totally_made_up_dep.pc
+++ b/test cases/unit/55 pkg_config_path option/host_extra_path/totally_made_up_dep.pc
diff --git a/test cases/unit/55 pkg_config_path option/meson.build b/test cases/unit/55 pkg_config_path option/meson.build
index 623c3a2..3af6164 100644
--- a/test cases/unit/55 pkg_config_path option/meson.build
+++ b/test cases/unit/55 pkg_config_path option/meson.build
@@ -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')