diff options
| author | Dylan Baker <dylan@pnwbakers.com> | 2025-12-05 09:15:06 -0800 |
|---|---|---|
| committer | Dylan Baker <dylan@pnwbakers.com> | 2025-12-17 14:04:17 -0800 |
| commit | a152da9206891caad17fd9271aff04073e811784 (patch) | |
| tree | dfbcf9fd6eb8be2906ec0f140691d48841c1e753 /mesonbuild | |
| parent | 7a1655acd29e5ba50a2951ad6c8db934fa7a6eb9 (diff) | |
| download | meson-a152da9206891caad17fd9271aff04073e811784.tar.gz | |
build|interpreter: use typed_kwargs for link_with
This replaces the long explanation of `external_library`s in the
`link_with` parameter to the simpler one used by declare_dependency.
Additionally, declare_dependency now checks that a target is linkable
when adding it. This just catches the problem before it goes down into
the build layer giving a better error message.
There is a bug in the declare_dependency annotations, in that they don't
mark Executable as acceptable. So I've fixed that.
Diffstat (limited to 'mesonbuild')
| -rw-r--r-- | mesonbuild/build.py | 18 | ||||
| -rw-r--r-- | mesonbuild/interpreter/kwargs.py | 3 | ||||
| -rw-r--r-- | mesonbuild/interpreter/type_checking.py | 13 |
3 files changed, 19 insertions, 15 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 50d83fa9f..f32010917 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -796,7 +796,7 @@ class BuildTarget(Target): self.external_deps: T.List[dependencies.Dependency] = [] self.include_dirs: T.List['IncludeDirs'] = [] self.link_language = kwargs.get('link_language') - self.link_targets: T.List[LibTypes] = [] + self.link_targets: T.List[BuildTargetTypes] = [] self.link_whole_targets: T.List[StaticTargetTypes] = [] self.depend_files: T.List[File] = [] self.link_depends: T.List[T.Union[File, BuildTargetTypes]] = [] @@ -1468,18 +1468,6 @@ class BuildTarget(Target): def link(self, targets: T.List[BuildTargetTypes]) -> None: for t in targets: - if not isinstance(t, (Target, CustomTargetIndex)): - if isinstance(t, dependencies.ExternalLibrary): - raise MesonException(textwrap.dedent('''\ - An external library was used in link_with keyword argument, which - is reserved for libraries built as part of this project. External - libraries must be passed using the dependencies keyword argument - instead, because they are conceptually "external dependencies", - just like those detected with the dependency() function. - ''')) - raise InvalidArguments(f'{t!r} is not a target.') - if not t.is_linkable_target(): - raise InvalidArguments(f"Link target '{t!s}' is not linkable.") if isinstance(self, StaticLibrary) and self.install and t.is_internal(): # When we're a static library and we link_with to an # internal/convenience library, promote to link_whole. @@ -2758,6 +2746,10 @@ class BothLibraries(SecondLevelHolder): def get_id(self) -> str: return self.get_default_object().get_id() + def is_linkable_target(self) -> bool: + # For polymorphism with build targets + return True + class CommandBase: depend_files: T.List[File] diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index e7d2ac9a8..6adad72e7 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -349,6 +349,7 @@ class _BaseBuildTarget(TypedDict): link_depends: T.List[T.Union[str, File, build.GeneratedTypes]] link_language: T.Optional[str] link_whole: T.List[build.StaticTargetTypes] + link_with: T.List[build.BuildTargetTypes] name_prefix: T.Optional[str] name_suffix: T.Optional[str] native: MachineChoice @@ -494,7 +495,7 @@ class FuncDeclareDependency(TypedDict): include_directories: T.List[T.Union[build.IncludeDirs, str]] link_args: T.List[str] link_whole: T.List[build.StaticTargetTypes] - link_with: T.List[build.LibTypes] + link_with: T.List[build.BuildTargetTypes] objects: T.List[build.ExtractedObjects] sources: T.List[T.Union[FileOrString, build.GeneratedTypes]] variables: T.Dict[str, str] diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py index 2d9f2a11e..3512925ee 100644 --- a/mesonbuild/interpreter/type_checking.py +++ b/mesonbuild/interpreter/type_checking.py @@ -440,13 +440,23 @@ D_MODULE_VERSIONS_KW: KwargInfo[T.List[T.Union[str, int]]] = KwargInfo( _LINK_WITH_ERROR = 'Dependency and external_library objects must go in the "dependencies" keyword argument' +def _link_with_validator(values: T.List[T.Union[BothLibraries, SharedLibrary, StaticLibrary, + CustomTarget, CustomTargetIndex, Jar, Executable, + ]] + ) -> T.Optional[str]: + for value in values: + if not value.is_linkable_target(): + return f'Link target "{value!s}" is not linkable' + return None + # Allow Dependency for the better error message? But then in other cases it will list this as one of the allowed types! LINK_WITH_KW: KwargInfo[T.List[T.Union[BothLibraries, SharedLibrary, StaticLibrary, CustomTarget, CustomTargetIndex, Jar, Executable]]] = KwargInfo( 'link_with', ContainerTypeInfo(list, (BothLibraries, SharedLibrary, StaticLibrary, CustomTarget, CustomTargetIndex, Jar, Executable)), listify=True, default=[], - extra_types={Dependency: lambda _: _LINK_WITH_ERROR} + extra_types={Dependency: lambda _: _LINK_WITH_ERROR}, + validator=_link_with_validator, ) def link_whole_validator(values: T.List[T.Union[StaticLibrary, CustomTarget, CustomTargetIndex]]) -> T.Optional[str]: @@ -729,6 +739,7 @@ _BUILD_TARGET_KWS: T.List[KwargInfo] = [ DEPENDENCIES_KW, INCLUDE_DIRECTORIES.evolve(name='d_import_dirs'), LINK_WHOLE_KW, + LINK_WITH_KW, _NAME_PREFIX_KW, _NAME_PREFIX_KW.evolve(name='name_suffix', validator=_name_suffix_validator), RUST_CRATE_TYPE_KW, |
