diff options
| author | Dylan Baker <dylan@pnwbakers.com> | 2025-09-23 09:45:47 -0700 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-10-15 10:21:46 -0700 |
| commit | 943638976e692f2d9b073bedd80481653cb3bd31 (patch) | |
| tree | c80f9c035f4513bb2c7ca9f6819cfd9fa911e472 /mesonbuild | |
| parent | 5d05b1e2695d9f87e4f2d5f22c25a7b28e9f5657 (diff) | |
| download | meson-943638976e692f2d9b073bedd80481653cb3bd31.tar.gz | |
build: Add a TypedDict for BuildTarget keyword arguments
This has the "processed" keyword arguments that the interpreter is
supposed to create for us, or that we expect internal users to build by
build.
This requires some hacking around in the rust module for the moment
because we suddenly have a type.
Diffstat (limited to 'mesonbuild')
| -rw-r--r-- | mesonbuild/ast/introspection.py | 9 | ||||
| -rw-r--r-- | mesonbuild/build.py | 59 | ||||
| -rw-r--r-- | mesonbuild/modules/rust.py | 17 |
3 files changed, 66 insertions, 19 deletions
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index b4cf8203c..360edae31 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -19,7 +19,7 @@ from ..mparser import BaseNode, ArrayNode, ElementaryNode, IdNode, FunctionNode, from .interpreter import AstInterpreter, IntrospectionBuildTarget, IntrospectionDependency if T.TYPE_CHECKING: - from ..build import BuildTarget + from ..build import BuildTarget, BuildTargetKeywordArguments from ..interpreterbase import TYPE_var from .visitor import AstVisitor @@ -243,9 +243,10 @@ class IntrospectionInterpreter(AstInterpreter): extraf_nodes = v # Make sure nothing can crash when creating the build class - kwargs_reduced = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs and k in {'install', 'build_by_default', 'build_always', 'name_prefix'}} - kwargs_reduced = {k: v.value if isinstance(v, ElementaryNode) else v for k, v in kwargs_reduced.items()} - kwargs_reduced = {k: v for k, v in kwargs_reduced.items() if not isinstance(v, (BaseNode, UnknownValue))} + _kwargs_reduced = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs and k in {'install', 'build_by_default', 'build_always', 'name_prefix'}} + _kwargs_reduced = {k: v.value if isinstance(v, ElementaryNode) else v for k, v in _kwargs_reduced.items()} + _kwargs_reduced = {k: v for k, v in _kwargs_reduced.items() if not isinstance(v, (BaseNode, UnknownValue))} + kwargs_reduced = T.cast('BuildTargetKeywordArguments', _kwargs_reduced) for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST objects: T.List[T.Any] = [] empty_sources: T.List[T.Any] = [] diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 643149c44..a8bb9cea1 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -63,6 +63,52 @@ if T.TYPE_CHECKING: import_dirs: T.List[IncludeDirs] versions: T.List[T.Union[str, int]] + class BuildTargetKeywordArguments(TypedDict, total=False): + + # The use of Sequence[str] here is intentional to get the generally + # undesirable behavior of Sequence[str] + + build_by_default: bool + build_rpath: str + c_pch: T.Sequence[str] + cpp_pch: T.Sequence[str] + d_debug: T.List[T.Union[str, int]] + d_import_dirs: T.List[IncludeDirs] + d_module_versions: T.List[T.Union[str, int]] + d_unittest: bool + dependencies: T.List[dependencies.Dependency] + extra_files: T.List[File] + gnu_symbol_visibility: Literal['default', 'internal', 'hidden', 'protected', 'inlineshidden', ''] + implicit_include_directories: bool + include_directories: T.List[IncludeDirs] + install: bool + install_dir: T.List[T.Union[str, Literal[False]]] + install_mode: FileMode + install_rpath: str + install_tag: T.List[str] + language_args: T.DefaultDict[str, T.List[str]] + link_args: T.List[str] + link_depends: T.List[T.Union[str, File, CustomTarget, CustomTargetIndex]] + link_language: str + link_whole: T.List[T.Union[StaticLibrary, CustomTarget, CustomTargetIndex]] + link_with: T.List[BuildTargetTypes] + name_prefix: T.Optional[str] + name_suffix: T.Optional[str] + native: MachineChoice + override_options: T.Dict[OptionKey, str] + resources: T.List[str] + swift_interoperability_mode: Literal['c', 'cpp'] + swift_module_name: str + rust_abi: Literal['c', 'rust'] + rust_crate_type: str # Literal? + rust_dependency_map: T.Dict[str, str] + vala_gir: str + vala_header: str + vala_vapi: str + win_subsystem: str + + _allow_no_sources: bool + DEFAULT_STATIC_LIBRARY_NAMES: T.Mapping[str, T.Tuple[str, str]] = { 'unix': ('lib', 'a'), 'windows': ('', 'lib'), @@ -77,6 +123,7 @@ DEFAULT_SHARED_LIBRARY_NAMES: T.Mapping[str, T.Tuple[str, str, str]] = { 'cygwin': ('cyg', 'dll', 'dll.a'), } + pch_kwargs = {'c_pch', 'cpp_pch'} lang_arg_kwargs = {f'{lang}_args' for lang in all_languages} @@ -699,7 +746,7 @@ class BuildTarget(Target): objects: T.List[ObjectTypes], environment: environment.Environment, compilers: T.Dict[str, 'Compiler'], - kwargs: T.Dict[str, T.Any]): + kwargs: BuildTargetKeywordArguments): super().__init__(name, subdir, subproject, True, for_machine, environment, install=kwargs.get('install', False)) self.all_compilers = compilers self.compilers: OrderedDict[str, Compiler] = OrderedDict() @@ -811,12 +858,12 @@ class BuildTarget(Target): else: mlog.warning('Installing target build for the build machine. This will fail in a cross build.') - def check_unknown_kwargs(self, kwargs): + def check_unknown_kwargs(self, kwargs: BuildTargetKeywordArguments) -> None: # Override this method in derived classes that have more # keywords. self.check_unknown_kwargs_int(kwargs, self.known_kwargs) - def check_unknown_kwargs_int(self, kwargs, known_kwargs): + def check_unknown_kwargs_int(self, kwargs: BuildTargetKeywordArguments, known_kwargs: T.Set[str]) -> None: unknowns = [] for k in kwargs: if k == 'language_args': @@ -1159,7 +1206,7 @@ class BuildTarget(Target): def get_custom_install_mode(self) -> T.Optional['FileMode']: return self.install_mode - def process_kwargs(self, kwargs): + def process_kwargs(self, kwargs: BuildTargetKeywordArguments) -> None: self.original_kwargs = kwargs if 'build_by_default' in kwargs: @@ -1299,7 +1346,7 @@ class BuildTarget(Target): if self.swift_module_name == '': self.swift_module_name = self.name - def _extract_pic_pie(self, kwargs: T.Dict[str, T.Any], arg: str, option: str) -> bool: + def _extract_pic_pie(self, kwargs: BuildTargetKeywordArguments, arg: str, option: str) -> bool: # Check if we have -fPIC, -fpic, -fPIE, or -fpie in cflags all_flags = self.extra_args['c'] + self.extra_args['cpp'] if '-f' + arg.lower() in all_flags or '-f' + arg.upper() in all_flags: @@ -1797,7 +1844,7 @@ class BuildTarget(Target): 'a file object, a Custom Target, or a Custom Target Index') self.process_link_depends(path) - def extract_targets_as_list(self, kwargs: T.Dict[str, T.Union[LibTypes, T.Sequence[LibTypes]]], key: T.Literal['link_with', 'link_whole']) -> T.List[LibTypes]: + def extract_targets_as_list(self, kwargs: BuildTargetKeywordArguments, key: T.Literal['link_with', 'link_whole']) -> T.List[LibTypes]: bl_type = self.environment.coredata.optstore.get_value_for(OptionKey('default_both_libraries')) if bl_type == 'auto': if isinstance(self, StaticLibrary): diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index 2c56a860e..c8b5d7482 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -26,7 +26,7 @@ from ..programs import ExternalProgram, NonExistingExternalProgram if T.TYPE_CHECKING: from . import ModuleState - from ..build import IncludeDirs, LibTypes + from ..build import BuildTargetTypes, IncludeDirs, LibTypes from ..compilers.rust import RustCompiler from ..dependencies import Dependency, ExternalLibrary from ..interpreter import Interpreter @@ -44,7 +44,7 @@ if T.TYPE_CHECKING: dependencies: T.List[T.Union[Dependency, ExternalLibrary]] is_parallel: bool link_with: T.List[LibTypes] - link_whole: T.List[LibTypes] + link_whole: T.List[T.Union[StaticLibrary, CustomTarget, CustomTargetIndex]] rust_args: T.List[str] FuncTest = FuncRustTest[_kwargs.TestArgs] @@ -179,16 +179,15 @@ class RustModule(ExtensionModule): tkwargs['protocol'] = 'rust' new_target_kwargs = base_target.original_kwargs.copy() - # Don't mutate the shallow copied list, instead replace it with a new - # one + del new_target_kwargs['rust_crate_type'] + for kw in ('pic', 'prelink', 'rust_abi', 'version', 'soversion', 'darwin_versions'): + if kw in new_target_kwargs: + del new_target_kwargs[kw] # type: ignore[misc] + new_target_kwargs['install'] = False new_target_kwargs['dependencies'] = new_target_kwargs.get('dependencies', []) + kwargs['dependencies'] - new_target_kwargs['link_with'] = new_target_kwargs.get('link_with', []) + kwargs['link_with'] + new_target_kwargs['link_with'] = new_target_kwargs.get('link_with', []) + T.cast('T.List[BuildTargetTypes]', kwargs['link_with']) new_target_kwargs['link_whole'] = new_target_kwargs.get('link_whole', []) + kwargs['link_whole'] - del new_target_kwargs['rust_crate_type'] - for kw in ['pic', 'prelink', 'rust_abi', 'version', 'soversion', 'darwin_versions']: - if kw in new_target_kwargs: - del new_target_kwargs[kw] lang_args = base_target.extra_args.copy() lang_args['rust'] = base_target.extra_args['rust'] + kwargs['rust_args'] + ['--test'] |
