summaryrefslogtreecommitdiff
path: root/mesonbuild/modules/rust.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/modules/rust.py')
-rw-r--r--mesonbuild/modules/rust.py125
1 files changed, 124 insertions, 1 deletions
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index 974d50ae6..137d64099 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -19,7 +19,8 @@ from ..compilers.rust import RustSystemDependency
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
+ OUTPUT_KW, INCLUDE_DIRECTORIES, SOURCES_VARARGS, NoneType, in_set_validator,
+ LIBRARY_KWS, _BASE_LANG_KW
)
from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noKwargs, noPosargs, permittedKwargs
from ..interpreter.interpreterobjects import Doctest
@@ -75,6 +76,11 @@ if T.TYPE_CHECKING:
class FuncDependency(TypedDict):
rust_abi: T.Optional[RUST_ABI]
+ class RustPackageLibrary(_kwargs.Library):
+ dependencies: T.List[T.Union[Dependency, ExternalLibrary]]
+ link_with: T.List[LibTypes]
+ link_whole: T.List[LibTypes]
+
RUST_TEST_KWS: T.List[KwargInfo] = [
KwargInfo(
'rust_args',
@@ -234,6 +240,8 @@ class RustPackage(RustCrate):
super().__init__(rust_ws, package)
self.methods.update({
'dependencies': self.dependencies_method,
+ 'library': self.library_method,
+ 'proc_macro': self.proc_macro_method,
})
@noPosargs
@@ -271,6 +279,121 @@ class RustPackage(RustCrate):
return dependencies
+ @staticmethod
+ def validate_pos_args(name: str, args: T.Tuple[
+ T.Optional[T.Union[str, StructuredSources]],
+ T.Optional[StructuredSources]]) -> T.Tuple[T.Optional[str], T.Optional[StructuredSources]]:
+ if isinstance(args[0], str):
+ return args[0], args[1]
+ if args[1] is not None:
+ raise MesonException(f"{name} only accepts one StructuredSources parameter")
+ return None, args[0]
+
+ def merge_kw_args(self, state: ModuleState, kwargs: RustPackageLibrary) -> None:
+ deps = kwargs['dependencies']
+ kwargs['dependencies'] = self.dependencies_method(state, [], {})
+ kwargs['dependencies'].extend(deps)
+
+ depmap = kwargs['rust_dependency_map']
+ kwargs['rust_dependency_map'] = self.rust_dependency_map_method(state, [], {})
+ kwargs['rust_dependency_map'].update(depmap)
+
+ rust_args = kwargs['rust_args']
+ kwargs['rust_args'] = self.rust_args_method(state, [], {})
+ kwargs['rust_args'].extend(rust_args)
+
+ kwargs['override_options'].setdefault('rust_std', self.package.manifest.package.edition)
+
+ def _library_method(self, state: ModuleState, args: T.Tuple[
+ T.Optional[T.Union[str, StructuredSources]],
+ T.Optional[StructuredSources]], kwargs: RustPackageLibrary,
+ static: bool, shared: bool) -> T.Union[BothLibraries, SharedLibrary, StaticLibrary]:
+ tgt_args = self.validate_pos_args('package.library', args)
+ if not self.package.manifest.lib:
+ raise MesonException("no [lib] section in Cargo package")
+
+ sources: T.Union[StructuredSources, str]
+ tgt_name, sources = tgt_args
+ if not tgt_name:
+ rust_abi: RUST_ABI
+ if kwargs['rust_crate_type'] is not None:
+ rust_abi = 'rust' if kwargs['rust_crate_type'] in {'lib', 'rlib', 'dylib', 'proc-macro'} else 'c'
+ else:
+ rust_abi = kwargs['rust_abi']
+ tgt_name = self.package.library_name(rust_abi)
+ if not sources:
+ sources = self.package.manifest.lib.path
+
+ lib_args: T.Tuple[str, SourcesVarargsType] = (tgt_name, [sources])
+ self.merge_kw_args(state, kwargs)
+
+ if static and shared:
+ return state._interpreter.build_both_libraries(state.current_node, lib_args, kwargs)
+ elif shared:
+ return state._interpreter.build_target(state.current_node, lib_args,
+ T.cast('_kwargs.SharedLibrary', kwargs),
+ SharedLibrary)
+ else:
+ return state._interpreter.build_target(state.current_node, lib_args,
+ T.cast('_kwargs.StaticLibrary', kwargs),
+ StaticLibrary)
+
+ def _proc_macro_method(self, state: 'ModuleState', args: T.Tuple[
+ T.Optional[T.Union[str, StructuredSources]],
+ T.Optional[StructuredSources]], kwargs: RustPackageLibrary) -> SharedLibrary:
+ kwargs['native'] = MachineChoice.BUILD
+ kwargs['rust_abi'] = None
+ kwargs['rust_crate_type'] = 'proc-macro'
+ kwargs['rust_args'] = kwargs['rust_args'] + ['--extern', 'proc_macro']
+ result = self._library_method(state, args, kwargs, shared=True, static=False)
+ return T.cast('SharedLibrary', result)
+
+ @typed_pos_args('package.library', optargs=[(str, StructuredSources), StructuredSources])
+ @typed_kwargs(
+ 'package.library',
+ *LIBRARY_KWS,
+ DEPENDENCIES_KW,
+ LINK_WITH_KW,
+ LINK_WHOLE_KW,
+ _BASE_LANG_KW.evolve(name='rust_args'),
+ )
+ def library_method(self, state: ModuleState, args: T.Tuple[
+ T.Optional[T.Union[str, StructuredSources]],
+ T.Optional[StructuredSources]], kwargs: RustPackageLibrary) -> T.Union[BothLibraries, SharedLibrary, StaticLibrary]:
+ if not self.package.manifest.lib:
+ raise MesonException("no [lib] section in Cargo package")
+ if kwargs['rust_crate_type'] is not None:
+ static = kwargs['rust_crate_type'] in {'lib', 'rlib', 'staticlib'}
+ shared = kwargs['rust_crate_type'] in {'dylib', 'cdylib', 'proc-macro'}
+ else:
+ rust_abi = self.package.abi_resolve_default(kwargs['rust_abi'])
+ static = self.package.abi_has_static(rust_abi)
+ shared = self.package.abi_has_shared(rust_abi)
+ if rust_abi == 'proc-macro':
+ kwargs['rust_crate_type'] = 'proc-macro'
+ kwargs['rust_abi'] = None
+ else:
+ kwargs['rust_abi'] = rust_abi
+ return self._library_method(state, args, kwargs, static=static, shared=shared)
+
+ @typed_pos_args('package.proc_macro', optargs=[(str, StructuredSources), StructuredSources])
+ @typed_kwargs(
+ 'package.proc_macro',
+ *SHARED_LIB_KWS,
+ DEPENDENCIES_KW,
+ LINK_WITH_KW,
+ LINK_WHOLE_KW,
+ _BASE_LANG_KW.evolve(name='rust_args'),
+ )
+ def proc_macro_method(self, state: 'ModuleState', args: T.Tuple[
+ T.Optional[T.Union[str, StructuredSources]],
+ T.Optional[StructuredSources]], kwargs: RustPackageLibrary) -> SharedLibrary:
+ if not self.package.manifest.lib:
+ raise MesonException("no [lib] section in Cargo package")
+ if 'proc-macro' not in self.package.manifest.lib.crate_type:
+ raise MesonException("not a procedural macro crate")
+ return self._proc_macro_method(state, args, kwargs)
+
class RustSubproject(RustCrate):
"""Represents a Cargo subproject."""