This source file includes following definitions.
- MergeDirectDependentConfigsFrom
- MergeAllDependentConfigsFrom
- hard_dep_
- GetStringForOutputType
- AsTarget
- AsTarget
- OnResolved
- IsLinkable
- PullDependentTargetInfo
#include "tools/gn/target.h"
#include "base/bind.h"
#include "tools/gn/config_values_extractors.h"
#include "tools/gn/scheduler.h"
namespace {
typedef std::set<const Config*> ConfigSet;
void MergeDirectDependentConfigsFrom(const Target* from_target,
ConfigSet* unique_configs,
LabelConfigVector* dest) {
const LabelConfigVector& direct = from_target->direct_dependent_configs();
for (size_t i = 0; i < direct.size(); i++) {
if (unique_configs->find(direct[i].ptr) == unique_configs->end()) {
unique_configs->insert(direct[i].ptr);
dest->push_back(direct[i]);
}
}
}
void MergeAllDependentConfigsFrom(const Target* from_target,
ConfigSet* unique_configs,
LabelConfigVector* dest,
LabelConfigVector* all_dest) {
const LabelConfigVector& all = from_target->all_dependent_configs();
for (size_t i = 0; i < all.size(); i++) {
all_dest->push_back(all[i]);
if (unique_configs->find(all[i].ptr) == unique_configs->end()) {
dest->push_back(all[i]);
unique_configs->insert(all[i].ptr);
}
}
}
}
Target::Target(const Settings* settings, const Label& label)
: Item(settings, label),
output_type_(UNKNOWN),
hard_dep_(false) {
}
Target::~Target() {
}
const char* Target::GetStringForOutputType(OutputType type) {
switch (type) {
case UNKNOWN:
return "Unknown";
case GROUP:
return "Group";
case EXECUTABLE:
return "Executable";
case SHARED_LIBRARY:
return "Shared library";
case STATIC_LIBRARY:
return "Static library";
case COPY_FILES:
return "Copy";
case ACTION:
return "Action";
case ACTION_FOREACH:
return "ActionForEach";
default:
return "";
}
}
Target* Target::AsTarget() {
return this;
}
const Target* Target::AsTarget() const {
return this;
}
void Target::OnResolved() {
DCHECK(output_type_ != UNKNOWN);
size_t original_deps_size = deps_.size();
for (size_t i = 0; i < original_deps_size; i++) {
const Target* dep = deps_[i].ptr;
if (dep->output_type_ == GROUP) {
deps_.insert(deps_.begin() + i + 1, dep->deps_.begin(), dep->deps_.end());
i += dep->deps_.size();
}
}
ConfigSet unique_configs;
for (size_t i = 0; i < configs_.size(); i++)
unique_configs.insert(configs_[i].ptr);
for (size_t i = 0; i < all_dependent_configs_.size(); i++) {
if (unique_configs.find(all_dependent_configs_[i].ptr) ==
unique_configs.end()) {
unique_configs.insert(all_dependent_configs_[i].ptr);
configs_.push_back(all_dependent_configs_[i]);
}
}
for (size_t i = 0; i < direct_dependent_configs_.size(); i++) {
if (unique_configs.find(direct_dependent_configs_[i].ptr) ==
unique_configs.end()) {
unique_configs.insert(direct_dependent_configs_[i].ptr);
configs_.push_back(direct_dependent_configs_[i]);
}
}
for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
const ConfigValues& cur = iter.cur();
all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end());
all_libs_.append(cur.libs().begin(), cur.libs().end());
}
if (output_type_ != GROUP) {
PullDependentTargetInfo(&unique_configs);
}
}
bool Target::IsLinkable() const {
return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY;
}
void Target::PullDependentTargetInfo(std::set<const Config*>* unique_configs) {
for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) {
const Target* dep = deps_[dep_i].ptr;
MergeAllDependentConfigsFrom(dep, unique_configs, &configs_,
&all_dependent_configs_);
MergeDirectDependentConfigsFrom(dep, unique_configs, &configs_);
if (dep->output_type() == STATIC_LIBRARY ||
dep->output_type() == SHARED_LIBRARY ||
dep->output_type() == SOURCE_SET)
inherited_libraries_.insert(dep);
if (dep->output_type() != SHARED_LIBRARY &&
dep->output_type() != EXECUTABLE) {
const std::set<const Target*> inherited = dep->inherited_libraries();
for (std::set<const Target*>::const_iterator i = inherited.begin();
i != inherited.end(); ++i)
inherited_libraries_.insert(*i);
all_lib_dirs_.append(dep->all_lib_dirs());
all_libs_.append(dep->all_libs());
}
}
for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) {
const Target* from_target = forward_dependent_configs_[dep].ptr;
DCHECK(std::find_if(deps_.begin(), deps_.end(),
LabelPtrPtrEquals<Target>(from_target)) !=
deps_.end());
direct_dependent_configs_.insert(
direct_dependent_configs_.end(),
from_target->direct_dependent_configs().begin(),
from_target->direct_dependent_configs().end());
}
}