summaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2025-09-23 09:45:47 -0700
committerDylan Baker <dylan@pnwbakers.com>2025-10-15 10:21:46 -0700
commit943638976e692f2d9b073bedd80481653cb3bd31 (patch)
treec80f9c035f4513bb2c7ca9f6819cfd9fa911e472 /mesonbuild
parent5d05b1e2695d9f87e4f2d5f22c25a7b28e9f5657 (diff)
downloadmeson-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.py9
-rw-r--r--mesonbuild/build.py59
-rw-r--r--mesonbuild/modules/rust.py17
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']