diff --git a/docs/markdown/snippets/unknown-options-always-fatal.md b/docs/markdown/snippets/unknown-options-always-fatal.md new file mode 100644 index 000000000000..ce982c3caebb --- /dev/null +++ b/docs/markdown/snippets/unknown-options-always-fatal.md @@ -0,0 +1,5 @@ +## Unknown options are now always fatal + +Passing unknown options to "meson setup" or "meson configure" is now +always fatal. That is, Meson will exit with an error code if this +happens. Previous Meson versions only showed a warning message. diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index c2604be3a82e..37d830de2f3b 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -758,7 +758,7 @@ def copy_build_options_from_regular_ones(self) -> None: except KeyError: continue - def set_options(self, options: T.Dict[OptionKey, T.Any], subproject: str = '', warn_unknown: bool = True) -> None: + def set_options(self, options: T.Dict[OptionKey, T.Any], subproject: str = '') -> None: if not self.is_cross_build(): options = {k: v for k, v in options.items() if k.machine is not MachineChoice.BUILD} # Set prefix first because it's needed to sanitize other options @@ -774,16 +774,15 @@ def set_options(self, options: T.Dict[OptionKey, T.Any], subproject: str = '', w for k, v in options.items(): if k == pfk: continue - elif k not in self.options: - unknown_options.append(k) - else: + elif k in self.options: self.set_option(k, v) - if unknown_options and warn_unknown: + elif k.machine != MachineChoice.BUILD: + 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 '' - mlog.warning(f'{sub}Unknown options: "{unknown_options_str}"') - mlog.log('The value of new options can be set with:') - mlog.log(mlog.bold('meson setup --reconfigure -Dnew_option=new_value ...')) + raise MesonException(f'{sub}Unknown options: "{unknown_options_str}"') + if not self.is_cross_build(): self.copy_build_options_from_regular_ones() diff --git a/run_unittests.py b/run_unittests.py index 324de94379e1..830678255f49 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -3306,8 +3306,6 @@ def test_lto_threads(self): if cc.get_id() == 'clang': if is_windows(): raise unittest.SkipTest('LTO not (yet) supported by windows clang') - else: - extra_args.append('-D_cargs=-Werror=unused-command-line-argument') self.init(testdir, extra_args=['-Db_lto=true', '-Db_lto_threads=8'] + extra_args) self.build() @@ -4315,9 +4313,11 @@ def test_command_line(self): self.assertEqual(obj.options[OptionKey('default_library')].value, 'shared') self.wipe() - # Should warn on unknown options - out = self.init(testdir, extra_args=['-Dbad=1', '-Dfoo=2', '-Dwrong_link_args=foo']) - self.assertIn('Unknown options: "bad, foo, wrong_link_args"', out) + # Should fail on unknown options + with self.assertRaises((subprocess.CalledProcessError, RuntimeError)) as cm: + self.init(testdir, extra_args=['-Dbad=1', '-Dfoo=2', '-Dwrong_link_args=foo']) + self.assertNotEqual(0, cm.exception.returncode) + self.assertIn(msg, cm.exception.output) self.wipe() # Should fail on malformed option