summaryrefslogtreecommitdiff
path: root/mesonbuild/modules
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/modules')
-rw-r--r--mesonbuild/modules/__init__.py10
-rw-r--r--mesonbuild/modules/rust.py59
2 files changed, 66 insertions, 3 deletions
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 3ff9368d9..ed8deff06 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -7,7 +7,7 @@ from __future__ import annotations
import dataclasses
import typing as T
-from .. import build, mesonlib
+from .. import build, dependencies, mesonlib
from ..options import OptionKey
from ..build import IncludeDirs
from ..interpreterbase.decorators import noKwargs, noPosargs
@@ -46,6 +46,7 @@ class ModuleState:
# The backend object is under-used right now, but we will need it:
# https://github.com/mesonbuild/meson/issues/1419
self.backend = interpreter.backend
+ self.dependency_overrides = interpreter.build.dependency_overrides
self.targets = interpreter.build.targets
self.data = interpreter.build.data
self.headers = interpreter.build.get_headers()
@@ -108,6 +109,13 @@ class ModuleState:
# Normal program lookup
return self.find_program(name, required=required, wanted=wanted)
+ def overridden_dependency(self, depname: str, for_machine: MachineChoice = MachineChoice.HOST) -> Dependency:
+ identifier = dependencies.get_dep_identifier(depname, {})
+ try:
+ return self.dependency_overrides[for_machine][identifier].dep
+ except KeyError:
+ raise mesonlib.MesonException(f'dependency "{depname}" was not overridden for the {for_machine}')
+
def dependency(self, depname: str, native: bool = False, required: bool = True,
wanted: T.Optional[str] = None) -> 'Dependency':
kwargs: T.Dict[str, object] = {'native': native, 'required': required}
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index 39e1d9ce1..86e3ce426 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -15,11 +15,12 @@ from .. import mesonlib, mlog
from ..build import (BothLibraries, BuildTarget, CustomTargetIndex, Executable, ExtractedObjects, GeneratedList,
CustomTarget, InvalidArguments, Jar, StructuredSources, SharedLibrary, StaticLibrary)
from ..compilers.compilers import are_asserts_disabled_for_subproject, lang_suffixes
+from ..dependencies import Dependency
from ..interpreter.type_checking import (
DEPENDENCIES_KW, LINK_WITH_KW, LINK_WHOLE_KW, SHARED_LIB_KWS, TEST_KWS, TEST_KWS_NO_ARGS,
OUTPUT_KW, INCLUDE_DIRECTORIES, SOURCES_VARARGS, NoneType, in_set_validator
)
-from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noPosargs, permittedKwargs
+from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noKwargs, noPosargs, permittedKwargs
from ..interpreter.interpreterobjects import Doctest
from ..mesonlib import File, MachineChoice, MesonException, PerMachine
from ..programs import ExternalProgram, NonExistingExternalProgram
@@ -28,12 +29,14 @@ if T.TYPE_CHECKING:
from . import ModuleState
from ..build import BuildTargetTypes, ExecutableKeywordArguments, IncludeDirs, LibTypes
from .. import cargo
+ from ..cargo.interpreter import RUST_ABI
from ..compilers.rust import RustCompiler
- from ..dependencies import Dependency, ExternalLibrary
+ from ..dependencies import ExternalLibrary
from ..interpreter import Interpreter
from ..interpreter import kwargs as _kwargs
from ..interpreter.interpreter import SourceInputs, SourceOutputs
from ..interpreter.interpreterobjects import Test
+ from ..interpreterbase import TYPE_kwargs
from ..programs import OverrideProgram
from ..interpreter.type_checking import SourcesVarargsType
@@ -68,6 +71,9 @@ if T.TYPE_CHECKING:
default_features: T.Optional[bool]
features: T.List[str]
+ class FuncDependency(TypedDict):
+ rust_abi: T.Optional[RUST_ABI]
+
RUST_TEST_KWS: T.List[KwargInfo] = [
KwargInfo(
'rust_args',
@@ -93,6 +99,55 @@ class RustWorkspace(ModuleObject):
super().__init__()
self.interpreter = interpreter
self.ws = ws
+ self.methods.update({
+ 'subproject': self.subproject_method,
+ })
+
+ def _do_subproject(self, pkg: cargo.PackageState) -> None:
+ kw: _kwargs.DoSubproject = {
+ 'required': True,
+ 'version': None,
+ 'options': None,
+ 'cmake_options': [],
+ 'default_options': {},
+ }
+ subp_name = pkg.get_subproject_name()
+ self.interpreter.do_subproject(subp_name, kw, force_method='cargo')
+
+ @typed_pos_args('workspace.subproject', str, optargs=[str])
+ @noKwargs
+ def subproject_method(self, state: ModuleState, args: T.Tuple[str, T.Optional[str]], kwargs: TYPE_kwargs) -> RustSubproject:
+ """Returns a package object for a subproject package."""
+ package_name = args[0]
+ pkg = self.interpreter.cargo.resolve_package(package_name, args[1] or '')
+ if pkg is None:
+ if args[1]:
+ raise MesonException(f'No version of cargo package "{package_name}" provides API {args[1]}')
+ else:
+ raise MesonException(f'Cargo package "{package_name}" not available')
+
+ self._do_subproject(pkg)
+ return RustSubproject(self, pkg)
+
+
+class RustSubproject(ModuleObject):
+ """Represents a Rust package within a workspace."""
+
+ def __init__(self, rust_ws: RustWorkspace, package: cargo.PackageState) -> None:
+ super().__init__()
+ self.rust_ws = rust_ws
+ self.package = package
+ self.methods.update({
+ 'dependency': self.dependency_method,
+ })
+
+ @noPosargs
+ @typed_kwargs('package.dependency',
+ KwargInfo('rust_abi', (str, NoneType), default=None, validator=in_set_validator({'rust', 'c', 'proc-macro'})))
+ def dependency_method(self, state: ModuleState, args: T.List, kwargs: FuncDependency) -> Dependency:
+ """Returns dependency for the package with the given ABI."""
+ depname = self.package.get_dependency_name(kwargs['rust_abi'])
+ return state.overridden_dependency(depname)
class RustModule(ExtensionModule):