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_;