summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/meson_configure_options_changes.md12
-rw-r--r--mesonbuild/interpreter/interpreter.py4
-rw-r--r--mesonbuild/mconf.py31
-rw-r--r--unittests/platformagnostictests.py10
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'))