diff options
Diffstat (limited to 'mesonbuild/modules')
| -rw-r--r-- | mesonbuild/modules/rust.py | 125 |
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.""" |
