summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-06-20 10:43:53 +0200
committerJussi Pakkanen <jussi.pakkanen@mailbox.org>2025-07-07 20:32:11 +0300
commitf95c2bb012ea4bbc07a6018823aee1831fa47f28 (patch)
treee6ffc4fd51867204157812983b578b4892c4f884
parent70ebe33a3e0990b5df4a6c1579d9e91d34515a9b (diff)
downloadmeson-f95c2bb012ea4bbc07a6018823aee1831fa47f28.tar.gz
options: give priority to parent augments over child default_options
Restore behavior of 1.7. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--mesonbuild/options.py26
-rw-r--r--unittests/optiontests.py20
2 files changed, 41 insertions, 5 deletions
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index 9ea523b8f..38bfdf034 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -1357,16 +1357,32 @@ class OptionStore:
project_default_options: OptionDict,
cmd_line_options: OptionDict,
machine_file_options: OptionDict) -> None:
- # pick up pending per-project settings from the toplevel project() invocation
- options = {k: v for k, v in self.pending_subproject_options.items() if k.subproject == subproject}
- # apply project() and subproject() default_options
- for key, valstr in itertools.chain(project_default_options.items(), spcall_default_options.items()):
+ options: OptionDict = {}
+
+ # project() default_options
+ for key, valstr in project_default_options.items():
+ if key.subproject == subproject:
+ without_subp = key.evolve(subproject=None)
+ raise MesonException(f'subproject name not needed in default_options; use "{without_subp}" instead of "{key}"')
+
if key.subproject is None:
key = key.evolve(subproject=subproject)
- elif key.subproject == subproject:
+ options[key] = valstr
+
+ # augments from the toplevel project() default_options
+ for key, valstr in self.pending_subproject_options.items():
+ if key.subproject == subproject:
+ options[key] = valstr
+
+ # subproject() default_options
+ for key, valstr in spcall_default_options.items():
+ if key.subproject == subproject:
without_subp = key.evolve(subproject=None)
raise MesonException(f'subproject name not needed in default_options; use "{without_subp}" instead of "{key}"')
+
+ if key.subproject is None:
+ key = key.evolve(subproject=subproject)
options[key] = valstr
# then global settings from machine file and command line
diff --git a/unittests/optiontests.py b/unittests/optiontests.py
index 1fffc13b7..3da6f31df 100644
--- a/unittests/optiontests.py
+++ b/unittests/optiontests.py
@@ -274,6 +274,26 @@ class OptionTests(unittest.TestCase):
self.assertEqual(optstore.get_value_for(name, subp), new_value)
self.assertEqual(optstore.get_value_for(name), new_value)
+ def test_subproject_parent_override_subp(self):
+ name = 'optimization'
+ subp = 'subp'
+ default_value = 's'
+ subp_value = '0'
+
+ optstore = OptionStore(False)
+ prefix = UserStringOption('prefix', 'This is needed by OptionStore', '/usr')
+ optstore.add_system_option('prefix', prefix)
+ o = UserComboOption(name, 'Optimization level', '0', choices=['plain', '0', 'g', '1', '2', '3', 's'])
+ optstore.add_system_option(name, o)
+
+ toplevel_proj_default = {OptionKey(name, subproject=subp): subp_value, OptionKey(name): default_value}
+ subp_proj_default = {OptionKey(name): '3'}
+
+ optstore.initialize_from_top_level_project_call(toplevel_proj_default, {}, {})
+ optstore.initialize_from_subproject_call(subp, {}, subp_proj_default, {}, {})
+ self.assertEqual(optstore.get_value_for(name, subp), subp_value)
+ self.assertEqual(optstore.get_value_for(name), default_value)
+
def test_subproject_cmdline_override_global_and_augment(self):
name = 'optimization'
subp = 'subp'