diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 9283bca97..0cb21cfeb 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1276,13 +1276,13 @@ class BuildTarget(Target): return self.extra_args[language] @lru_cache(maxsize=None) - def get_dependencies(self) -> OrderedSet[Target]: + def get_dependencies(self) -> OrderedSet[BuildTargetTypes]: # Get all targets needed for linking. This includes all link_with and # link_whole targets, and also all dependencies of static libraries # recursively. The algorithm here is closely related to what we do in # get_internal_static_libraries(): Installed static libraries include # objects from all their dependencies already. - result: OrderedSet[Target] = OrderedSet() + result: OrderedSet[BuildTargetTypes] = OrderedSet() for t in itertools.chain(self.link_targets, self.link_whole_targets): if t not in result: result.add(t) @@ -1290,7 +1290,7 @@ class BuildTarget(Target): t.get_dependencies_recurse(result) return result - def get_dependencies_recurse(self, result: OrderedSet[Target], include_internals: bool = True) -> None: + def get_dependencies_recurse(self, result: OrderedSet[BuildTargetTypes], include_internals: bool = True) -> None: # self is always a static library because we don't need to pull dependencies # of shared libraries. If self is installed (not internal) it already # include objects extracted from all its internal dependencies so we can @@ -1394,7 +1394,7 @@ class BuildTarget(Target): def is_internal(self) -> bool: return False - def link(self, targets): + def link(self, targets: T.List[BuildTargetTypes]) -> None: for t in targets: if not isinstance(t, (Target, CustomTargetIndex)): if isinstance(t, dependencies.ExternalLibrary): @@ -1420,7 +1420,7 @@ class BuildTarget(Target): self.check_can_link_together(t) self.link_targets.append(t) - def link_whole(self, targets, promoted: bool = False): + def link_whole(self, targets: T.List[BuildTargetTypes], promoted: bool = False) -> None: for t in targets: if isinstance(t, (CustomTarget, CustomTargetIndex)): if not t.is_linkable_target(): @@ -1437,32 +1437,30 @@ class BuildTarget(Target): if isinstance(self, StaticLibrary) and not self.uses_rust(): # When we're a static library and we link_whole: to another static # library, we need to add that target's objects to ourselves. - self.check_can_extract_objects(t, origin=self, promoted=promoted) - self.objects += [t.extract_all_objects()] + self._bundle_static_library(t, promoted) # If we install this static library we also need to include objects # from all uninstalled static libraries it depends on. if self.install: - for lib in t.get_internal_static_libraries(origin=self): - self.objects += [lib.extract_all_objects()] + for lib in t.get_internal_static_libraries(): + self._bundle_static_library(lib, True) self.link_whole_targets.append(t) @lru_cache(maxsize=None) - def get_internal_static_libraries(self, origin: StaticLibrary) -> OrderedSet[Target]: - result: OrderedSet[Target] = OrderedSet() - self.get_internal_static_libraries_recurse(result, origin) + def get_internal_static_libraries(self) -> OrderedSet[BuildTargetTypes]: + result: OrderedSet[BuildTargetTypes] = OrderedSet() + self.get_internal_static_libraries_recurse(result) return result - def get_internal_static_libraries_recurse(self, result: OrderedSet[Target], origin: StaticLibrary) -> None: + def get_internal_static_libraries_recurse(self, result: OrderedSet[BuildTargetTypes]) -> None: for t in self.link_targets: if t.is_internal() and t not in result: - self.check_can_extract_objects(t, origin, promoted=True) result.add(t) - t.get_internal_static_libraries_recurse(result, origin) + t.get_internal_static_libraries_recurse(result) for t in self.link_whole_targets: if t.is_internal(): - t.get_internal_static_libraries_recurse(result, origin) + t.get_internal_static_libraries_recurse(result) - def check_can_extract_objects(self, t: T.Union[Target, CustomTargetIndex], origin: StaticLibrary, promoted: bool = False) -> None: + def _bundle_static_library(self, t: T.Union[BuildTargetTypes], promoted: bool = False) -> None: if isinstance(t, (CustomTarget, CustomTargetIndex)) or t.uses_rust(): # To extract objects from a custom target we would have to extract # the archive, WIP implementation can be found in @@ -1472,12 +1470,13 @@ class BuildTarget(Target): # https://github.com/mesonbuild/meson/issues/10722 # https://github.com/mesonbuild/meson/issues/10723 # https://github.com/mesonbuild/meson/issues/10724 - m = (f'Cannot link_whole a custom or Rust target {t.name!r} into a static library {origin.name!r}. ' + m = (f'Cannot link_whole a custom or Rust target {t.name!r} into a static library {self.name!r}. ' 'Instead, pass individual object files with the "objects:" keyword argument if possible.') if promoted: - m += (f' Meson had to promote link to link_whole because {origin.name!r} is installed but not {t.name!r},' + m += (f' Meson had to promote link to link_whole because {self.name!r} is installed but not {t.name!r},' f' and thus has to include objects from {t.name!r} to be usable.') raise InvalidArguments(m) + self.objects.append(t.extract_all_objects()) def check_can_link_together(self, t: BuildTargetTypes) -> None: links_with_rust_abi = isinstance(t, BuildTarget) and t.uses_rust_abi()