aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2023-04-24 22:42:09 -0400
committerXavier Claessens <xclaesse@gmail.com>2023-09-22 15:50:26 -0400
commit49e7e3b9ccba7f9b0a135188f892b37d4e52cafc (patch)
treec2d7cce36113bc1fae778b3a55823672ee28e99f /mesonbuild
parentc0da998afa7466d58c12d8a54baf09d09ae3225e (diff)
downloadmeson-49e7e3b9ccba7f9b0a135188f892b37d4e52cafc.zip
meson-49e7e3b9ccba7f9b0a135188f892b37d4e52cafc.tar.gz
meson-49e7e3b9ccba7f9b0a135188f892b37d4e52cafc.tar.bz2
Allow to fallback to cmake subproject
The method can be overridden by setting the `method` key in the wrap file and always defaults to 'meson'. cmake.subproject() is still needed in case specific cmake options need to be passed. This also makes it easier to extend to other methods in the future e.g. cargo.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/interpreter/dependencyfallbacks.py2
-rw-r--r--mesonbuild/interpreter/interpreter.py14
-rw-r--r--mesonbuild/modules/cmake.py2
-rwxr-xr-xmesonbuild/msubprojects.py6
-rw-r--r--mesonbuild/wrap/wrap.py40
5 files changed, 37 insertions, 27 deletions
diff --git a/mesonbuild/interpreter/dependencyfallbacks.py b/mesonbuild/interpreter/dependencyfallbacks.py
index 7ef1527..eca6a2c 100644
--- a/mesonbuild/interpreter/dependencyfallbacks.py
+++ b/mesonbuild/interpreter/dependencyfallbacks.py
@@ -127,7 +127,7 @@ class DependencyFallbacksHolder(MesonInterpreterObject):
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)
+ self.interpreter.do_subproject(subp_name, func_kwargs)
return self._get_subproject_dep(subp_name, varname, kwargs)
def _get_subproject(self, subp_name: str) -> T.Optional[SubprojectHolder]:
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index a5c8a5a..e0c17e6 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -116,8 +116,6 @@ import copy
if T.TYPE_CHECKING:
import argparse
- from typing_extensions import Literal
-
from . import kwargs as kwtypes
from ..backend.backends import Backend
from ..interpreterbase.baseobjects import InterpreterObject, TYPE_var, TYPE_kwargs
@@ -868,7 +866,7 @@ class Interpreter(InterpreterBase, HoldableObject):
'options': None,
'cmake_options': [],
}
- return self.do_subproject(args[0], 'meson', kw)
+ return self.do_subproject(args[0], kw)
def disabled_subproject(self, subp_name: str, disabled_feature: T.Optional[str] = None,
exception: T.Optional[Exception] = None) -> SubprojectHolder:
@@ -877,7 +875,7 @@ class Interpreter(InterpreterBase, HoldableObject):
self.subprojects[subp_name] = sub
return sub
- def do_subproject(self, subp_name: str, method: Literal['meson', 'cmake'], kwargs: kwtypes.DoSubproject) -> SubprojectHolder:
+ def do_subproject(self, subp_name: str, kwargs: kwtypes.DoSubproject, force_method: T.Optional[wrap.Method] = None) -> 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')
@@ -913,7 +911,7 @@ class Interpreter(InterpreterBase, HoldableObject):
r = self.environment.wrap_resolver
try:
- subdir = r.resolve(subp_name, method)
+ subdir, method = r.resolve(subp_name, force_method)
except wrap.WrapException as e:
if not required:
mlog.log(e)
@@ -1009,8 +1007,8 @@ class Interpreter(InterpreterBase, HoldableObject):
prefix = self.coredata.options[OptionKey('prefix')].value
from ..modules.cmake import CMakeSubprojectOptions
- options = kwargs['options'] or CMakeSubprojectOptions()
- cmake_options = kwargs['cmake_options'] + options.cmake_options
+ options = kwargs.get('options') or CMakeSubprojectOptions()
+ cmake_options = kwargs.get('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()
@@ -1734,7 +1732,7 @@ class Interpreter(InterpreterBase, HoldableObject):
'cmake_options': [],
'options': None,
}
- self.do_subproject(fallback, 'meson', sp_kwargs)
+ self.do_subproject(fallback, sp_kwargs)
return self.program_from_overrides(args, extra_info)
@typed_pos_args('find_program', varargs=(str, mesonlib.File), min_varargs=1)
diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py
index bec1b2a..ee4e844 100644
--- a/mesonbuild/modules/cmake.py
+++ b/mesonbuild/modules/cmake.py
@@ -435,7 +435,7 @@ class CmakeModule(ExtensionModule):
'default_options': {},
'version': [],
}
- subp = self.interpreter.do_subproject(dirname, 'cmake', kw)
+ subp = self.interpreter.do_subproject(dirname, kw, force_method='cmake')
if not subp.found():
return subp
return CMakeSubproject(subp)
diff --git a/mesonbuild/msubprojects.py b/mesonbuild/msubprojects.py
index 64a09b0..45b711d 100755
--- a/mesonbuild/msubprojects.py
+++ b/mesonbuild/msubprojects.py
@@ -189,7 +189,7 @@ class Runner:
# cached.
windows_proof_rmtree(self.repo_dir)
try:
- self.wrap_resolver.resolve(self.wrap.name, 'meson')
+ self.wrap_resolver.resolve(self.wrap.name)
self.log(' -> New version extracted')
return True
except WrapException as e:
@@ -292,7 +292,7 @@ class Runner:
# Delete existing directory and redownload
windows_proof_rmtree(self.repo_dir)
try:
- self.wrap_resolver.resolve(self.wrap.name, 'meson')
+ self.wrap_resolver.resolve(self.wrap.name)
self.update_git_done()
return True
except WrapException as e:
@@ -464,7 +464,7 @@ class Runner:
self.log(' -> Already downloaded')
return True
try:
- self.wrap_resolver.resolve(self.wrap.name, 'meson')
+ self.wrap_resolver.resolve(self.wrap.name)
self.log(' -> done')
except WrapException as e:
self.log(' ->', mlog.red(str(e)))
diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py
index c0f0f07..a1bf725 100644
--- a/mesonbuild/wrap/wrap.py
+++ b/mesonbuild/wrap/wrap.py
@@ -45,6 +45,9 @@ from .. import mesonlib
if T.TYPE_CHECKING:
import http.client
+ from typing_extensions import Literal
+
+ Method = Literal['meson', 'cmake']
try:
# Importing is just done to check if SSL exists, so all warnings
@@ -406,7 +409,7 @@ class Resolver:
return wrap_name
return None
- def resolve(self, packagename: str, method: str) -> str:
+ def resolve(self, packagename: str, force_method: T.Optional[Method] = None) -> T.Tuple[str, Method]:
self.packagename = packagename
self.directory = packagename
self.wrap = self.wraps.get(packagename)
@@ -443,17 +446,28 @@ class Resolver:
self.dirname = self.wrap.filename
rel_path = os.path.relpath(self.dirname, self.source_dir)
- if method == 'meson':
- buildfile = os.path.join(self.dirname, 'meson.build')
- elif method == 'cmake':
- buildfile = os.path.join(self.dirname, 'CMakeLists.txt')
- else:
- raise WrapException('Only the methods "meson" and "cmake" are supported')
+ # Map each supported method to a file that must exist at the root of source tree.
+ methods_map: T.Dict[Method, str] = {
+ 'meson': 'meson.build',
+ 'cmake': 'CMakeLists.txt',
+ }
+
+ # Check if this wrap forces a specific method, use meson otherwise.
+ method = T.cast('T.Optional[Method]', self.wrap.values.get('method', force_method))
+ if method and method not in methods_map:
+ allowed_methods = ', '.join(methods_map.keys())
+ raise WrapException(f'Wrap method {method!r} is not supported, must be one of: {allowed_methods}')
+ if force_method and method != force_method:
+ raise WrapException(f'Wrap method is {method!r} but we are trying to configure it with {force_method}')
+ method = method or 'meson'
+
+ def has_buildfile() -> bool:
+ return os.path.exists(os.path.join(self.dirname, methods_map[method]))
# The directory is there and has meson.build? Great, use it.
- if os.path.exists(buildfile):
+ if has_buildfile():
self.validate()
- return rel_path
+ return rel_path, method
# Check if the subproject is a git submodule
self.resolve_git_submodule()
@@ -491,16 +505,14 @@ class Resolver:
windows_proof_rmtree(self.dirname)
raise
- # A meson.build or CMakeLists.txt file is required in the directory
- if not os.path.exists(buildfile):
- raise WrapException(f'Subproject exists but has no {os.path.basename(buildfile)} file')
+ if not has_buildfile():
+ raise WrapException(f'Subproject exists but has no {methods_map[method]} file.')
# At this point, the subproject has been successfully resolved for the
# first time so save off the hash of the entire wrap file for future
# reference.
self.wrap.update_hash_cache(self.dirname)
-
- return rel_path
+ return rel_path, method
def check_can_download(self) -> None:
# Don't download subproject data based on wrap file if requested.