aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2024-06-29 12:41:50 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2024-06-29 12:41:50 +0300
commite062baf6bc1aaa45cabff4448420b74e229587ad (patch)
tree6da4f136a1cb851cdf741daa76314266fc94e58c
parent7b43a2e19613f3702935872b21b1020f7d8c6a9b (diff)
downloadmeson-optionkeyrefactor.zip
meson-optionkeyrefactor.tar.gz
meson-optionkeyrefactor.tar.bz2
Move project option detection into OptionStore.optionkeyrefactor
-rw-r--r--mesonbuild/ast/introspection.py2
-rw-r--r--mesonbuild/backend/ninjabackend.py2
-rw-r--r--mesonbuild/coredata.py6
-rw-r--r--mesonbuild/interpreter/interpreter.py4
-rw-r--r--mesonbuild/mconf.py6
-rw-r--r--mesonbuild/mintro.py2
-rw-r--r--mesonbuild/optinterpreter.py5
-rw-r--r--mesonbuild/options.py8
-rw-r--r--mesonbuild/utils/universal.py4
-rw-r--r--unittests/platformagnostictests.py7
10 files changed, 29 insertions, 17 deletions
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index 1197510..07f82df 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -105,7 +105,7 @@ class IntrospectionInterpreter(AstInterpreter):
if not os.path.exists(optfile):
optfile = os.path.join(self.source_root, self.subdir, 'meson_options.txt')
if os.path.exists(optfile):
- oi = optinterpreter.OptionInterpreter(self.subproject)
+ oi = optinterpreter.OptionInterpreter(self.coredata.optstore, self.subproject)
oi.process(optfile)
assert isinstance(proj_name, str), 'for mypy'
self.coredata.update_project_options(oi.options, T.cast('SubProject', proj_name))
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index eabe758..456615e 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -3603,7 +3603,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
def get_user_option_args(self):
cmds = []
for k, v in self.environment.coredata.optstore.items():
- if k.is_project():
+ if self.environment.coredata.optstore.is_project_option(k):
cmds.append('-D' + str(k) + '=' + (v.value if isinstance(v.value, str) else str(v.value).lower()))
# The order of these arguments must be the same between runs of Meson
# to ensure reproducible output. The order we pass them shouldn't
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 7fb3bca..1bd2269 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -584,7 +584,7 @@ class CoreData:
def update_project_options(self, project_options: 'MutableKeyedOptionDictType', subproject: SubProject) -> None:
for key, value in project_options.items():
- if not key.is_project():
+ if not self.optstore.is_project_option(key):
continue
if key not in self.optstore:
self.optstore.add_project_option(key, value)
@@ -608,7 +608,7 @@ class CoreData:
# Find any extranious keys for this project and remove them
for key in self.optstore.keys() - project_options.keys():
- if key.is_project() and key.subproject == subproject:
+ if self.optstore.is_project_option(key) and key.subproject == subproject:
self.optstore.remove(key)
def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool:
@@ -906,7 +906,7 @@ class OptionsView(abc.Mapping):
# FIXME: This is fundamentally the same algorithm than interpreter.get_option_internal().
# We should try to share the code somehow.
key = key.evolve(subproject=self.subproject)
- if not key.is_project():
+ if not key.is_project_hack_for_optionsview():
opt = self.original_options.get(key)
if opt is None or opt.yielding:
key2 = key.as_root()
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 13f7f22..742d24c 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -1051,7 +1051,7 @@ class Interpreter(InterpreterBase, HoldableObject):
def get_option_internal(self, optname: str) -> options.UserOption:
key = OptionKey.from_string(optname).evolve(subproject=self.subproject)
- if not key.is_project():
+ if not self.environment.coredata.optstore.is_project_option(key):
for opts in [self.coredata.optstore, compilers.base_options]:
v = opts.get(key)
if v is None or v.yielding:
@@ -1198,7 +1198,7 @@ class Interpreter(InterpreterBase, HoldableObject):
# 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 = optinterpreter.OptionInterpreter(self.environment.coredata.optstore, self.subproject)
oi.process(option_file)
self.coredata.update_project_options(oi.options, self.subproject)
self.add_build_def_file(option_file)
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index da96ac4..1294479 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -92,7 +92,7 @@ class Conf:
with open(opfile, 'rb') as f:
ophash = hashlib.sha1(f.read()).hexdigest()
if ophash != conf_options[1]:
- oi = OptionInterpreter(sub)
+ oi = OptionInterpreter(self.coredata.optstore, sub)
oi.process(opfile)
self.coredata.update_project_options(oi.options, sub)
self.coredata.options_files[sub] = (opfile, ophash)
@@ -101,7 +101,7 @@ class Conf:
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 = OptionInterpreter(self.coredata.optstore, sub)
oi.process(opfile)
self.coredata.update_project_options(oi.options, sub)
with open(opfile, 'rb') as f:
@@ -284,7 +284,7 @@ class Conf:
build_core_options = self.split_options_per_subproject({k: v for k, v in core_options.items() if k.machine is MachineChoice.BUILD})
host_compiler_options = self.split_options_per_subproject({k: v for k, v in self.coredata.optstore.items() if k.is_compiler() and k.machine is MachineChoice.HOST})
build_compiler_options = self.split_options_per_subproject({k: v for k, v in self.coredata.optstore.items() if k.is_compiler() and k.machine is MachineChoice.BUILD})
- project_options = self.split_options_per_subproject({k: v for k, v in self.coredata.optstore.items() if k.is_project()})
+ project_options = self.split_options_per_subproject({k: v for k, v in self.coredata.optstore.items() if self.coredata.optstore.is_project_option(k)})
show_build_options = self.default_values_only or self.build.environment.is_cross_build()
self.add_section('Main project options')
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index dea67d8..17d1b08 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -335,7 +335,7 @@ def list_buildoptions(coredata: cdata.CoreData, subprojects: T.Optional[T.List[s
'compiler',
)
add_keys(dir_options, 'directory')
- add_keys({k: v for k, v in coredata.optstore.items() if k.is_project()}, 'user')
+ add_keys({k: v for k, v in coredata.optstore.items() if coredata.optstore.is_project_option(k)}, 'user')
add_keys(test_options, 'test')
return optlist
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index ffa46cd..7c94c15 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -64,7 +64,7 @@ optname_regex = re.compile('[^a-zA-Z0-9_-]')
class OptionInterpreter:
- def __init__(self, subproject: 'SubProject') -> None:
+ def __init__(self, optionstore, subproject: 'SubProject') -> None:
self.options: 'coredata.MutableKeyedOptionDictType' = {}
self.subproject = subproject
self.option_types: T.Dict[str, T.Callable[..., options.UserOption]] = {
@@ -75,6 +75,7 @@ class OptionInterpreter:
'array': self.string_array_parser,
'feature': self.feature_parser,
}
+ self.optionstore = optionstore
def process(self, option_file: str) -> None:
try:
@@ -189,7 +190,7 @@ class OptionInterpreter:
if optname_regex.search(opt_name) is not None:
raise OptionException('Option names can only contain letters, numbers or dashes.')
key = mesonlib.OptionKey.from_string(opt_name).evolve(subproject=self.subproject)
- if not key.is_project():
+ if self.optionstore.is_reserved_name(key):
raise OptionException('Option name %s is reserved.' % opt_name)
opt_type = kwargs['type']
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index d83a312..e88710d 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -8,6 +8,7 @@ import argparse
from .mesonlib import (
HoldableObject,
OptionKey,
+ OptionType,
default_prefix,
default_datadir,
default_includedir,
@@ -536,3 +537,10 @@ class OptionStore:
def get(self, *args, **kwargs) -> UserOption:
return self.d.get(*args, **kwargs)
+
+ def is_project_option(self, key: OptionKey) -> bool:
+ """Convenience method to check if this is a project option."""
+ return key.type is OptionType.PROJECT
+
+ def is_reserved_name(self, key: OptionKey) -> bool:
+ return not self.is_project_option(key)
diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py
index 6aee268..4582336 100644
--- a/mesonbuild/utils/universal.py
+++ b/mesonbuild/utils/universal.py
@@ -2406,8 +2406,8 @@ class OptionKey:
"""Convenience method to check if this is a builtin option."""
return self.type is OptionType.COMPILER
- def is_project(self) -> bool:
- """Convenience method to check if this is a project option."""
+ def is_project_hack_for_optionsview(self) -> bool:
+ """This method will be removed once we can delete OptionsView."""
return self.type is OptionType.PROJECT
def is_base(self) -> bool:
diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py
index fe598a7..4ac4b7a 100644
--- a/unittests/platformagnostictests.py
+++ b/unittests/platformagnostictests.py
@@ -18,6 +18,7 @@ from .helpers import is_ci
from mesonbuild.mesonlib import EnvironmentVariables, ExecutableSerialisation, MesonException, is_linux, python_command
from mesonbuild.mformat import match_path
from mesonbuild.optinterpreter import OptionInterpreter, OptionException
+from mesonbuild.options import OptionStore
from run_tests import Backend
@skipIf(is_ci() and not is_linux(), "Run only on fast platforms")
@@ -35,7 +36,8 @@ class PlatformAgnosticTests(BasePlatformTests):
self.init(testdir, workdir=testdir)
def test_invalid_option_names(self):
- interp = OptionInterpreter('')
+ store = OptionStore()
+ interp = OptionInterpreter(store, '')
def write_file(code: str):
with tempfile.NamedTemporaryFile('w', dir=self.builddir, encoding='utf-8', delete=False) as f:
@@ -68,7 +70,8 @@ class PlatformAgnosticTests(BasePlatformTests):
def test_option_validation(self):
"""Test cases that are not catch by the optinterpreter itself."""
- interp = OptionInterpreter('')
+ store = OptionStore()
+ interp = OptionInterpreter(store, '')
def write_file(code: str):
with tempfile.NamedTemporaryFile('w', dir=self.builddir, encoding='utf-8', delete=False) as f: