aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2023-03-01 12:21:56 -0800
committerDylan Baker <dylan@pnwbakers.com>2023-06-20 16:10:20 -0700
commitbe20e0809f3cee518a49f4c22ce3ca19319ebb33 (patch)
tree0ad524dad972c023255f49329b810e34d13631aa
parentd0cbda99a3932f2a66c40ba1e1cfe6332e6b68bb (diff)
downloadmeson-be20e0809f3cee518a49f4c22ce3ca19319ebb33.zip
meson-be20e0809f3cee518a49f4c22ce3ca19319ebb33.tar.gz
meson-be20e0809f3cee518a49f4c22ce3ca19319ebb33.tar.bz2
interpreter: allow default_options and override_options as a dict
-rw-r--r--docs/markdown/snippets/option_dict.md5
-rw-r--r--docs/yaml/functions/_build_target_base.yaml3
-rw-r--r--docs/yaml/functions/dependency.yaml3
-rw-r--r--docs/yaml/functions/project.yaml4
-rw-r--r--docs/yaml/functions/subproject.yaml12
-rw-r--r--mesonbuild/interpreter/dependencyfallbacks.py13
-rw-r--r--mesonbuild/interpreter/interpreter.py25
-rw-r--r--mesonbuild/interpreter/kwargs.py8
-rw-r--r--mesonbuild/interpreter/type_checking.py37
-rw-r--r--mesonbuild/modules/cmake.py2
10 files changed, 66 insertions, 46 deletions
diff --git a/docs/markdown/snippets/option_dict.md b/docs/markdown/snippets/option_dict.md
new file mode 100644
index 0000000..79cca5f
--- /dev/null
+++ b/docs/markdown/snippets/option_dict.md
@@ -0,0 +1,5 @@
+## default_options and override_options may now be dictionaries
+
+Instead of passing them as `default_options : ['key=value']`, they can now be
+passed as `default_options : {'key': 'value'}`, and the same for
+`override_options`.
diff --git a/docs/yaml/functions/_build_target_base.yaml b/docs/yaml/functions/_build_target_base.yaml
index abc5bf9..f863288 100644
--- a/docs/yaml/functions/_build_target_base.yaml
+++ b/docs/yaml/functions/_build_target_base.yaml
@@ -228,12 +228,13 @@ kwargs:
Set this to `[]`, or omit the keyword argument for the default behaviour.
override_options:
- type: list[str]
+ type: list[str] | dict[str]
since: 0.40.0
description: |
takes an array of strings in the same format as `project`'s `default_options`
overriding the values of these options
for this target only.
+ *(since 1.2.0)*: A dictionary may now be passed.
gnu_symbol_visibility:
type: str
diff --git a/docs/yaml/functions/dependency.yaml b/docs/yaml/functions/dependency.yaml
index 85255b9..6a628bd 100644
--- a/docs/yaml/functions/dependency.yaml
+++ b/docs/yaml/functions/dependency.yaml
@@ -78,7 +78,7 @@ varargs:
kwargs:
default_options:
- type: list[str]
+ type: list[str] | dict[str]
since: 0.38.0
description: |
An array of default option values
@@ -86,6 +86,7 @@ kwargs:
(like `default_options` in [[project]], they only have
effect when Meson is run for the first time, and command line
arguments override any default options in build files)
+ *(since 1.2.0)*: A dictionary may now be passed.
allow_fallback:
type: bool
diff --git a/docs/yaml/functions/project.yaml b/docs/yaml/functions/project.yaml
index 59595cd..6eb7adc 100644
--- a/docs/yaml/functions/project.yaml
+++ b/docs/yaml/functions/project.yaml
@@ -38,7 +38,7 @@ varargs:
kwargs:
default_options:
- type: list[str]
+ type: list[str] | dict[str]
description: |
Accepts strings in the form `key=value`
which have the same format as options to `meson configure`.
@@ -54,6 +54,8 @@ kwargs:
environment variable is not used. Consider using
[[add_project_arguments()]] instead.
+ *(since 1.2.0)*: A dictionary may now be passed.
+
version:
type: str | file
description: |
diff --git a/docs/yaml/functions/subproject.yaml b/docs/yaml/functions/subproject.yaml
index 14a778d..3017c20 100644
--- a/docs/yaml/functions/subproject.yaml
+++ b/docs/yaml/functions/subproject.yaml
@@ -12,8 +12,9 @@ description: |
that override those set in the subproject's `meson.options`
(like `default_options` in `project`, they only have effect when
Meson is run for the first time, and command line arguments override
- any default options in build files). *(since 0.54.0)*: `default_library`
- built-in option can also be overridden.
+ any default options in build files).
+ *(since 0.54.0)*: `default_library` built-in option can also be overridden.
+ *(since 1.2.0)*: A dictionary may be passed instead of array.
- `version`: works just like the same as in `dependency`.
It specifies what version the subproject should be, as an example `>=1.0.1`
- `required` *(since 0.48.0)*: By default, `required` is `true` and
@@ -41,15 +42,16 @@ posargs:
kwargs:
default_options:
- type: list[str]
+ type: list[str] | dict[str]
since: 0.37.0
description: |
An array of default option values
that override those set in the subproject's `meson.options`
(like `default_options` in [[project]], they only have effect when
Meson is run for the first time, and command line arguments override
- any default options in build files). *(since 0.54.0)*: `default_library`
- built-in option can also be overridden.
+ any default options in build files).
+ *(since 0.54.0)*: `default_library` built-in option can also be overridden.
+ *(since 1.2.0)*: A dictionary may now be passed.
version:
type: str
diff --git a/mesonbuild/interpreter/dependencyfallbacks.py b/mesonbuild/interpreter/dependencyfallbacks.py
index 79ca884..7ef1527 100644
--- a/mesonbuild/interpreter/dependencyfallbacks.py
+++ b/mesonbuild/interpreter/dependencyfallbacks.py
@@ -19,7 +19,7 @@ if T.TYPE_CHECKING:
class DependencyFallbacksHolder(MesonInterpreterObject):
def __init__(self, interpreter: 'Interpreter', names: T.List[str], allow_fallback: T.Optional[bool] = None,
- default_options: T.Optional[T.List[str]] = None) -> None:
+ default_options: T.Optional[T.Dict[OptionKey, str]] = None) -> None:
super().__init__(subproject=interpreter.subproject)
self.interpreter = interpreter
self.subproject = interpreter.subproject
@@ -30,7 +30,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject):
self.allow_fallback = allow_fallback
self.subproject_name: T.Optional[str] = None
self.subproject_varname: T.Optional[str] = None
- self.subproject_kwargs = {'default_options': default_options or []}
+ self.subproject_kwargs = {'default_options': default_options or {}}
self.names: T.List[str] = []
self.forcefallback: bool = False
self.nofallback: bool = False
@@ -114,12 +114,11 @@ class DependencyFallbacksHolder(MesonInterpreterObject):
# dependency('foo', static: true) should implicitly add
# default_options: ['default_library=static']
static = kwargs.get('static')
- default_options = stringlistify(func_kwargs.get('default_options', []))
- if static is not None and not any('default_library' in i for i in default_options):
+ default_options = func_kwargs.get('default_options', {})
+ if static is not None and 'default_library' not in default_options:
default_library = 'static' if static else 'shared'
- opt = f'default_library={default_library}'
- mlog.log(f'Building fallback subproject with {opt}')
- default_options.append(opt)
+ mlog.log(f'Building fallback subproject with default_library={default_library}')
+ default_options[OptionKey('default_library')] = default_library
func_kwargs['default_options'] = default_options
# Configure the subproject
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 5908bec..c5e25d3 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -80,6 +80,7 @@ from .type_checking import (
INSTALL_TAG_KW,
LANGUAGE_KW,
NATIVE_KW,
+ OVERRIDE_OPTIONS_KW,
PRESERVE_PATH_KW,
REQUIRED_KW,
SOURCES_KW,
@@ -890,7 +891,7 @@ class Interpreter(InterpreterBase, HoldableObject):
mlog.log('Subproject', mlog.bold(subp_name), ':', 'skipped: feature', mlog.bold(feature), 'disabled')
return self.disabled_subproject(subp_name, disabled_feature=feature)
- default_options = coredata.create_options_dict(kwargs['default_options'], subp_name)
+ default_options = {k.evolve(subproject=subp_name): v for k, v in kwargs['default_options'].items()}
if subp_name == '':
raise InterpreterException('Subproject name must not be empty.')
@@ -1196,13 +1197,17 @@ class Interpreter(InterpreterBase, HoldableObject):
self.coredata.update_project_options(oi.options)
self.add_build_def_file(option_file)
+ if self.subproject:
+ self.project_default_options = {k.evolve(subproject=self.subproject): v
+ for k, v in kwargs['default_options'].items()}
+ else:
+ self.project_default_options = kwargs['default_options']
+
# Do not set default_options on reconfigure otherwise it would override
# values previously set from command line. That means that changing
# default_options in a project will trigger a reconfigure but won't
# have any effect.
- self.project_default_options = coredata.create_options_dict(
- kwargs['default_options'], self.subproject)
-
+ #
# If this is the first invocation we always need to initialize
# builtins, if this is a subproject that is new in a re-invocation we
# need to initialize builtins for that
@@ -1694,7 +1699,7 @@ class Interpreter(InterpreterBase, HoldableObject):
mlog.bold(' '.join(args)))
sp_kwargs: kwtypes.DoSubproject = {
'required': required,
- 'default_options': [],
+ 'default_options': {},
'version': [],
'cmake_options': [],
'options': None,
@@ -1739,10 +1744,10 @@ class Interpreter(InterpreterBase, HoldableObject):
@FeatureNewKwargs('dependency', '0.50.0', ['not_found_message', 'cmake_module_path', 'cmake_args'])
@FeatureNewKwargs('dependency', '0.49.0', ['disabler'])
@FeatureNewKwargs('dependency', '0.40.0', ['method'])
- @FeatureNewKwargs('dependency', '0.38.0', ['default_options'])
@disablerIfNotFound
@permittedKwargs(permitted_dependency_kwargs)
@typed_pos_args('dependency', varargs=str, min_varargs=1)
+ @typed_kwargs('dependency', DEFAULT_OPTIONS.evolve(since='0.38.0'), allow_unknown=True)
def func_dependency(self, node: mparser.BaseNode, args: T.Tuple[T.List[str]], kwargs) -> Dependency:
# Replace '' by empty list of names
names = [n for n in args[0] if n]
@@ -1794,6 +1799,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@FeatureDeprecatedKwargs('executable', '0.56.0', ['gui_app'], extra_message="Use 'win_subsystem' instead.")
@permittedKwargs(build.known_exe_kwargs)
@typed_pos_args('executable', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('executable', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_executable(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.Executable:
@@ -1801,6 +1807,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@permittedKwargs(build.known_stlib_kwargs)
@typed_pos_args('static_library', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('static_library', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_static_lib(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.StaticLibrary:
@@ -1808,6 +1815,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@permittedKwargs(build.known_shlib_kwargs)
@typed_pos_args('shared_library', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('shared_library', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_shared_lib(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.SharedLibrary:
@@ -1817,6 +1825,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@permittedKwargs(known_library_kwargs)
@typed_pos_args('both_libraries', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('both_libraries', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_both_lib(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.BothLibraries:
@@ -1825,6 +1834,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@FeatureNew('shared_module', '0.37.0')
@permittedKwargs(build.known_shmod_kwargs)
@typed_pos_args('shared_module', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('shared_module', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_shared_module(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.SharedModule:
@@ -1832,6 +1842,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@permittedKwargs(known_library_kwargs)
@typed_pos_args('library', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('library', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_library(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> build.Executable:
@@ -1839,6 +1850,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@permittedKwargs(build.known_jar_kwargs)
@typed_pos_args('jar', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('jar', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_jar(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[T.Union[str, mesonlib.File, build.GeneratedTypes]]],
kwargs) -> build.Jar:
@@ -1847,6 +1859,7 @@ class Interpreter(InterpreterBase, HoldableObject):
@FeatureNewKwargs('build_target', '0.40.0', ['link_whole', 'override_options'])
@permittedKwargs(known_build_target_kwargs)
@typed_pos_args('build_target', str, varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList, build.StructuredSources, build.ExtractedObjects, build.BuildTarget))
+ @typed_kwargs('build_target', OVERRIDE_OPTIONS_KW, allow_unknown=True)
def func_build_target(self, node: mparser.BaseNode,
args: T.Tuple[str, T.List[BuildTargetSource]],
kwargs) -> T.Union[build.Executable, build.StaticLibrary, build.SharedLibrary,
diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py
index 3c1cb00..972b0f3 100644
--- a/mesonbuild/interpreter/kwargs.py
+++ b/mesonbuild/interpreter/kwargs.py
@@ -12,7 +12,7 @@ from typing_extensions import TypedDict, Literal, Protocol
from .. import build
from .. import coredata
from ..compilers import Compiler
-from ..mesonlib import MachineChoice, File, FileMode, FileOrString
+from ..mesonlib import MachineChoice, File, FileMode, FileOrString, OptionKey
from ..modules.cmake import CMakeSubprojectOptions
from ..programs import ExternalProgram
@@ -203,7 +203,7 @@ class Project(TypedDict):
version: T.Optional[FileOrString]
meson_version: T.Optional[str]
- default_options: T.List[str]
+ default_options: T.Dict[OptionKey, str]
license: T.List[str]
subproject_dir: str
@@ -298,13 +298,13 @@ class ConfigureFile(TypedDict):
class Subproject(ExtractRequired):
- default_options: T.List[str]
+ default_options: T.Dict[OptionKey, str]
version: T.List[str]
class DoSubproject(ExtractRequired):
- default_options: T.List[str]
+ default_options: T.Dict[OptionKey, str]
version: T.List[str]
cmake_options: T.List[str]
options: T.Optional[CMakeSubprojectOptions]
diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py
index 2d2b916..e950da0 100644
--- a/mesonbuild/interpreter/type_checking.py
+++ b/mesonbuild/interpreter/type_checking.py
@@ -281,21 +281,25 @@ COMMAND_KW: KwargInfo[T.List[T.Union[str, BuildTarget, CustomTarget, CustomTarge
default=[],
)
-def _override_options_convertor(raw: T.List[str]) -> T.Dict[OptionKey, str]:
- output: T.Dict[OptionKey, str] = {}
- for each in raw:
- k, v = split_equal_string(each)
- output[OptionKey.from_string(k)] = v
- return output
-
-
-OVERRIDE_OPTIONS_KW: KwargInfo[T.List[str]] = KwargInfo(
+def _override_options_convertor(raw: T.Union[str, T.List[str], T.Dict[str, str]]) -> T.Dict[OptionKey, str]:
+ if isinstance(raw, str):
+ raw = [raw]
+ if isinstance(raw, list):
+ output: T.Dict[OptionKey, str] = {}
+ for each in raw:
+ k, v = split_equal_string(each)
+ output[OptionKey.from_string(k)] = v
+ return output
+ return {OptionKey.from_string(k): v for k, v in raw.items()}
+
+
+OVERRIDE_OPTIONS_KW: KwargInfo[T.Union[str, T.Dict[str, str], T.List[str]]] = KwargInfo(
'override_options',
- ContainerTypeInfo(list, str),
- listify=True,
- default=[],
+ (str, ContainerTypeInfo(list, str), ContainerTypeInfo(dict, str)),
+ default={},
validator=_options_validator,
convertor=_override_options_convertor,
+ since_values={dict: '1.2.0'},
)
@@ -385,14 +389,7 @@ INCLUDE_DIRECTORIES: KwargInfo[T.List[T.Union[str, IncludeDirs]]] = KwargInfo(
default=[],
)
-# for cases like default_options and override_options
-DEFAULT_OPTIONS: KwargInfo[T.List[str]] = KwargInfo(
- 'default_options',
- ContainerTypeInfo(list, str),
- listify=True,
- default=[],
- validator=_options_validator,
-)
+DEFAULT_OPTIONS = OVERRIDE_OPTIONS_KW.evolve(name='default_options')
ENV_METHOD_KW = KwargInfo('method', str, default='set', since='0.62.0',
validator=in_set_validator({'set', 'prepend', 'append'}))
diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py
index 25129e6..d37c832 100644
--- a/mesonbuild/modules/cmake.py
+++ b/mesonbuild/modules/cmake.py
@@ -431,7 +431,7 @@ class CmakeModule(ExtensionModule):
'required': kwargs_['required'],
'options': kwargs_['options'],
'cmake_options': kwargs_['cmake_options'],
- 'default_options': [],
+ 'default_options': {},
'version': [],
}
subp = self.interpreter.do_subproject(dirname, 'cmake', kw)