|
19 | 19 | from ..dependencies import Dependency |
20 | 20 | from ..interpreter.type_checking import ( |
21 | 21 | DEPENDENCIES_KW, LINK_WITH_KW, LINK_WHOLE_KW, SHARED_LIB_KWS, TEST_KWS, TEST_KWS_NO_ARGS, |
22 | | - OUTPUT_KW, INCLUDE_DIRECTORIES, SOURCES_VARARGS, NoneType, in_set_validator |
| 22 | + OUTPUT_KW, INCLUDE_DIRECTORIES, SOURCES_VARARGS, NoneType, in_set_validator, |
| 23 | + LIBRARY_KWS, _BASE_LANG_KW |
23 | 24 | ) |
24 | 25 | from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noKwargs, noPosargs, permittedKwargs |
25 | 26 | from ..interpreter.interpreterobjects import Doctest |
@@ -75,6 +76,11 @@ class FuncWorkspace(TypedDict): |
75 | 76 | class FuncDependency(TypedDict): |
76 | 77 | rust_abi: T.Optional[RUST_ABI] |
77 | 78 |
|
| 79 | + class RustPackageLibrary(_kwargs.Library): |
| 80 | + dependencies: T.List[T.Union[Dependency, ExternalLibrary]] |
| 81 | + link_with: T.List[LibTypes] |
| 82 | + link_whole: T.List[LibTypes] |
| 83 | + |
78 | 84 | RUST_TEST_KWS: T.List[KwargInfo] = [ |
79 | 85 | KwargInfo( |
80 | 86 | 'rust_args', |
@@ -234,6 +240,8 @@ def __init__(self, rust_ws: RustWorkspace, package: cargo.PackageState) -> None: |
234 | 240 | super().__init__(rust_ws, package) |
235 | 241 | self.methods.update({ |
236 | 242 | 'dependencies': self.dependencies_method, |
| 243 | + 'library': self.library_method, |
| 244 | + 'proc_macro': self.proc_macro_method, |
237 | 245 | }) |
238 | 246 |
|
239 | 247 | @noPosargs |
@@ -271,6 +279,121 @@ def dependencies_method(self, state: ModuleState, args: T.List, kwargs: T.Dict[s |
271 | 279 |
|
272 | 280 | return dependencies |
273 | 281 |
|
| 282 | + @staticmethod |
| 283 | + def validate_pos_args(name: str, args: T.Tuple[ |
| 284 | + T.Optional[T.Union[str, StructuredSources]], |
| 285 | + T.Optional[StructuredSources]]) -> T.Tuple[T.Optional[str], T.Optional[StructuredSources]]: |
| 286 | + if isinstance(args[0], str): |
| 287 | + return args[0], args[1] |
| 288 | + if args[1] is not None: |
| 289 | + raise MesonException(f"{name} only accepts one StructuredSources parameter") |
| 290 | + return None, args[0] |
| 291 | + |
| 292 | + def merge_kw_args(self, state: ModuleState, kwargs: RustPackageLibrary) -> None: |
| 293 | + deps = kwargs['dependencies'] |
| 294 | + kwargs['dependencies'] = self.dependencies_method(state, [], {}) |
| 295 | + kwargs['dependencies'].extend(deps) |
| 296 | + |
| 297 | + depmap = kwargs['rust_dependency_map'] |
| 298 | + kwargs['rust_dependency_map'] = self.rust_dependency_map_method(state, [], {}) |
| 299 | + kwargs['rust_dependency_map'].update(depmap) |
| 300 | + |
| 301 | + rust_args = kwargs['rust_args'] |
| 302 | + kwargs['rust_args'] = self.rust_args_method(state, [], {}) |
| 303 | + kwargs['rust_args'].extend(rust_args) |
| 304 | + |
| 305 | + kwargs['override_options'].setdefault('rust_std', self.package.manifest.package.edition) |
| 306 | + |
| 307 | + def _library_method(self, state: ModuleState, args: T.Tuple[ |
| 308 | + T.Optional[T.Union[str, StructuredSources]], |
| 309 | + T.Optional[StructuredSources]], kwargs: RustPackageLibrary, |
| 310 | + static: bool, shared: bool) -> T.Union[BothLibraries, SharedLibrary, StaticLibrary]: |
| 311 | + tgt_args = self.validate_pos_args('package.library', args) |
| 312 | + if not self.package.manifest.lib: |
| 313 | + raise MesonException("no [lib] section in Cargo package") |
| 314 | + |
| 315 | + sources: T.Union[StructuredSources, str] |
| 316 | + tgt_name, sources = tgt_args |
| 317 | + if not tgt_name: |
| 318 | + rust_abi: RUST_ABI |
| 319 | + if kwargs['rust_crate_type'] is not None: |
| 320 | + rust_abi = 'rust' if kwargs['rust_crate_type'] in {'lib', 'rlib', 'dylib', 'proc-macro'} else 'c' |
| 321 | + else: |
| 322 | + rust_abi = kwargs['rust_abi'] |
| 323 | + tgt_name = self.package.library_name(rust_abi) |
| 324 | + if not sources: |
| 325 | + sources = self.package.manifest.lib.path |
| 326 | + |
| 327 | + lib_args: T.Tuple[str, SourcesVarargsType] = (tgt_name, [sources]) |
| 328 | + self.merge_kw_args(state, kwargs) |
| 329 | + |
| 330 | + if static and shared: |
| 331 | + return state._interpreter.build_both_libraries(state.current_node, lib_args, kwargs) |
| 332 | + elif shared: |
| 333 | + return state._interpreter.build_target(state.current_node, lib_args, |
| 334 | + T.cast('_kwargs.SharedLibrary', kwargs), |
| 335 | + SharedLibrary) |
| 336 | + else: |
| 337 | + return state._interpreter.build_target(state.current_node, lib_args, |
| 338 | + T.cast('_kwargs.StaticLibrary', kwargs), |
| 339 | + StaticLibrary) |
| 340 | + |
| 341 | + def _proc_macro_method(self, state: 'ModuleState', args: T.Tuple[ |
| 342 | + T.Optional[T.Union[str, StructuredSources]], |
| 343 | + T.Optional[StructuredSources]], kwargs: RustPackageLibrary) -> SharedLibrary: |
| 344 | + kwargs['native'] = MachineChoice.BUILD |
| 345 | + kwargs['rust_abi'] = None |
| 346 | + kwargs['rust_crate_type'] = 'proc-macro' |
| 347 | + kwargs['rust_args'] = kwargs['rust_args'] + ['--extern', 'proc_macro'] |
| 348 | + result = self._library_method(state, args, kwargs, shared=True, static=False) |
| 349 | + return T.cast('SharedLibrary', result) |
| 350 | + |
| 351 | + @typed_pos_args('package.library', optargs=[(str, StructuredSources), StructuredSources]) |
| 352 | + @typed_kwargs( |
| 353 | + 'package.library', |
| 354 | + *LIBRARY_KWS, |
| 355 | + DEPENDENCIES_KW, |
| 356 | + LINK_WITH_KW, |
| 357 | + LINK_WHOLE_KW, |
| 358 | + _BASE_LANG_KW.evolve(name='rust_args'), |
| 359 | + ) |
| 360 | + def library_method(self, state: ModuleState, args: T.Tuple[ |
| 361 | + T.Optional[T.Union[str, StructuredSources]], |
| 362 | + T.Optional[StructuredSources]], kwargs: RustPackageLibrary) -> T.Union[BothLibraries, SharedLibrary, StaticLibrary]: |
| 363 | + if not self.package.manifest.lib: |
| 364 | + raise MesonException("no [lib] section in Cargo package") |
| 365 | + if kwargs['rust_crate_type'] is not None: |
| 366 | + static = kwargs['rust_crate_type'] in {'lib', 'rlib', 'staticlib'} |
| 367 | + shared = kwargs['rust_crate_type'] in {'dylib', 'cdylib', 'proc-macro'} |
| 368 | + else: |
| 369 | + rust_abi = self.package.abi_resolve_default(kwargs['rust_abi']) |
| 370 | + static = self.package.abi_has_static(rust_abi) |
| 371 | + shared = self.package.abi_has_shared(rust_abi) |
| 372 | + if rust_abi == 'proc-macro': |
| 373 | + kwargs['rust_crate_type'] = 'proc-macro' |
| 374 | + kwargs['rust_abi'] = None |
| 375 | + else: |
| 376 | + kwargs['rust_abi'] = rust_abi |
| 377 | + return self._library_method(state, args, kwargs, static=static, shared=shared) |
| 378 | + |
| 379 | + @typed_pos_args('package.proc_macro', optargs=[(str, StructuredSources), StructuredSources]) |
| 380 | + @typed_kwargs( |
| 381 | + 'package.proc_macro', |
| 382 | + *SHARED_LIB_KWS, |
| 383 | + DEPENDENCIES_KW, |
| 384 | + LINK_WITH_KW, |
| 385 | + LINK_WHOLE_KW, |
| 386 | + _BASE_LANG_KW.evolve(name='rust_args'), |
| 387 | + ) |
| 388 | + def proc_macro_method(self, state: 'ModuleState', args: T.Tuple[ |
| 389 | + T.Optional[T.Union[str, StructuredSources]], |
| 390 | + T.Optional[StructuredSources]], kwargs: RustPackageLibrary) -> SharedLibrary: |
| 391 | + if not self.package.manifest.lib: |
| 392 | + raise MesonException("no [lib] section in Cargo package") |
| 393 | + if 'proc-macro' not in self.package.manifest.lib.crate_type: |
| 394 | + raise MesonException("not a procedural macro crate") |
| 395 | + return self._proc_macro_method(state, args, kwargs) |
| 396 | + |
274 | 397 |
|
275 | 398 | class RustSubproject(RustCrate): |
276 | 399 | """Represents a Cargo subproject.""" |
|
0 commit comments