summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-07-09 00:30:29 +0200
committerDylan Baker <dylan@pnwbakers.com>2025-07-09 09:45:28 -0700
commit9ad10ee78f632a60d35327eaa9b88c7efde35fe6 (patch)
tree5bad6580148299238125c69e446f9fa4e12cf527
parentb92ae89ac742e229f477701488677106930bc91a (diff)
downloadmeson-9ad10ee78f632a60d35327eaa9b88c7efde35fe6.tar.gz
options: do not overwrite parent options when a yielding option is set
Fixes: #14774 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/options.py32
1 files changed, 21 insertions, 11 deletions
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index b9b00eff5..317acbd79 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -848,7 +848,7 @@ class OptionStore:
def __len__(self) -> int:
return len(self.options)
- def get_value_object_for(self, key: 'T.Union[OptionKey, str]') -> AnyOptionType:
+ def get_key_and_value_object_for(self, key: 'T.Union[OptionKey, str]') -> T.Tuple[OptionKey, AnyOptionType]:
key = self.ensure_and_validate_key(key)
potential = self.options.get(key, None)
if self.is_project_option(key):
@@ -861,26 +861,31 @@ class OptionStore:
# Subproject is set to yield, but top level
# project does not have an option of the same
# name. Return the subproject option.
- return potential
+ return key, potential
# If parent object has different type, do not yield.
# This should probably be an error.
if type(parent_option) is type(potential):
- return parent_option
- return potential
+ return parent_key, parent_option
+ return key, potential
if potential is None:
raise KeyError(f'Tried to access nonexistant project option {key}.')
- return potential
+ return key, potential
else:
if potential is None:
parent_key = OptionKey(key.name, subproject=None, machine=key.machine)
if parent_key not in self.options:
raise KeyError(f'Tried to access nonexistant project parent option {parent_key}.')
- return self.options[parent_key]
- return potential
+ # This is a global option but it can still have per-project
+ # augment, so return the subproject key.
+ return key, self.options[parent_key]
+ return key, potential
+
+ def get_value_object_for(self, key: 'T.Union[OptionKey, str]') -> AnyOptionType:
+ return self.get_key_and_value_object_for(key)[1]
def get_value_object_and_value_for(self, key: OptionKey) -> T.Tuple[AnyOptionType, ElementaryOptionValues]:
assert isinstance(key, OptionKey)
- vobject = self.get_value_object_for(key)
+ _, vobject = self.get_key_and_value_object_for(key)
computed_value = vobject.value
if key in self.augments:
assert key.subproject is not None
@@ -1015,7 +1020,7 @@ class OptionStore:
new_value = self.sanitize_dir_option_value(prefix, key, new_value)
try:
- opt = self.get_value_object_for(key)
+ actual_key, opt = self.get_key_and_value_object_for(key)
except KeyError:
raise MesonException(f'Unknown option: "{error_key}".')
@@ -1042,8 +1047,13 @@ class OptionStore:
new_value = opt.validate_value(new_value)
if key in self.options:
- old_value = opt.value
- opt.set_value(new_value)
+ if actual_key.subproject == key.subproject:
+ old_value = opt.value
+ opt.set_value(new_value)
+ else:
+ # the key must have pointed to a yielding option;
+ # do not overwrite the global value in that case
+ return changed
else:
assert key.subproject is not None
old_value = self.augments.get(key, opt.value)