diff options
| -rw-r--r-- | docs/markdown/snippets/meson_configure_options_changes.md | 12 | ||||
| -rw-r--r-- | mesonbuild/interpreter/interpreter.py | 4 | ||||
| -rw-r--r-- | mesonbuild/mconf.py | 31 | ||||
| -rw-r--r-- | unittests/platformagnostictests.py | 10 |
4 files changed, 45 insertions, 12 deletions
diff --git a/docs/markdown/snippets/meson_configure_options_changes.md b/docs/markdown/snippets/meson_configure_options_changes.md new file mode 100644 index 000000000..c86792ceb --- /dev/null +++ b/docs/markdown/snippets/meson_configure_options_changes.md @@ -0,0 +1,12 @@ +## Meson configure handles changes to options in more cases + +Meson configure now correctly handles updates to the options file without a full +reconfigure. This allows making a change to the `meson.options` or +`meson_options.txt` file without a reconfigure. + +For example, this now works: +```sh +meson setup builddir +git pull +meson configure builddir -Doption-added-by-pull=value +``` diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 2c1ac89f6..730eddd4a 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1190,8 +1190,8 @@ class Interpreter(InterpreterBase, HoldableObject): option_file = old_option_file if os.path.exists(option_file): with open(option_file, 'rb') as f: - # We want fast, not cryptographically secure, this is just to see of - # the option file has changed + # We want fast not cryptographically secure, this is just to + # see if the option file has changed self.coredata.options_files[self.subproject] = (option_file, hashlib.sha1(f.read()).hexdigest()) oi = optinterpreter.OptionInterpreter(self.subproject) oi.process(option_file) diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py index 8c18eab31..2cef24fd7 100644 --- a/mesonbuild/mconf.py +++ b/mesonbuild/mconf.py @@ -1,10 +1,11 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2014-2016 The Meson development team -# Copyright © 2023 Intel Corporation +# Copyright © 2023-2024 Intel Corporation from __future__ import annotations import itertools +import hashlib import shutil import os import textwrap @@ -19,6 +20,7 @@ from . import mintro from . import mlog from .ast import AstIDGenerator, IntrospectionInterpreter from .mesonlib import MachineChoice, OptionKey +from .optinterpreter import OptionInterpreter if T.TYPE_CHECKING: from typing_extensions import Protocol @@ -77,6 +79,33 @@ class Conf: self.source_dir = self.build.environment.get_source_dir() self.coredata = self.build.environment.coredata self.default_values_only = False + + # if the option file has been updated, reload it + # This cannot handle options for a new subproject that has not yet + # been configured. + for sub, options in self.coredata.options_files.items(): + if options is not None and os.path.exists(options[0]): + opfile = options[0] + with open(opfile, 'rb') as f: + ophash = hashlib.sha1(f.read()).hexdigest() + if ophash != options[1]: + oi = OptionInterpreter(sub) + oi.process(opfile) + self.coredata.update_project_options(oi.options, sub) + self.coredata.options_files[sub] = (opfile, ophash) + else: + opfile = os.path.join(self.source_dir, 'meson.options') + if not os.path.exists(opfile): + opfile = os.path.join(self.source_dir, 'meson_options.txt') + if os.path.exists(opfile): + oi = OptionInterpreter(sub) + oi.process(opfile) + self.coredata.update_project_options(oi.options, sub) + with open(opfile, 'rb') as f: + ophash = hashlib.sha1(f.read()).hexdigest() + self.coredata.options_files[sub] = (opfile, ophash) + else: + self.coredata.update_project_options({}, sub) elif os.path.isfile(os.path.join(self.build_dir, environment.build_filename)): # Make sure that log entries in other parts of meson don't interfere with the JSON output with mlog.no_logging(): diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py index 969cbd747..ba3f5013c 100644 --- a/unittests/platformagnostictests.py +++ b/unittests/platformagnostictests.py @@ -10,7 +10,7 @@ import tempfile import subprocess import textwrap import shutil -from unittest import expectedFailure, skipIf, SkipTest +from unittest import skipIf, SkipTest from pathlib import Path from .baseplatformtests import BasePlatformTests @@ -318,7 +318,6 @@ class PlatformAgnosticTests(BasePlatformTests): out = self.init(testdir, extra_args=['--wipe', f'-D{option}=1'], allow_fail=True) self.assertIn(f'ERROR: Unknown options: "{option}"', out) - @expectedFailure def test_configure_new_option(self) -> None: """Adding a new option without reconfiguring should work.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '40 options')) @@ -328,7 +327,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dnew_option=true') self.assertEqual(self.getconf('new_option'), True) - @expectedFailure def test_configure_removed_option(self) -> None: """Removing an options without reconfiguring should still give an error.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '40 options')) @@ -344,7 +342,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dneg_int_opt=0') self.assertIn('Unknown options: "neg_int_opt"', e.exception.stdout) - @expectedFailure def test_configure_option_changed_constraints(self) -> None: """Changing the constraints of an option without reconfiguring should work.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '40 options')) @@ -360,7 +357,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dneg_int_opt=-10') self.assertEqual(self.getconf('neg_int_opt'), -10) - @expectedFailure def test_configure_meson_options_txt_to_meson_options(self) -> None: """Changing from a meson_options.txt to meson.options should still be detected.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '40 options')) @@ -377,7 +373,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dneg_int_opt=-10') self.assertEqual(self.getconf('neg_int_opt'), -10) - @expectedFailure def test_configure_options_file_deleted(self) -> None: """Deleting all option files should make seting a project option an error.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '40 options')) @@ -387,7 +382,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dneg_int_opt=0') self.assertIn('Unknown options: "neg_int_opt"', e.exception.stdout) - @expectedFailure def test_configure_options_file_added(self) -> None: """A new project option file should be detected.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '1 trivial')) @@ -397,7 +391,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dnew_option=bar') self.assertEqual(self.getconf('new_option'), 'bar') - @expectedFailure def test_configure_options_file_added_old(self) -> None: """A new project option file should be detected.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '1 trivial')) @@ -407,7 +400,6 @@ class PlatformAgnosticTests(BasePlatformTests): self.setconf('-Dnew_option=bar') self.assertEqual(self.getconf('new_option'), 'bar') - @expectedFailure def test_configure_new_option_subproject(self) -> None: """Adding a new option to a subproject without reconfiguring should work.""" testdir = self.copy_srcdir(os.path.join(self.common_test_dir, '43 subproject options')) |
