Add support for module options

pull/9357/merge
Xavier Claessens 3 years ago committed by Eli Schwartz
parent 9b2bc0be6d
commit 2628ce576c
  1. 1
      mesonbuild/build.py
  2. 1
      mesonbuild/interpreter/interpreter.py
  3. 10
      mesonbuild/mconf.py
  4. 50
      mesonbuild/mesonlib/universal.py

@ -271,6 +271,7 @@ class Build:
self.dependency_overrides: PerMachine[T.Dict[T.Tuple, DependencyOverride]] = PerMachineDefaultable.default(
environment.is_cross_build(), {}, {})
self.devenv: T.List[EnvironmentVariables] = []
self.modules: T.List[str] = []
def get_build_targets(self):
build_targets = OrderedDict()

@ -551,6 +551,7 @@ class Interpreter(InterpreterBase, HoldableObject):
else:
ext_module = module.initialize(self)
assert isinstance(ext_module, (ExtensionModule, NewExtensionModule))
self.build.modules.append(modname)
self.modules[modname] = ext_module
return ext_module

@ -17,6 +17,7 @@ import shutil
import os
import textwrap
import typing as T
import collections
from . import build
from . import coredata
@ -243,11 +244,18 @@ class Conf:
dir_options: 'coredata.KeyedOptionDictType' = {}
test_options: 'coredata.KeyedOptionDictType' = {}
core_options: 'coredata.KeyedOptionDictType' = {}
module_options: T.Dict[str, 'coredata.KeyedOptionDictType'] = collections.defaultdict(dict)
for k, v in self.coredata.options.items():
if k in dir_option_names:
dir_options[k] = v
elif k in test_option_names:
test_options[k] = v
elif k.module:
# Ignore module options if we did not use that module during
# configuration.
if self.build and k.module not in self.build.modules:
continue
module_options[k.module][k] = v
elif k.is_builtin():
core_options[k] = v
@ -267,6 +275,8 @@ class Conf:
self.print_options('Compiler options', host_compiler_options.get('', {}))
if show_build_options:
self.print_options('', build_compiler_options.get('', {}))
for mod, mod_options in module_options.items():
self.print_options(f'{mod} module options', mod_options)
self.print_options('Directories', dir_options)
self.print_options('Testing options', test_options)
self.print_options('Project options', project_options.get('', {}))

@ -2024,7 +2024,7 @@ def _classify_argument(key: 'OptionKey') -> OptionType:
return OptionType.BASE
elif key.lang is not None:
return OptionType.COMPILER
elif key.name in _BUILTIN_NAMES:
elif key.name in _BUILTIN_NAMES or key.module:
return OptionType.BUILTIN
elif key.name.startswith('backend_'):
assert key.machine is MachineChoice.HOST, str(key)
@ -2044,7 +2044,7 @@ class OptionKey:
internally easier to reason about and produce.
"""
__slots__ = ['name', 'subproject', 'machine', 'lang', '_hash', 'type']
__slots__ = ['name', 'subproject', 'machine', 'lang', '_hash', 'type', 'module']
name: str
subproject: str
@ -2052,10 +2052,13 @@ class OptionKey:
lang: T.Optional[str]
_hash: int
type: OptionType
module: T.Optional[str]
def __init__(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
lang: T.Optional[str] = None, _type: T.Optional[OptionType] = None):
lang: T.Optional[str] = None,
module: T.Optional[str] = None,
_type: T.Optional[OptionType] = None):
# the _type option to the constructor is kinda private. We want to be
# able tos ave the state and avoid the lookup function when
# pickling/unpickling, but we need to be able to calculate it when
@ -2064,7 +2067,8 @@ class OptionKey:
object.__setattr__(self, 'subproject', subproject)
object.__setattr__(self, 'machine', machine)
object.__setattr__(self, 'lang', lang)
object.__setattr__(self, '_hash', hash((name, subproject, machine, lang)))
object.__setattr__(self, 'module', module)
object.__setattr__(self, '_hash', hash((name, subproject, machine, lang, module)))
if _type is None:
_type = _classify_argument(self)
object.__setattr__(self, 'type', _type)
@ -2079,6 +2083,7 @@ class OptionKey:
'machine': self.machine,
'lang': self.lang,
'_type': self.type,
'module': self.module,
}
def __setstate__(self, state: T.Dict[str, T.Any]) -> None:
@ -2095,20 +2100,17 @@ class OptionKey:
def __hash__(self) -> int:
return self._hash
def _to_tuple(self):
return (self.subproject, self.type, self.lang or '', self.module or '', self.machine, self.name)
def __eq__(self, other: object) -> bool:
if isinstance(other, OptionKey):
return (
self.name == other.name and
self.subproject == other.subproject and
self.machine is other.machine and
self.lang == other.lang)
return self._to_tuple() == other._to_tuple()
return NotImplemented
def __lt__(self, other: object) -> bool:
if isinstance(other, OptionKey):
self_tuple = (self.subproject, self.type, self.lang, self.machine, self.name)
other_tuple = (other.subproject, other.type, other.lang, other.machine, other.name)
return self_tuple < other_tuple
return self._to_tuple() < other._to_tuple()
return NotImplemented
def __str__(self) -> str:
@ -2117,6 +2119,8 @@ class OptionKey:
out = f'{self.lang}_{out}'
if self.machine is MachineChoice.BUILD:
out = f'build.{out}'
if self.module:
out = f'{self.module}.{out}'
if self.subproject:
out = f'{self.subproject}:{out}'
return out
@ -2136,12 +2140,16 @@ class OptionKey:
except ValueError:
subproject, raw2 = '', raw
if raw2.startswith('build.'):
raw3 = raw2.split('.', 1)[1]
for_machine = MachineChoice.BUILD
else:
module = None
for_machine = MachineChoice.HOST
try:
prefix, raw3 = raw2.split('.')
if prefix == 'build':
for_machine = MachineChoice.BUILD
else:
module = prefix
except ValueError:
raw3 = raw2
for_machine = MachineChoice.HOST
from ..compilers import all_languages
if any(raw3.startswith(f'{l}_') for l in all_languages):
@ -2149,12 +2157,13 @@ class OptionKey:
else:
lang, opt = None, raw3
assert ':' not in opt
assert 'build.' not in opt
assert '.' not in opt
return cls(opt, subproject, for_machine, lang)
return cls(opt, subproject, for_machine, lang, module)
def evolve(self, name: T.Optional[str] = None, subproject: T.Optional[str] = None,
machine: T.Optional[MachineChoice] = None, lang: T.Optional[str] = '') -> 'OptionKey':
machine: T.Optional[MachineChoice] = None, lang: T.Optional[str] = '',
module: T.Optional[str] = '') -> 'OptionKey':
"""Create a new copy of this key, but with alterted members.
For example:
@ -2170,6 +2179,7 @@ class OptionKey:
subproject if subproject is not None else self.subproject,
machine if machine is not None else self.machine,
lang if lang != '' else self.lang,
module if module != '' else self.module
)
def as_root(self) -> 'OptionKey':

Loading…
Cancel
Save