OptionOverrideProxy: Handle per-subproject options

pull/10165/head
Xavier Claessens 3 years ago committed by Xavier Claessens
parent 06d12064d0
commit 34f442a365
  1. 13
      mesonbuild/backend/backends.py
  2. 29
      mesonbuild/mesonlib/universal.py

@ -312,19 +312,16 @@ class Backend:
def get_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy: def get_options_for_target(self, target: build.BuildTarget) -> OptionOverrideProxy:
return OptionOverrideProxy(target.option_overrides, return OptionOverrideProxy(target.option_overrides,
self.environment.coredata.options) self.environment.coredata.options,
target.subproject)
def get_option_for_target(self, option_name: 'OptionKey', target: build.BuildTarget) -> T.Union[str, int, bool, 'WrapMode']: def get_option_for_target(self, key: 'OptionKey', target: build.BuildTarget) -> T.Union[str, int, bool, 'WrapMode']:
if option_name in target.option_overrides_base: options = self.get_options_for_target(target)
override = target.option_overrides_base[option_name]
v = self.environment.coredata.validate_option_value(option_name, override)
else:
v = self.environment.coredata.get_option(option_name.evolve(subproject=target.subproject))
# We don't actually have wrapmode here to do an assert, so just do a # We don't actually have wrapmode here to do an assert, so just do a
# cast, we know what's in coredata anyway. # cast, we know what's in coredata anyway.
# TODO: if it's possible to annotate get_option or validate_option_value # TODO: if it's possible to annotate get_option or validate_option_value
# in the future we might be able to remove the cast here # in the future we might be able to remove the cast here
return T.cast('T.Union[str, int, bool, WrapMode]', v) return T.cast('T.Union[str, int, bool, WrapMode]', options[key].value)
def get_source_dir_include_args(self, target: build.BuildTarget, compiler: 'Compiler', *, absolute_path: bool = False) -> T.List[str]: def get_source_dir_include_args(self, target: build.BuildTarget, compiler: 'Compiler', *, absolute_path: bool = False) -> T.List[str]:
curdir = target.get_subdir() curdir = target.get_subdir()

@ -1946,18 +1946,29 @@ class OptionOverrideProxy(collections.abc.Mapping):
# TODO: the typing here could be made more explicit using a TypeDict from # TODO: the typing here could be made more explicit using a TypeDict from
# python 3.8 or typing_extensions # python 3.8 or typing_extensions
def __init__(self, overrides: T.Dict['OptionKey', T.Any], options: 'KeyedOptionDictType'): def __init__(self, overrides: T.Dict['OptionKey', T.Any], options: 'KeyedOptionDictType',
subproject: T.Optional[str] = None):
self.overrides = overrides self.overrides = overrides
self.options = options self.options = options
self.subproject = subproject
def __getitem__(self, key: 'OptionKey') -> 'UserOption': def __getitem__(self, key: 'OptionKey') -> 'UserOption':
if key in self.options: # FIXME: This is fundamentally the same algorithm than interpreter.get_option_internal().
# We should try to share the code somehow.
key = key.evolve(subproject=self.subproject)
if not key.is_project():
opt = self.options.get(key)
if opt is None or opt.yielding:
opt = self.options[key.as_root()]
else:
opt = self.options[key] opt = self.options[key]
if key in self.overrides: if opt.yielding:
opt = copy.copy(opt) opt = self.options.get(key.as_root(), opt)
opt.set_value(self.overrides[key]) override_value = self.overrides.get(key.as_root())
return opt if override_value is not None :
raise KeyError('Option not found', key) opt = copy.copy(opt)
opt.set_value(override_value)
return opt
def __iter__(self) -> T.Iterator['OptionKey']: def __iter__(self) -> T.Iterator['OptionKey']:
return iter(self.options) return iter(self.options)
@ -1968,8 +1979,8 @@ class OptionOverrideProxy(collections.abc.Mapping):
def __eq__(self, other: object) -> bool: def __eq__(self, other: object) -> bool:
if not isinstance(other, OptionOverrideProxy): if not isinstance(other, OptionOverrideProxy):
return NotImplemented return NotImplemented
t1 = (self.overrides, self.options) t1 = (self.overrides, self.subproject, self.options)
t2 = (other.overrides, other.options) t2 = (other.overrides, other.subproject, other.options)
return t1 == t2 return t1 == t2

Loading…
Cancel
Save