Add ResolvedTargetData::GetHardDeps() This CL removes Target::recursive_hard_deps() and moves the computation of the corresponding value to the ResolvedTargetData class, which creates it on demand with the GetHardDeps() method. Bug: 331 Change-Id: I8aec15ab047533b2fe80ff853850de3a57dc898d Reviewed-on: https://gn-review.googlesource.com/c/gn/+/15325 Commit-Queue: David Turner <digit@google.com> Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/ninja_target_writer.cc b/src/gn/ninja_target_writer.cc index 416d62e..ea39822 100644 --- a/src/gn/ninja_target_writer.cc +++ b/src/gn/ninja_target_writer.cc
@@ -434,7 +434,7 @@ // Hard dependencies that are direct or indirect dependencies. // These are large (up to 100s), hence why we check other - const TargetSet& hard_deps(target_->recursive_hard_deps()); + const TargetSet& hard_deps = resolved().GetHardDeps(target_); for (const Target* target : hard_deps) { // BUNDLE_DATA should normally be treated as a data-only dependency // (see Target::IsDataOnly()). Only the CREATE_BUNDLE target, that actually
diff --git a/src/gn/resolved_target_data.cc b/src/gn/resolved_target_data.cc index 3208f04..467e2fb 100644 --- a/src/gn/resolved_target_data.cc +++ b/src/gn/resolved_target_data.cc
@@ -62,3 +62,29 @@ info->weak_frameworks = all_weak_frameworks.release(); info->has_framework_info = true; } + +void ResolvedTargetData::ComputeHardDeps(TargetInfo* info) const { + TargetSet all_hard_deps; + for (const Target* dep : info->deps.linked_deps()) { + // Direct hard dependencies + if (info->target->hard_dep() || dep->hard_dep()) { + all_hard_deps.insert(dep); + continue; + } + // If |dep| is binary target and |dep| has no public header, + // |this| target does not need to have |dep|'s hard_deps as its + // hard_deps to start compiles earlier. Unless the target compiles a + // Swift module (since they also generate a header that can be used + // by the current target). + if (dep->IsBinary() && !dep->all_headers_public() && + dep->public_headers().empty() && !dep->builds_swift_module()) { + continue; + } + + // Recursive hard dependencies of all dependencies. + const TargetInfo* dep_info = GetTargetHardDeps(dep); + all_hard_deps.insert(dep_info->hard_deps); + } + info->hard_deps = std::move(all_hard_deps); + info->has_hard_deps = true; +}
diff --git a/src/gn/resolved_target_data.h b/src/gn/resolved_target_data.h index 754abc2..bc992a1 100644 --- a/src/gn/resolved_target_data.h +++ b/src/gn/resolved_target_data.h
@@ -96,6 +96,13 @@ return GetTargetFrameworkInfo(target)->weak_frameworks; } + // Retrieves a set of hard dependencies for this target. + // All hard deps from this target and all dependencies, but not the + // target itself. + const TargetSet& GetHardDeps(const Target* target) const { + return GetTargetHardDeps(target)->hard_deps; + } + private: // The information associated with a given Target pointer. struct TargetInfo { @@ -112,6 +119,7 @@ bool has_lib_info = false; bool has_framework_info = false; + bool has_hard_deps = false; // Only valid if |has_lib_info| is true. std::vector<SourceDir> lib_dirs; @@ -121,6 +129,9 @@ std::vector<SourceDir> framework_dirs; std::vector<std::string> frameworks; std::vector<std::string> weak_frameworks; + + // Only valid if |has_hard_deps| is true. + TargetSet hard_deps; }; // Retrieve TargetInfo value associated with |target|. Create @@ -145,11 +156,21 @@ return info; } + const TargetInfo* GetTargetHardDeps(const Target* target) const { + TargetInfo* info = GetTargetInfo(target); + if (!info->has_hard_deps) { + ComputeHardDeps(info); + DCHECK(info->has_hard_deps); + } + return info; + } + // Compute the portion of TargetInfo guarded by one of the |has_xxx| // booleans. This performs recursive and expensive computations and // should only be called once per TargetInfo instance. void ComputeLibInfo(TargetInfo* info) const; void ComputeFrameworkInfo(TargetInfo* info) const; + void ComputeHardDeps(TargetInfo* info) const; // A { Target* -> TargetInfo } map that will create entries // on demand (hence the mutable qualifier). Implemented with a
diff --git a/src/gn/target.cc b/src/gn/target.cc index 0ad2dd2..84cfbfa 100644 --- a/src/gn/target.cc +++ b/src/gn/target.cc
@@ -485,7 +485,6 @@ PullRecursiveBundleData(); PullDependentTargetLibs(); - PullRecursiveHardDeps(); if (!ResolvePrecompiledHeaders(err)) return false; @@ -848,31 +847,6 @@ PullDependentTargetLibsFrom(dep.ptr, false); } -void Target::PullRecursiveHardDeps() { - for (const auto& pair : GetDeps(DEPS_LINKED)) { - // Direct hard dependencies. - if (hard_dep() || pair.ptr->hard_dep()) { - recursive_hard_deps_.insert(pair.ptr); - continue; - } - - // If |pair.ptr| is binary target and |pair.ptr| has no public header, - // |this| target does not need to have |pair.ptr|'s hard_deps as its - // hard_deps to start compiles earlier. Unless the target compiles a - // Swift module (since they also generate a header that can be used - // by the current target). - if (pair.ptr->IsBinary() && !pair.ptr->all_headers_public() && - pair.ptr->public_headers().empty() && - !pair.ptr->builds_swift_module()) { - continue; - } - - // Recursive hard dependencies of all dependencies. - recursive_hard_deps_.insert(pair.ptr->recursive_hard_deps().begin(), - pair.ptr->recursive_hard_deps().end()); - } -} - void Target::PullRecursiveBundleData() { for (const auto& pair : GetDeps(DEPS_LINKED)) { // Don't propagate bundle_data once they are added to a bundle.
diff --git a/src/gn/target.h b/src/gn/target.h index 899e06b..d672985 100644 --- a/src/gn/target.h +++ b/src/gn/target.h
@@ -332,8 +332,6 @@ return rust_transitive_inheritable_libs_; } - const TargetSet& recursive_hard_deps() const { return recursive_hard_deps_; } - std::vector<LabelPattern>& friends() { return friends_; } const std::vector<LabelPattern>& friends() const { return friends_; } @@ -491,10 +489,6 @@ // that need to be linked. InheritedLibraries inherited_libraries_; - // All hard deps from this target and all dependencies. Filled in when this - // target is marked resolved. This will not include the current target. - TargetSet recursive_hard_deps_; - std::vector<LabelPattern> friends_; std::vector<LabelPattern> assert_no_deps_;