Add ResolvedTargetData:GetSwiftModuleDependencies() This moves the SwiftValues::modules_ and SwiftValues::public_modules_ values to the ResolvedTargetData class to compute them on demand, instead of unconditionally. Bug: 331 Change-Id: Icc894415cb556c9b750227dd8cf7a493982d77b9 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/15328 Commit-Queue: David Turner <digit@google.com> Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/ninja_c_binary_target_writer.cc b/src/gn/ninja_c_binary_target_writer.cc index 9978b63..da27df6 100644 --- a/src/gn/ninja_c_binary_target_writer.cc +++ b/src/gn/ninja_c_binary_target_writer.cc
@@ -564,7 +564,8 @@ swift_order_only_deps.Append(order_only_deps.begin(), order_only_deps.end()); - for (const Target* swiftmodule : target_->swift_values().modules()) + for (const Target* swiftmodule : + resolved().GetSwiftModuleDependencies(target_)) swift_order_only_deps.push_back(swiftmodule->dependency_output_file()); WriteCompilerBuildLine(target_->sources(), input_deps,
diff --git a/src/gn/ninja_target_writer.cc b/src/gn/ninja_target_writer.cc index ea39822..2f7ec38 100644 --- a/src/gn/ninja_target_writer.cc +++ b/src/gn/ninja_target_writer.cc
@@ -346,7 +346,7 @@ // Uniquify the list of swiftmodule dirs (in case multiple swiftmodules // are generated in the same directory). UniqueVector<SourceDir> swiftmodule_dirs; - for (const Target* dep : target_->swift_values().modules()) + for (const Target* dep : resolved().GetSwiftModuleDependencies(target_)) swiftmodule_dirs.push_back(dep->swift_values().module_output_dir()); if (indent)
diff --git a/src/gn/resolved_target_data.cc b/src/gn/resolved_target_data.cc index b2692e7..7c3e79f 100644 --- a/src/gn/resolved_target_data.cc +++ b/src/gn/resolved_target_data.cc
@@ -223,3 +223,43 @@ } } } + +void ResolvedTargetData::ComputeSwiftValues(TargetInfo* info) const { + UniqueVector<const Target*> modules; + UniqueVector<const Target*> public_modules; + const Target* target = info->target; + + for (const Target* dep : info->deps.public_deps()) { + if (dep->toolchain() != target->toolchain() && + !dep->toolchain()->propagates_configs()) { + continue; + } + + const TargetInfo* dep_info = GetTargetSwiftValues(dep); + if (dep_info->swift_values.get()) { + const auto& public_deps = dep_info->swift_values->public_modules; + modules.Append(public_deps); + public_modules.Append(public_deps); + } + } + + for (const Target* dep : info->deps.private_deps()) { + if (dep->toolchain() != target->toolchain() && + !dep->toolchain()->propagates_configs()) { + continue; + } + const TargetInfo* dep_info = GetTargetSwiftValues(dep); + if (dep_info->swift_values.get()) { + modules.Append(dep_info->swift_values->public_modules); + } + } + + if (target->builds_swift_module()) + public_modules.push_back(target); + + if (!modules.empty() || !public_modules.empty()) { + info->swift_values = std::make_unique<TargetInfo::SwiftValues>( + modules.release(), public_modules.release()); + } + info->has_swift_values = true; +}
diff --git a/src/gn/resolved_target_data.h b/src/gn/resolved_target_data.h index f8f6458..61483bf 100644 --- a/src/gn/resolved_target_data.h +++ b/src/gn/resolved_target_data.h
@@ -117,6 +117,17 @@ return GetTargetRustLibs(target)->rust_inherited_libs; } + // List of dependent target that generate a .swiftmodule. The current target + // is assumed to depend on those modules, and will add them to the module + // search path. + base::span<const Target*> GetSwiftModuleDependencies( + const Target* target) const { + const TargetInfo* info = GetTargetSwiftValues(target); + if (!info->swift_values.get()) + return {}; + return info->swift_values->modules; + } + private: // The information associated with a given Target pointer. struct TargetInfo { @@ -136,6 +147,7 @@ bool has_hard_deps = false; bool has_inherited_libs = false; bool has_rust_libs = false; + bool has_swift_values = false; // Only valid if |has_lib_info| is true. std::vector<SourceDir> lib_dirs; @@ -155,6 +167,21 @@ // Only valid if |has_rust_libs| is true. std::vector<TargetPublicPair> rust_inherited_libs; std::vector<TargetPublicPair> rust_inheritable_libs; + + // Only valid if |has_swift_values| is true. + // Most targets will not have Swift dependencies, so only + // allocate a SwiftValues struct when needed. A null pointer + // indicates empty lists. + struct SwiftValues { + std::vector<const Target*> modules; + std::vector<const Target*> public_modules; + + SwiftValues(std::vector<const Target*> modules, + std::vector<const Target*> public_modules) + : modules(std::move(modules)), + public_modules(std::move(public_modules)) {} + }; + std::unique_ptr<SwiftValues> swift_values; }; // Retrieve TargetInfo value associated with |target|. Create @@ -206,6 +233,15 @@ return info; } + const TargetInfo* GetTargetSwiftValues(const Target* target) const { + TargetInfo* info = GetTargetInfo(target); + if (!info->has_swift_values) { + ComputeSwiftValues(info); + DCHECK(info->has_swift_values); + } + 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. @@ -214,6 +250,7 @@ void ComputeHardDeps(TargetInfo* info) const; void ComputeInheritedLibs(TargetInfo* info) const; void ComputeRustLibs(TargetInfo* info) const; + void ComputeSwiftValues(TargetInfo* info) const; // Helper function used by ComputeInheritedLibs(). void ComputeInheritedLibsFor(
diff --git a/src/gn/swift_values.cc b/src/gn/swift_values.cc index 85a49ad..6065478 100644 --- a/src/gn/swift_values.cc +++ b/src/gn/swift_values.cc
@@ -16,40 +16,7 @@ // static bool SwiftValues::OnTargetResolved(Target* target, Err* err) { - if (!FillModuleOutputFile(target, err)) - return false; - - FillModuleDependencies(target); - return true; -} - -// static -void SwiftValues::FillModuleDependencies(Target* target) { - for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) { - if (!pair.ptr->has_swift_values()) - continue; - - if (pair.ptr->toolchain() == target->toolchain() || - pair.ptr->toolchain()->propagates_configs()) { - target->swift_values().modules_.Append( - pair.ptr->swift_values().public_modules().begin(), - pair.ptr->swift_values().public_modules().end()); - } - } - - for (const auto& pair : target->public_deps()) { - if (!pair.ptr->has_swift_values()) - continue; - - if (pair.ptr->toolchain() == target->toolchain() || - pair.ptr->toolchain()->propagates_configs()) - target->swift_values().public_modules_.Append( - pair.ptr->swift_values().public_modules().begin(), - pair.ptr->swift_values().public_modules().end()); - } - - if (target->builds_swift_module()) - target->swift_values().public_modules_.push_back(target); + return FillModuleOutputFile(target, err); } // static
diff --git a/src/gn/swift_values.h b/src/gn/swift_values.h index 91ec066..198ca85 100644 --- a/src/gn/swift_values.h +++ b/src/gn/swift_values.h
@@ -43,25 +43,10 @@ // Computed when the target is resolved. const SourceDir& module_output_dir() const { return module_output_dir_; } - // List of dependent target that generate a .swiftmodule. The current target - // is assumed to depend on those modules, and will add them to the module - // search path. - const UniqueVector<const Target*>& modules() const { return modules_; } - - // List of dependent target that generate a .swiftmodule that are publicly - // exported by the current target. This will include the current target if - // it generates a .swiftmodule. - const UniqueVector<const Target*>& public_modules() const { - return public_modules_; - } - private: // Fill informations about .swiftmodule generated by this target. static bool FillModuleOutputFile(Target* target, Err* err); - // Fill dependencies information on other target generating .swiftmodules. - static void FillModuleDependencies(Target* target); - // Name of the optional bridge header used to import Objective-C classes. // Filled from the target, may be empty even if the target include .swift // source files. @@ -77,12 +62,6 @@ // Path of the directory containing the .swiftmodule generated by this // target. Will be null if the target does not include .swift sources. SourceDir module_output_dir_; - - // For modules() and public_modules() function. Will be filled when the - // target is resolved (can be non-empty even if the target does not build - // .swift sources due to transitive dependencies). - UniqueVector<const Target*> modules_; - UniqueVector<const Target*> public_modules_; }; #endif // TOOLS_GN_SWIFT_TARGET_VALUES_H_