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_