aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2024-07-14 19:33:41 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2024-07-17 18:37:51 +0300
commit6e200222957063819a00e3bf767ce28b7489c31f (patch)
tree1c95bf865976905b83b4f7ae5c4a32edeb799f8b
parent61c742fae9ec74e81b3bb3caf815cf49992fb93c (diff)
downloadmeson-6e200222957063819a00e3bf767ce28b7489c31f.zip
meson-6e200222957063819a00e3bf767ce28b7489c31f.tar.gz
meson-6e200222957063819a00e3bf767ce28b7489c31f.tar.bz2
Remove module type from OptionKey.
-rw-r--r--mesonbuild/coredata.py6
-rw-r--r--mesonbuild/mconf.py7
-rw-r--r--mesonbuild/modules/__init__.py10
-rw-r--r--mesonbuild/modules/pkgconfig.py2
-rw-r--r--mesonbuild/modules/python.py10
-rw-r--r--mesonbuild/options.py78
-rw-r--r--unittests/datatests.py4
7 files changed, 72 insertions, 45 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 8c797cd..f9d2099 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -422,7 +422,11 @@ class CoreData:
value = opts_map.get_value(key.as_root())
else:
value = None
- opts_map.add_system_option(key, opt.init_option(key, value, options.default_prefix()))
+ if key.has_module_prefix():
+ modulename = key.get_module_prefix()
+ opts_map.add_module_option(modulename, key, opt.init_option(key, value, options.default_prefix()))
+ else:
+ opts_map.add_system_option(key, opt.init_option(key, value, options.default_prefix()))
def init_backend_options(self, backend_name: str) -> None:
if backend_name == 'ninja':
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index bd54251..6cb64e1 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -272,12 +272,13 @@ class Conf:
dir_options[k] = v
elif k in test_option_names:
test_options[k] = v
- elif k.module:
+ elif k.has_module_prefix():
# Ignore module options if we did not use that module during
# configuration.
- if self.build and k.module not in self.build.modules:
+ modname = k.get_module_prefix()
+ if self.build and modname not in self.build.modules:
continue
- module_options[k.module][k] = v
+ module_options[modname][k] = v
elif self.coredata.optstore.is_builtin_option(k):
core_options[k] = v
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 94d7e5d..3fe4956 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -132,15 +132,13 @@ class ModuleState:
self._interpreter.func_test(self.current_node, real_args, kwargs)
def get_option(self, name: str, subproject: str = '',
- machine: MachineChoice = MachineChoice.HOST,
- module: T.Optional[str] = None) -> T.Union[T.List[str], str, int, bool]:
- return self.environment.coredata.get_option(OptionKey(name, subproject, machine, module))
+ machine: MachineChoice = MachineChoice.HOST) -> T.Union[T.List[str], str, int, bool]:
+ return self.environment.coredata.get_option(OptionKey(name, subproject, machine))
def is_user_defined_option(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
- lang: T.Optional[str] = None,
- module: T.Optional[str] = None) -> bool:
- key = OptionKey(name, subproject, machine, module)
+ lang: T.Optional[str] = None) -> bool:
+ key = OptionKey(name, subproject, machine)
return key in self._interpreter.user_defined_options.cmd_line_options
def process_include_dirs(self, dirs: T.Iterable[T.Union[str, IncludeDirs]]) -> T.Iterable[IncludeDirs]:
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index d66c2a9..16c8c07 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -703,7 +703,7 @@ class PkgConfigModule(NewExtensionModule):
else:
pkgroot = os.path.join(_as_str(state.environment.coredata.get_option(OptionKey('libdir'))), 'pkgconfig')
pkgroot_name = os.path.join('{libdir}', 'pkgconfig')
- relocatable = state.get_option('relocatable', module='pkgconfig')
+ relocatable = state.get_option('pkgconfig.relocatable')
self._generate_pkgconfig_file(state, deps, subdirs, name, description, url,
version, pcfile, conflicts, variables,
unescaped_variables, False, dataonly,
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index dec77e2..1b7a056 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -83,13 +83,13 @@ class PythonExternalProgram(BasicPythonExternalProgram):
if not state:
# This happens only from run_project_tests.py
return rel_path
- value = T.cast('str', state.get_option(f'{key}dir', module='python'))
+ value = T.cast('str', state.get_option(f'python.{key}dir'))
if value:
- if state.is_user_defined_option('install_env', module='python'):
+ if state.is_user_defined_option('python.install_env'):
raise mesonlib.MesonException(f'python.{key}dir and python.install_env are mutually exclusive')
return value
- install_env = state.get_option('install_env', module='python')
+ install_env = state.get_option('python.install_env')
if install_env == 'auto':
install_env = 'venv' if self.info['is_venv'] else 'system'
@@ -169,7 +169,7 @@ class PythonInstallation(_ExternalProgramHolder['PythonExternalProgram']):
self.current_node)
limited_api_version = kwargs.pop('limited_api')
- allow_limited_api = self.interpreter.environment.coredata.get_option(OptionKey('allow_limited_api', module='python'))
+ allow_limited_api = self.interpreter.environment.coredata.get_option(OptionKey('python.allow_limited_api'))
if limited_api_version != '' and allow_limited_api:
target_suffix = self.limited_api_suffix
@@ -374,7 +374,7 @@ class PythonModule(ExtensionModule):
def _get_install_scripts(self) -> T.List[mesonlib.ExecutableSerialisation]:
backend = self.interpreter.backend
ret = []
- optlevel = self.interpreter.environment.coredata.get_option(OptionKey('bytecompile', module='python'))
+ optlevel = self.interpreter.environment.coredata.get_option(OptionKey('python.bytecompile'))
if optlevel == -1:
return ret
if not any(PythonExternalProgram.run_bytecompile.values()):
diff --git a/mesonbuild/options.py b/mesonbuild/options.py
index e50aa43..912cfa2 100644
--- a/mesonbuild/options.py
+++ b/mesonbuild/options.py
@@ -90,17 +90,15 @@ class OptionKey:
internally easier to reason about and produce.
"""
- __slots__ = ['name', 'subproject', 'machine', '_hash', 'module']
+ __slots__ = ['name', 'subproject', 'machine', '_hash']
name: str
subproject: str
machine: MachineChoice
_hash: int
- module: T.Optional[str]
def __init__(self, name: str, subproject: str = '',
- machine: MachineChoice = MachineChoice.HOST,
- module: T.Optional[str] = None):
+ machine: MachineChoice = MachineChoice.HOST):
# the _type option to the constructor is kinda private. We want to be
# able tos ave the state and avoid the lookup function when
# pickling/unpickling, but we need to be able to calculate it when
@@ -108,8 +106,7 @@ class OptionKey:
object.__setattr__(self, 'name', name)
object.__setattr__(self, 'subproject', subproject)
object.__setattr__(self, 'machine', machine)
- object.__setattr__(self, 'module', module)
- object.__setattr__(self, '_hash', hash((name, subproject, machine, module)))
+ object.__setattr__(self, '_hash', hash((name, subproject, machine)))
def __setattr__(self, key: str, value: T.Any) -> None:
raise AttributeError('OptionKey instances do not support mutation.')
@@ -119,7 +116,6 @@ class OptionKey:
'name': self.name,
'subproject': self.subproject,
'machine': self.machine,
- 'module': self.module,
}
def __setstate__(self, state: T.Dict[str, T.Any]) -> None:
@@ -137,7 +133,7 @@ class OptionKey:
return self._hash
def _to_tuple(self) -> T.Tuple[str, str, str, MachineChoice, str]:
- return (self.subproject, self.module or '', self.machine, self.name)
+ return (self.subproject, self.machine, self.name)
def __eq__(self, other: object) -> bool:
if isinstance(other, OptionKey):
@@ -153,14 +149,12 @@ class OptionKey:
out = self.name
if self.machine is MachineChoice.BUILD:
out = f'build.{out}'
- if self.module:
- out = f'{self.module}.{out}'
if self.subproject:
out = f'{self.subproject}:{out}'
return out
def __repr__(self) -> str:
- return f'OptionKey({self.name!r}, {self.subproject!r}, {self.machine!r}, {self.module!r})'
+ return f'OptionKey({self.name!r}, {self.subproject!r}, {self.machine!r})'
@classmethod
def from_string(cls, raw: str) -> 'OptionKey':
@@ -174,26 +168,24 @@ class OptionKey:
except ValueError:
subproject, raw2 = '', raw
- module = None
for_machine = MachineChoice.HOST
try:
prefix, raw3 = raw2.split('.')
if prefix == 'build':
for_machine = MachineChoice.BUILD
else:
- module = prefix
+ raw3 = raw2
except ValueError:
raw3 = raw2
opt = raw3
assert ':' not in opt
- assert '.' not in opt
+ assert opt.count('.') < 2
- return cls(opt, subproject, for_machine, module)
+ return cls(opt, subproject, for_machine)
def evolve(self, name: T.Optional[str] = None, subproject: T.Optional[str] = None,
- machine: T.Optional[MachineChoice] = None,
- module: T.Optional[str] = '') -> 'OptionKey':
+ machine: T.Optional[MachineChoice] = None) -> 'OptionKey':
"""Create a new copy of this key, but with altered members.
For example:
@@ -208,7 +200,6 @@ class OptionKey:
name if name is not None else self.name,
subproject if subproject is not None else self.subproject,
machine if machine is not None else self.machine,
- module if module != '' else self.module
)
def as_root(self) -> 'OptionKey':
@@ -228,6 +219,20 @@ class OptionKey:
import sys
sys.exit('FATAL internal error. This should not make it into an actual release. File a bug.')
+ def has_module_prefix(self) -> bool:
+ return '.' in self.name
+
+ def get_module_prefix(self) -> T.Optional[str]:
+ if self.has_module_prefix():
+ return self.name.split('.', 1)[0]
+ return None
+
+ def without_module_prefix(self) -> 'OptionKey':
+ if self.has_module_prefix():
+ newname = self.name.split('.', 1)[1]
+ return self.evolve(newname)
+ return self
+
class UserOption(T.Generic[_T], HoldableObject):
def __init__(self, name: str, description: str, choices: T.Optional[T.Union[str, T.List[_T]]],
@@ -633,19 +638,19 @@ BUILTIN_CORE_OPTIONS: T.Dict['OptionKey', 'BuiltinOption'] = OrderedDict([
(OptionKey('vsenv'), BuiltinOption(UserBooleanOption, 'Activate Visual Studio environment', False, readonly=True)),
# Pkgconfig module
- (OptionKey('relocatable', module='pkgconfig'),
+ (OptionKey('pkgconfig.relocatable'),
BuiltinOption(UserBooleanOption, 'Generate pkgconfig files as relocatable', False)),
# Python module
- (OptionKey('bytecompile', module='python'),
+ (OptionKey('python.bytecompile'),
BuiltinOption(UserIntegerOption, 'Whether to compile bytecode', (-1, 2, 0))),
- (OptionKey('install_env', module='python'),
+ (OptionKey('python.install_env'),
BuiltinOption(UserComboOption, 'Which python environment to install to', 'prefix', choices=['auto', 'prefix', 'system', 'venv'])),
- (OptionKey('platlibdir', module='python'),
+ (OptionKey('python.platlibdir'),
BuiltinOption(UserStringOption, 'Directory for site-specific, platform-specific files.', '')),
- (OptionKey('purelibdir', module='python'),
+ (OptionKey('python.purelibdir'),
BuiltinOption(UserStringOption, 'Directory for site-specific, non-platform-specific files.', '')),
- (OptionKey('allow_limited_api', module='python'),
+ (OptionKey('python.allow_limited_api'),
BuiltinOption(UserBooleanOption, 'Whether to allow use of the Python Limited API', True)),
])
@@ -662,8 +667,8 @@ BUILTIN_DIR_NOPREFIX_OPTIONS: T.Dict[OptionKey, T.Dict[str, str]] = {
OptionKey('sysconfdir'): {'/usr': '/etc'},
OptionKey('localstatedir'): {'/usr': '/var', '/usr/local': '/var/local'},
OptionKey('sharedstatedir'): {'/usr': '/var/lib', '/usr/local': '/var/local/lib'},
- OptionKey('platlibdir', module='python'): {},
- OptionKey('purelibdir', module='python'): {},
+ OptionKey('python.platlibdir'): {},
+ OptionKey('python.purelibdir'): {},
}
class OptionStore:
@@ -671,6 +676,7 @@ class OptionStore:
self.d: T.Dict['OptionKey', 'UserOption[T.Any]'] = {}
self.project_options = set()
self.all_languages = set()
+ self.module_options = set()
from .compilers import all_languages
for lang in all_languages:
self.all_languages.add(lang)
@@ -691,6 +697,12 @@ class OptionStore:
def add_system_option(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]'):
key = self.ensure_key(key)
+ if '.' in key.name:
+ raise MesonException(f'Internal error: non-module option has a period in its name {key.name}.')
+ self.add_system_option_internal(key, valobj)
+
+ def add_system_option_internal(self, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]'):
+ key = self.ensure_key(key)
assert isinstance(valobj, UserOption)
self.d[key] = valobj
@@ -705,6 +717,15 @@ class OptionStore:
self.d[key] = valobj
self.project_options.add(key)
+ def add_module_option(self, modulename: str, key: T.Union[OptionKey, str], valobj: 'UserOption[T.Any]'):
+ key = self.ensure_key(key)
+ if key.name.startswith('build.'):
+ raise MesonException('FATAL internal error: somebody goofed option handling.')
+ if not key.name.startswith(modulename + '.'):
+ raise MesonException('Internal error: module option name {key.name} does not start with module prefix {modulename}.')
+ self.add_system_option_internal(key, valobj)
+ self.module_options.add(key)
+
def set_value(self, key: T.Union[OptionKey, str], new_value: 'T.Any') -> bool:
key = self.ensure_key(key)
return self.d[key].set_value(new_value)
@@ -764,7 +785,7 @@ class OptionStore:
def is_builtin_option(self, key: OptionKey) -> bool:
"""Convenience method to check if this is a builtin option."""
- return key.name in _BUILTIN_NAMES or key.module
+ return key.name in _BUILTIN_NAMES or self.is_module_option(key)
def is_base_option(self, key: OptionKey) -> bool:
"""Convenience method to check if this is a base option."""
@@ -784,3 +805,6 @@ class OptionStore:
if prefix in self.all_languages:
return True
return False
+
+ def is_module_option(self, key: OptionKey) -> bool:
+ return key in self.module_options
diff --git a/unittests/datatests.py b/unittests/datatests.py
index 73b937d..cb6542d 100644
--- a/unittests/datatests.py
+++ b/unittests/datatests.py
@@ -139,8 +139,8 @@ class DataTests(unittest.TestCase):
found_entries |= options
self.assertEqual(found_entries, {
- *(str(k.evolve(module=None)) for k in mesonbuild.options.BUILTIN_OPTIONS),
- *(str(k.evolve(module=None)) for k in mesonbuild.options.BUILTIN_OPTIONS_PER_MACHINE),
+ *(str(k.without_module_prefix()) for k in mesonbuild.options.BUILTIN_OPTIONS),
+ *(str(k.without_module_prefix()) for k in mesonbuild.options.BUILTIN_OPTIONS_PER_MACHINE),
})
# Check that `buildtype` table inside `Core options` matches how