diff options
Diffstat (limited to 'buildstream/element.py')
-rw-r--r-- | buildstream/element.py | 48 |
1 files changed, 46 insertions, 2 deletions
diff --git a/buildstream/element.py b/buildstream/element.py index a34b1ca36..88830d0aa 100644 --- a/buildstream/element.py +++ b/buildstream/element.py @@ -194,6 +194,7 @@ class Element(Plugin): self.__runtime_dependencies = [] # Direct runtime dependency Elements self.__build_dependencies = [] # Direct build dependency Elements + self.__reverse_dependencies = [] # Direct reverse dependency Elements self.__sources = [] # List of Sources self.__weak_cache_key = None # Our cached weak cache key self.__strict_cache_key = None # Our cached cache key for strict builds @@ -892,9 +893,11 @@ class Element(Plugin): for meta_dep in meta.dependencies: dependency = Element._new_from_meta(meta_dep, artifacts) element.__runtime_dependencies.append(dependency) + dependency.__reverse_dependencies.append(element) for meta_dep in meta.build_dependencies: dependency = Element._new_from_meta(meta_dep, artifacts) element.__build_dependencies.append(dependency) + dependency.__reverse_dependencies.append(element) return element @@ -1428,6 +1431,16 @@ class Element(Plugin): self._update_state() + if workspace: + # We need to invalidate reverse dependencies + for reverse_dep in self.__get_reverse_dependencies(): + reverse_dep.__cache_key_dict = None + reverse_dep.__cache_key = None + reverse_dep.__weak_cache_key = None + reverse_dep.__strict_cache_key = None + reverse_dep.__strong_cached = None + reverse_dep._update_state() + # _assemble_done(): # # This is called in the main process after the element has been assembled @@ -1465,8 +1478,14 @@ class Element(Plugin): # This does *not* cause a race condition, because # _assemble_done is called before a cleanup job may be # launched. - # - self.__artifacts.append_required_artifacts([self]) + required_artifacts = [self] + + # Reverse dependencies can now compute their keys + for reverse_dep in self.__get_reverse_dependencies(): + reverse_dep._update_state() + required_artifacts.append(reverse_dep) + + self.__artifacts.append_required_artifacts(required_artifacts) # _assemble(): # @@ -2598,6 +2617,31 @@ class Element(Plugin): return utils._deduplicate(keys) + # __get_reverse_dependencies(): + # + # Iterates through the closure of reverse dependenices. + # + # Args: + # visited (set): The elements to skip (only for recursion) + # recursed (bool): Whether to emit the current element (only for recursion) + # + # Yields: + # (:class:`.Element`): The reverse dependent elements + def __get_reverse_dependencies(self, *, visited=None, recursed=False): + if visited is None: + visited = set() + + full_name = self._get_full_name() + + if full_name in visited: + return + + if recursed: + yield self + + for reverse_dep in self.__reverse_dependencies: + yield from reverse_dep.__get_reverse_dependencies(visited=visited, recursed=True) + def _overlap_error_detail(f, forbidden_overlap_elements, elements): if forbidden_overlap_elements: |