aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter/dependencyfallbacks.py5
-rw-r--r--mesonbuild/interpreter/interpreter.py55
-rw-r--r--mesonbuild/interpreter/kwargs.py15
-rw-r--r--mesonbuild/modules/cmake.py13
-rw-r--r--test cases/failing/120 subproject version conflict/test.json2
-rw-r--r--test cases/failing/21 subver/test.json2
6 files changed, 67 insertions, 25 deletions
diff --git a/mesonbuild/interpreter/dependencyfallbacks.py b/mesonbuild/interpreter/dependencyfallbacks.py
index 8a0d351..e029854 100644
--- a/mesonbuild/interpreter/dependencyfallbacks.py
+++ b/mesonbuild/interpreter/dependencyfallbacks.py
@@ -4,7 +4,7 @@ from .. import mlog
from .. import dependencies
from .. import build
from ..wrap import WrapMode
-from ..mesonlib import OptionKey, extract_as_list, stringlistify, version_compare_many
+from ..mesonlib import OptionKey, extract_as_list, stringlistify, version_compare_many, listify
from ..dependencies import Dependency, DependencyException, NotFoundDependency
from ..interpreterbase import (MesonInterpreterObject, FeatureNew,
InterpreterException, InvalidArguments,
@@ -131,6 +131,9 @@ class DependencyFallbacksHolder(MesonInterpreterObject):
# Configure the subproject
subp_name = self.subproject_name
varname = self.subproject_varname
+ func_kwargs.setdefault('version', [])
+ if 'default_options' in kwargs and isinstance(kwargs['default_options'], str):
+ func_kwargs['default_options'] = listify(kwargs['default_options'])
self.interpreter.do_subproject(subp_name, 'meson', func_kwargs)
return self._get_subproject_dep(subp_name, varname, kwargs)
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 943f49e..1f778c8 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -799,8 +799,21 @@ external dependencies (including libraries) must go to "dependencies".''')
@FeatureNewKwargs('subproject', '0.38.0', ['default_options'])
@permittedKwargs({'version', 'default_options', 'required'})
@typed_pos_args('subproject', str)
- def func_subproject(self, nodes: mparser.BaseNode, args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> SubprojectHolder:
- return self.do_subproject(args[0], 'meson', kwargs)
+ @typed_kwargs(
+ 'subproject',
+ REQUIRED_KW,
+ DEFAULT_OPTIONS.evolve(since='0.38.0'),
+ KwargInfo('version', ContainerTypeInfo(list, str), default=[], listify=True),
+ )
+ def func_subproject(self, nodes: mparser.BaseNode, args: T.Tuple[str], kwargs_: kwargs.Subproject) -> SubprojectHolder:
+ kw: kwargs.DoSubproject = {
+ 'required': kwargs_['required'],
+ 'default_options': kwargs_['default_options'],
+ 'version': kwargs_['version'],
+ 'options': None,
+ 'cmake_options': [],
+ }
+ return self.do_subproject(args[0], 'meson', kw)
def disabled_subproject(self, subp_name: str, disabled_feature: T.Optional[str] = None,
exception: T.Optional[mesonlib.MesonException] = None) -> SubprojectHolder:
@@ -810,14 +823,13 @@ external dependencies (including libraries) must go to "dependencies".''')
self.coredata.initialized_subprojects.add(subp_name)
return sub
- def do_subproject(self, subp_name: str, method: Literal['meson', 'cmake'], kwargs) -> SubprojectHolder:
+ def do_subproject(self, subp_name: str, method: Literal['meson', 'cmake'], kwargs: kwargs.DoSubproject) -> SubprojectHolder:
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
if disabled:
mlog.log('Subproject', mlog.bold(subp_name), ':', 'skipped: feature', mlog.bold(feature), 'disabled')
return self.disabled_subproject(subp_name, disabled_feature=feature)
- default_options = mesonlib.stringlistify(kwargs.get('default_options', []))
- default_options = coredata.create_options_dict(default_options, subp_name)
+ default_options = coredata.create_options_dict(kwargs['default_options'], subp_name)
if subp_name == '':
raise InterpreterException('Subproject name must not be empty.')
@@ -838,7 +850,7 @@ external dependencies (including libraries) must go to "dependencies".''')
subproject = self.subprojects[subp_name]
if required and not subproject.found():
raise InterpreterException(f'Subproject "{subproject.subdir}" required but not found.')
- if 'version' in kwargs:
+ if kwargs['version']:
pv = self.build.subprojects[subp_name]
wanted = kwargs['version']
if pv == 'undefined' or not mesonlib.version_compare_many(pv, wanted)[0]:
@@ -885,7 +897,9 @@ external dependencies (including libraries) must go to "dependencies".''')
return self.disabled_subproject(subp_name, exception=e)
raise e
- def _do_subproject_meson(self, subp_name: str, subdir: str, default_options, kwargs,
+ def _do_subproject_meson(self, subp_name: str, subdir: str,
+ default_options: T.Dict[OptionKey, str],
+ kwargs: kwargs.DoSubproject,
ast: T.Optional[mparser.CodeBlockNode] = None,
build_def_files: T.Optional[T.List[str]] = None,
is_translated: bool = False) -> SubprojectHolder:
@@ -914,7 +928,7 @@ external dependencies (including libraries) must go to "dependencies".''')
mlog.log()
- if 'version' in kwargs:
+ if kwargs['version']:
pv = subi.project_version
wanted = kwargs['version']
if pv == 'undefined' or not mesonlib.version_compare_many(pv, wanted)[0]:
@@ -932,19 +946,16 @@ external dependencies (including libraries) must go to "dependencies".''')
self.coredata.initialized_subprojects.add(subp_name)
return self.subprojects[subp_name]
- def _do_subproject_cmake(self, subp_name: str, subdir: str, subdir_abs: str, default_options, kwargs):
+ def _do_subproject_cmake(self, subp_name: str, subdir: str, subdir_abs: str,
+ default_options: T.Dict[OptionKey, str],
+ kwargs: kwargs.DoSubproject) -> SubprojectHolder:
with mlog.nested(subp_name):
new_build = self.build.copy()
prefix = self.coredata.options[OptionKey('prefix')].value
from ..modules.cmake import CMakeSubprojectOptions
- options = kwargs.get('options', CMakeSubprojectOptions())
- if not isinstance(options, CMakeSubprojectOptions):
- raise InterpreterException('"options" kwarg must be CMakeSubprojectOptions'
- ' object (created by cmake.subproject_options())')
-
- cmake_options = mesonlib.stringlistify(kwargs.get('cmake_options', []))
- cmake_options += options.cmake_options
+ options = kwargs['options'] or CMakeSubprojectOptions()
+ cmake_options = kwargs['cmake_options'] + options.cmake_options
cm_int = CMakeInterpreter(new_build, Path(subdir), Path(subdir_abs), Path(prefix), new_build.environment, self.backend)
cm_int.initialise(cmake_options)
cm_int.analyse()
@@ -1501,7 +1512,7 @@ external dependencies (including libraries) must go to "dependencies".''')
progobj.was_returned_by_find_program = True
return progobj
- def program_lookup(self, args, for_machine, required, search_dirs, extra_info):
+ def program_lookup(self, args, for_machine, required: bool, search_dirs, extra_info):
progobj = self.program_from_overrides(args, extra_info)
if progobj:
return progobj
@@ -1524,10 +1535,16 @@ external dependencies (including libraries) must go to "dependencies".''')
return progobj
- def find_program_fallback(self, fallback, args, required, extra_info):
+ def find_program_fallback(self, fallback: str, args, required: bool, extra_info):
mlog.log('Fallback to subproject', mlog.bold(fallback), 'which provides program',
mlog.bold(' '.join(args)))
- sp_kwargs = {'required': required}
+ sp_kwargs: kwargs.DoSubproject = {
+ 'required': required,
+ 'default_options': [],
+ 'version': [],
+ 'cmake_options': [],
+ 'options': None,
+ }
self.do_subproject(fallback, 'meson', sp_kwargs)
return self.program_from_overrides(args, extra_info)
diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py
index 981f50d..f2460ac 100644
--- a/mesonbuild/interpreter/kwargs.py
+++ b/mesonbuild/interpreter/kwargs.py
@@ -12,6 +12,7 @@ from .. import build
from .. import coredata
from ..compilers import Compiler
from ..mesonlib import MachineChoice, File, FileMode, FileOrString, OptionKey
+from ..modules.cmake import CMakeSubprojectOptions
from ..programs import ExternalProgram
@@ -293,3 +294,17 @@ class ConfigureFile(TypedDict):
command: T.Optional[T.List[T.Union[build.Executable, ExternalProgram, Compiler, File, str]]]
input: T.List[FileOrString]
configuration: T.Optional[T.Union[T.Dict[str, T.Union[str, int, bool]], build.ConfigurationData]]
+
+
+class Subproject(ExtractRequired):
+
+ default_options: T.List[str]
+ version: T.List[str]
+
+
+class DoSubproject(ExtractRequired):
+
+ default_options: T.List[str]
+ version: T.List[str]
+ cmake_options: T.List[str]
+ options: T.Optional[CMakeSubprojectOptions]
diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py
index f996087..a58ad54 100644
--- a/mesonbuild/modules/cmake.py
+++ b/mesonbuild/modules/cmake.py
@@ -425,11 +425,18 @@ class CmakeModule(ExtensionModule):
deprecated_message='Use options instead',
),
)
- def subproject(self, state: ModuleState, args: T.Tuple[str], kwargs: Subproject) -> T.Union[SubprojectHolder, CMakeSubproject]:
- if kwargs['cmake_options'] and kwargs['options'] is not None:
+ def subproject(self, state: ModuleState, args: T.Tuple[str], kwargs_: Subproject) -> T.Union[SubprojectHolder, CMakeSubproject]:
+ if kwargs_['cmake_options'] and kwargs_['options'] is not None:
raise InterpreterException('"options" cannot be used together with "cmake_options"')
dirname = args[0]
- subp = self.interpreter.do_subproject(dirname, 'cmake', kwargs)
+ kw: kwargs.DoSubproject = {
+ 'required': kwargs_['required'],
+ 'options': kwargs_['options'],
+ 'cmake_options': kwargs_['cmake_options'],
+ 'default_options': [],
+ 'version': [],
+ }
+ subp = self.interpreter.do_subproject(dirname, 'cmake', kw)
if not subp.found():
return subp
return CMakeSubproject(subp)
diff --git a/test cases/failing/120 subproject version conflict/test.json b/test cases/failing/120 subproject version conflict/test.json
index 5d445e5..7807d68 100644
--- a/test cases/failing/120 subproject version conflict/test.json
+++ b/test cases/failing/120 subproject version conflict/test.json
@@ -1,7 +1,7 @@
{
"stdout": [
{
- "line": "test cases/failing/120 subproject version conflict/meson.build:4:0: ERROR: Subproject B version is 100 but 1 required."
+ "line": "test cases/failing/120 subproject version conflict/meson.build:4:0: ERROR: Subproject B version is 100 but ['1'] required."
}
]
}
diff --git a/test cases/failing/21 subver/test.json b/test cases/failing/21 subver/test.json
index f8cfd3a..a197b36 100644
--- a/test cases/failing/21 subver/test.json
+++ b/test cases/failing/21 subver/test.json
@@ -1,7 +1,7 @@
{
"stdout": [
{
- "line": "test cases/failing/21 subver/meson.build:3:0: ERROR: Subproject foo version is 1.0.0 but >1.0.0 required."
+ "line": "test cases/failing/21 subver/meson.build:3:0: ERROR: Subproject foo version is 1.0.0 but ['>1.0.0'] required."
}
]
}