|
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 |
@@ -77,6 +77,11 @@ class FuncWorkspace(TypedDict): |
77 | 77 | class FuncDependency(TypedDict): |
78 | 78 | rust_abi: T.Optional[RUST_ABI] |
79 | 79 |
|
| 80 | + class RustPackageExecutable(_kwargs.Executable): |
| 81 | + dependencies: T.List[T.Union[Dependency, ExternalLibrary]] |
| 82 | + link_with: T.List[LibTypes] |
| 83 | + link_whole: T.List[LibTypes] |
| 84 | + |
80 | 85 | class RustPackageLibrary(_kwargs.Library): |
81 | 86 | dependencies: T.List[T.Union[Dependency, ExternalLibrary]] |
82 | 87 | link_with: T.List[LibTypes] |
@@ -243,6 +248,7 @@ def __init__(self, rust_ws: RustWorkspace, package: cargo.PackageState) -> None: |
243 | 248 | 'dependencies': self.dependencies_method, |
244 | 249 | 'library': self.library_method, |
245 | 250 | 'proc_macro': self.proc_macro_method, |
| 251 | + 'executable': self.executable_method, |
246 | 252 | }) |
247 | 253 |
|
248 | 254 | @noPosargs |
@@ -290,7 +296,7 @@ def validate_pos_args(name: str, args: T.Tuple[ |
290 | 296 | raise MesonException(f"{name} only accepts one StructuredSources parameter") |
291 | 297 | return None, args[0] |
292 | 298 |
|
293 | | - def merge_kw_args(self, state: ModuleState, kwargs: RustPackageLibrary) -> None: |
| 299 | + def merge_kw_args(self, state: ModuleState, kwargs: T.Union[RustPackageExecutable, RustPackageLibrary]) -> None: |
294 | 300 | deps = kwargs['dependencies'] |
295 | 301 | kwargs['dependencies'] = self.dependencies_method(state, [], {}) |
296 | 302 | kwargs['dependencies'].extend(deps) |
@@ -382,6 +388,42 @@ def proc_macro_method(self, state: 'ModuleState', args: T.Tuple[ |
382 | 388 | result = self._library_method(state, args, kwargs) |
383 | 389 | return T.cast('SharedLibrary', result) |
384 | 390 |
|
| 391 | + @typed_pos_args('package.executable', optargs=[(str, StructuredSources), StructuredSources]) |
| 392 | + @typed_kwargs( |
| 393 | + 'package.executable', |
| 394 | + *EXECUTABLE_KWS, |
| 395 | + DEPENDENCIES_KW, |
| 396 | + LINK_WITH_KW, |
| 397 | + LINK_WHOLE_KW, |
| 398 | + _BASE_LANG_KW.evolve(name='rust_args'), |
| 399 | + ) |
| 400 | + def executable_method(self, state: 'ModuleState', args: T.Tuple[ |
| 401 | + T.Optional[T.Union[str, StructuredSources]], |
| 402 | + T.Optional[StructuredSources]], kwargs: RustPackageExecutable) -> Executable: |
| 403 | + """Builds executable targets from workspace bins.""" |
| 404 | + tgt_args = self.validate_pos_args('package.executable', args) |
| 405 | + if not self.package.manifest.bin: |
| 406 | + raise MesonException("no [[bin]] section in Cargo package") |
| 407 | + |
| 408 | + # If there's more than one binary, the first argument must be specified |
| 409 | + # and must be one of the keys in pkg.bin |
| 410 | + tgt_name, sources = tgt_args |
| 411 | + if not tgt_name: |
| 412 | + if len(self.package.manifest.bin) > 1: |
| 413 | + raise MesonException("Package has multiple binaries, you must specify which one to build as the first argument") |
| 414 | + # Single binary, use it |
| 415 | + tgt_name = next(iter(self.package.manifest.bin.keys())) |
| 416 | + else: |
| 417 | + if tgt_name not in self.package.manifest.bin: |
| 418 | + raise MesonException(f"Binary '{tgt_name}' not found.") |
| 419 | + |
| 420 | + if not sources: |
| 421 | + sources = self.package.manifest.bin[tgt_name].path |
| 422 | + |
| 423 | + exe_args: T.Tuple[str, SourcesVarargsType] = (tgt_name, [sources]) |
| 424 | + self.merge_kw_args(state, kwargs) |
| 425 | + return state._interpreter.build_target(state.current_node, exe_args, kwargs, Executable) |
| 426 | + |
385 | 427 |
|
386 | 428 | class RustSubproject(RustCrate): |
387 | 429 | """Represents a Cargo subproject.""" |
|
0 commit comments