#include "gn/resolved_target_data.h"
#include "gn/config_values_extractors.h"
ResolvedTargetData::TargetInfo* ResolvedTargetData::GetTargetInfo(
const Target* target) const {
{
std::shared_lock<std::shared_mutex> lock(map_mutex_);
size_t index = targets_.IndexOf(target);
if (index != UniqueVector<const Target*>::kIndexNone) {
return infos_[index].get();
}
}
std::unique_lock<std::shared_mutex> lock(map_mutex_);
auto ret = targets_.PushBackWithIndex(target);
if (ret.first) {
infos_.push_back(std::make_unique<TargetInfo>(target));
}
return infos_[ret.second].get();
}
void ResolvedTargetData::ComputeLibInfo(TargetInfo* info) const {
UniqueVector<SourceDir> all_lib_dirs;
UniqueVector<LibFile> all_libs;
for (ConfigValuesIterator iter(info->target); !iter.done(); iter.Next()) {
const ConfigValues& cur = iter.cur();
all_lib_dirs.Append(cur.lib_dirs());
all_libs.Append(cur.libs());
}
for (const Target* dep : info->deps.linked_deps()) {
if (!dep->IsFinal() || dep->output_type() == Target::STATIC_LIBRARY) {
const TargetInfo* dep_info = GetTargetLibInfo(dep);
all_lib_dirs.Append(dep_info->lib_dirs);
all_libs.Append(dep_info->libs);
}
}
info->lib_dirs = all_lib_dirs.release();
info->libs = all_libs.release();
info->has_lib_info = true;
}
void ResolvedTargetData::ComputeFrameworkInfo(TargetInfo* info) const {
UniqueVector<SourceDir> all_framework_dirs;
UniqueVector<std::string> all_frameworks;
UniqueVector<std::string> all_weak_frameworks;
UniqueVector<std::string> all_weak_libraries;
for (ConfigValuesIterator iter(info->target); !iter.done(); iter.Next()) {
const ConfigValues& cur = iter.cur();
all_framework_dirs.Append(cur.framework_dirs());
all_frameworks.Append(cur.frameworks());
all_weak_frameworks.Append(cur.weak_frameworks());
all_weak_libraries.Append(cur.weak_libraries());
}
for (const Target* dep : info->deps.linked_deps()) {
if (!dep->IsFinal() || dep->output_type() == Target::STATIC_LIBRARY) {
const TargetInfo* dep_info = GetTargetFrameworkInfo(dep);
all_framework_dirs.Append(dep_info->framework_dirs);
all_frameworks.Append(dep_info->frameworks);
all_weak_frameworks.Append(dep_info->weak_frameworks);
all_weak_libraries.Append(dep_info->weak_libraries);
}
}
info->framework_dirs = all_framework_dirs.release();
info->frameworks = all_frameworks.release();
info->weak_frameworks = all_weak_frameworks.release();
info->weak_libraries = all_weak_libraries.release();
info->has_framework_info = true;
}
void ResolvedTargetData::ComputeHardDeps(TargetInfo* info) const {
TargetSet all_hard_deps;
for (const Target* dep : info->deps.linked_deps()) {
if (info->target->hard_dep() || dep->hard_dep()) {
all_hard_deps.insert(dep);
continue;
}
if (dep->IsBinary() && !dep->all_headers_public() &&
dep->public_headers().empty() && !dep->builds_swift_module()) {
continue;
}
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;
}
void ResolvedTargetData::ComputeInheritedLibs(TargetInfo* info) const {
TargetPublicPairListBuilder inherited_libraries;
ComputeInheritedLibsFor(info->deps.public_deps(), true, &inherited_libraries);
ComputeInheritedLibsFor(info->deps.private_deps(), false,
&inherited_libraries);
info->inherited_libs = inherited_libraries.Build();
info->has_inherited_libs = true;
}
void ResolvedTargetData::ComputeInheritedLibsFor(
base::span<const Target*> deps,
bool is_public,
TargetPublicPairListBuilder* inherited_libraries) const {
for (const Target* dep : deps) {
if (dep->output_type() == Target::STATIC_LIBRARY ||
dep->output_type() == Target::SHARED_LIBRARY ||
dep->output_type() == Target::RUST_LIBRARY ||
dep->output_type() == Target::SOURCE_SET ||
dep->copy_linkable_file() ||
(dep->output_type() == Target::CREATE_BUNDLE &&
dep->bundle_data().is_framework())) {
inherited_libraries->Append(dep, is_public);
}
if (dep->output_type() == Target::SHARED_LIBRARY ||
dep->copy_linkable_file()) {
const TargetInfo* dep_info = GetTargetInheritedLibs(dep);
for (const auto& pair : dep_info->inherited_libs) {
if ((pair.target()->output_type() == Target::SHARED_LIBRARY ||
pair.target()->copy_linkable_file()) &&
pair.is_public()) {
inherited_libraries->Append(pair.target(), is_public);
}
}
} else if (!dep->IsFinal()) {
const TargetInfo* dep_info = GetTargetInheritedLibs(dep);
for (const auto& pair : dep_info->inherited_libs) {
if (pair.target()->output_type() != Target::RUST_PROC_MACRO)
inherited_libraries->Append(pair.target(),
is_public && pair.is_public());
}
} else if (dep->complete_static_lib()) {
const TargetInfo* dep_info = GetTargetInheritedLibs(dep);
for (const auto& pair : dep_info->inherited_libs) {
if (pair.target()->IsFinal())
inherited_libraries->Append(pair.target(),
is_public && pair.is_public());
}
}
}
}
void ResolvedTargetData::ComputeModuleDepsInformation(TargetInfo* info) const {
TargetPublicPairListBuilder module_deps_information;
ComputeModuleDepsInformationFor(info->deps.public_deps(), true,
&module_deps_information);
ComputeModuleDepsInformationFor(info->deps.private_deps(), false,
&module_deps_information);
info->module_deps_information = module_deps_information.Build();
info->has_module_deps_information = true;
}
void ResolvedTargetData::ComputeModuleDepsInformationFor(
base::span<const Target*> deps,
bool is_public,
TargetPublicPairListBuilder* module_deps_information) const {
for (const Target* dep : deps) {
if (dep->output_type() != Target::STATIC_LIBRARY &&
dep->output_type() != Target::SHARED_LIBRARY &&
dep->output_type() != Target::SOURCE_SET &&
dep->output_type() != Target::GROUP) {
continue;
}
module_deps_information->Append(dep, is_public);
const TargetInfo* dep_info = GetTargetModuleDepsInformation(dep);
for (const auto& pair : dep_info->module_deps_information) {
if (pair.is_public()) {
module_deps_information->Append(pair.target(), is_public);
}
}
}
}
void ResolvedTargetData::ComputeRustLibs(TargetInfo* info) const {
RustLibsBuilder rust_libs;
ComputeRustLibsFor(info->deps.public_deps(), true, &rust_libs);
ComputeRustLibsFor(info->deps.private_deps(), false, &rust_libs);
info->rust_inherited_libs = rust_libs.inherited.Build();
info->rust_inheritable_libs = rust_libs.inheritable.Build();
info->has_rust_libs = true;
}
void ResolvedTargetData::ComputeRustLibsFor(base::span<const Target*> deps,
bool is_public,
RustLibsBuilder* rust_libs) const {
for (const Target* dep : deps) {
if (dep->output_type() == Target::STATIC_LIBRARY ||
dep->output_type() == Target::SHARED_LIBRARY ||
dep->output_type() == Target::SOURCE_SET ||
dep->output_type() == Target::RUST_LIBRARY ||
dep->output_type() == Target::GROUP || dep->copy_linkable_file()) {
rust_libs->inherited.Append(dep, true);
rust_libs->inheritable.Append(dep, is_public);
const TargetInfo* dep_info = GetTargetRustLibs(dep);
rust_libs->inherited.AppendInherited(dep_info->rust_inheritable_libs,
true);
rust_libs->inheritable.AppendInherited(dep_info->rust_inheritable_libs,
is_public);
} else if (dep->output_type() == Target::RUST_PROC_MACRO) {
rust_libs->inherited.Append(dep, true);
rust_libs->inheritable.Append(dep, is_public);
}
}
}
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;
}