|
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 | 22 | OUTPUT_KW, INCLUDE_DIRECTORIES, SOURCES_VARARGS, NoneType, in_set_validator, |
23 | | - LIBRARY_KWS, _BASE_LANG_KW |
| 23 | + EXECUTABLE_KWS, LIBRARY_KWS, _BASE_LANG_KW |
24 | 24 | ) |
25 | 25 | from ..interpreterbase import ContainerTypeInfo, InterpreterException, KwargInfo, typed_kwargs, typed_pos_args, noKwargs, noPosargs, permittedKwargs |
26 | 26 | from ..interpreter.interpreterobjects import Doctest |
@@ -76,6 +76,11 @@ class FuncWorkspace(TypedDict): |
76 | 76 | class FuncDependency(TypedDict): |
77 | 77 | rust_abi: T.Optional[RUST_ABI] |
78 | 78 |
|
| 79 | + class RustPackageExecutable(_kwargs.Executable): |
| 80 | + dependencies: T.List[T.Union[Dependency, ExternalLibrary]] |
| 81 | + link_with: T.List[LibTypes] |
| 82 | + link_whole: T.List[LibTypes] |
| 83 | + |
79 | 84 | class RustPackageLibrary(_kwargs.Library): |
80 | 85 | dependencies: T.List[T.Union[Dependency, ExternalLibrary]] |
81 | 86 | link_with: T.List[LibTypes] |
@@ -242,6 +247,7 @@ def __init__(self, rust_ws: RustWorkspace, package: cargo.PackageState) -> None: |
242 | 247 | 'dependencies': self.dependencies_method, |
243 | 248 | 'library': self.library_method, |
244 | 249 | 'proc_macro': self.proc_macro_method, |
| 250 | + 'executable': self.executable_method, |
245 | 251 | }) |
246 | 252 |
|
247 | 253 | @noPosargs |
@@ -289,7 +295,7 @@ def validate_pos_args(name: str, args: T.Tuple[ |
289 | 295 | raise MesonException(f"{name} only accepts one StructuredSources parameter") |
290 | 296 | return None, args[0] |
291 | 297 |
|
292 | | - def merge_kw_args(self, state: ModuleState, kwargs: RustPackageLibrary) -> None: |
| 298 | + def merge_kw_args(self, state: ModuleState, kwargs: T.Union[RustPackageExecutable, RustPackageLibrary]) -> None: |
293 | 299 | deps = kwargs['dependencies'] |
294 | 300 | kwargs['dependencies'] = self.dependencies_method(state, [], {}) |
295 | 301 | kwargs['dependencies'].extend(deps) |
@@ -394,6 +400,43 @@ def proc_macro_method(self, state: 'ModuleState', args: T.Tuple[ |
394 | 400 | raise MesonException("not a procedural macro crate") |
395 | 401 | return self._proc_macro_method(state, args, kwargs) |
396 | 402 |
|
| 403 | + @typed_pos_args('package.executable', optargs=[(str, StructuredSources), StructuredSources]) |
| 404 | + @typed_kwargs( |
| 405 | + 'package.executable', |
| 406 | + *EXECUTABLE_KWS, |
| 407 | + DEPENDENCIES_KW, |
| 408 | + LINK_WITH_KW, |
| 409 | + LINK_WHOLE_KW, |
| 410 | + _BASE_LANG_KW.evolve(name='rust_args'), |
| 411 | + ) |
| 412 | + def executable_method(self, state: 'ModuleState', args: T.Tuple[ |
| 413 | + T.Optional[T.Union[str, StructuredSources]], |
| 414 | + T.Optional[StructuredSources]], kwargs: RustPackageExecutable) -> Executable: |
| 415 | + """Builds executable targets from workspace bins.""" |
| 416 | + tgt_args = self.validate_pos_args('package.executable', args) |
| 417 | + if not self.package.manifest.bin: |
| 418 | + raise MesonException("no [[bin]] section in Cargo package") |
| 419 | + |
| 420 | + sources: T.Union[StructuredSources, str] |
| 421 | + tgt_name, sources = tgt_args |
| 422 | + # If there's more than one binary, the first argument must be specified |
| 423 | + # and must be one of the keys in pkg.bin |
| 424 | + if not tgt_name: |
| 425 | + if len(self.package.manifest.bin) > 1: |
| 426 | + raise MesonException("Package has multiple binaries, you must specify which one to build as the first argument") |
| 427 | + # Single binary, use it |
| 428 | + tgt_name = next(iter(self.package.manifest.bin.keys())) |
| 429 | + else: |
| 430 | + if tgt_name not in self.package.manifest.bin: |
| 431 | + raise MesonException(f"Binary '{tgt_name}' not found.") |
| 432 | + |
| 433 | + if not sources: |
| 434 | + sources = self.package.manifest.bin[tgt_name].path |
| 435 | + |
| 436 | + exe_args: T.Tuple[str, SourcesVarargsType] = (tgt_name, [sources]) |
| 437 | + self.merge_kw_args(state, kwargs) |
| 438 | + return state._interpreter.build_target(state.current_node, exe_args, kwargs, Executable) |
| 439 | + |
397 | 440 |
|
398 | 441 | class RustSubproject(RustCrate): |
399 | 442 | """Represents a Cargo subproject.""" |
|
0 commit comments