diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index f9a6e11c0eb4..9110d6c1915c 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -183,7 +183,7 @@ def _add_languages(self, raw_langs: T.List[TYPE_var], required: bool, for_machin v = copy.copy(self.coredata.options[k]) k = k.evolve(subproject=self.subproject) options[k] = v - self.coredata.add_compiler_options(options, lang, for_machine, self.environment) + self.coredata.add_compiler_options(options, lang, for_machine, self.environment, self.subproject) def func_dependency(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> None: args = self.flatten_args(args) diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index dbc2b4879208..f88fe9a58257 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -106,7 +106,7 @@ def detect_compiler_for(env: 'Environment', lang: str, for_machine: MachineChoic if comp is None: return comp assert comp.for_machine == for_machine - env.coredata.process_compiler_options(lang, comp, env) + env.coredata.process_compiler_options(lang, comp, env, '') if not skip_sanity_check: comp.sanity_check(env.get_scratch_dir(), env) env.coredata.compilers[comp.for_machine][lang] = comp diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 72f0054c05aa..4da15645a5f3 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -1016,8 +1016,8 @@ def set_default_options(self, default_options: T.MutableMapping[OptionKey, str], self.set_options(options, subproject=subproject, first_invocation=env.first_invocation) - def add_compiler_options(self, options: 'MutableKeyedOptionDictType', lang: str, for_machine: MachineChoice, - env: 'Environment') -> None: + def add_compiler_options(self, options: MutableKeyedOptionDictType, lang: str, for_machine: MachineChoice, + env: Environment, subproject: str) -> None: for k, o in options.items(): value = env.options.get(k) if value is not None: @@ -1025,6 +1025,20 @@ def add_compiler_options(self, options: 'MutableKeyedOptionDictType', lang: str, self.options[k] = o # override compiler option on reconfigure self.options.setdefault(k, o) + if subproject: + k = k.evolve(subproject=subproject) + if k in env.options: + self.options[k] = o + + unknown_options: T.List[OptionKey] = [] + for k in env.options: + if k.lang == lang and k.subproject == subproject and k.evolve(subproject='') not in self.options: + unknown_options.append(k) + if unknown_options: + unknown_options_str = ', '.join(sorted(str(s) for s in unknown_options)) + sub = f'In subproject {subproject}: ' if subproject else '' + raise MesonException(f'{sub}Unknown options: "{unknown_options_str}"') + def add_lang_args(self, lang: str, comp: T.Type['Compiler'], for_machine: MachineChoice, env: 'Environment') -> None: """Add global language arguments that are needed before compiler/linker detection.""" @@ -1034,10 +1048,10 @@ def add_lang_args(self, lang: str, comp: T.Type['Compiler'], # `self.options.update()`` is perfectly safe. self.options.update(compilers.get_global_options(lang, comp, for_machine, env)) - def process_compiler_options(self, lang: str, comp: 'Compiler', env: 'Environment') -> None: + def process_compiler_options(self, lang: str, comp: Compiler, env: Environment, subproject: str) -> None: from . import compilers - self.add_compiler_options(comp.get_options(), lang, comp.for_machine, env) + self.add_compiler_options(comp.get_options(), lang, comp.for_machine, env, subproject) enabled_opts: T.List[OptionKey] = [] for key in comp.base_options: diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index e5a201e053e4..56740d76c75f 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1520,7 +1520,7 @@ def add_languages_for(self, args: T.List[str], required: bool, for_machine: Mach raise else: # update new values from commandline, if it applies - self.coredata.process_compiler_options(lang, comp, self.environment) + self.coredata.process_compiler_options(lang, comp, self.environment, self.subproject) # Add per-subproject compiler options. They inherit value from main project. if self.subproject: @@ -1529,7 +1529,7 @@ def add_languages_for(self, args: T.List[str], required: bool, for_machine: Mach v = copy.copy(self.coredata.options[k]) k = k.evolve(subproject=self.subproject) options[k] = v - self.coredata.add_compiler_options(options, lang, for_machine, self.environment) + self.coredata.add_compiler_options(options, lang, for_machine, self.environment, self.subproject) if for_machine == MachineChoice.HOST or self.environment.is_cross_build(): logger_fun = mlog.log diff --git a/run_project_tests.py b/run_project_tests.py index 6fc9cb7f77fa..a14741364aab 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -981,7 +981,7 @@ def have_working_compiler(lang: str, use_tmp: bool) -> bool: return False if not compiler: return False - env.coredata.process_compiler_options(lang, compiler, env) + env.coredata.process_compiler_options(lang, compiler, env, '') try: compiler.sanity_check(env.get_scratch_dir(), env) except mesonlib.MesonException: diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py index 28a79a0d4b7b..0b2179cfec24 100644 --- a/unittests/platformagnostictests.py +++ b/unittests/platformagnostictests.py @@ -289,6 +289,6 @@ def test_reconfigure_base_options(self): def test_setup_with_unknown_option(self): testdir = os.path.join(self.common_test_dir, '1 trivial') - for option in ('not_an_option', 'b_not_an_option'): + for option in ('not_an_option', 'b_not_an_option', 'c_not_an_option'): out = self.init(testdir, extra_args=['--wipe', f'-D{option}=1'], inprocess=True, allow_fail=True) self.assertIn(f'ERROR: Unknown options: "{option}"', out)