Rewrite AcceptTouchEvents test from content_browsertests to browser_tests.
[chromium-blink-merge.git] / tools / gn / target.cc
blobb6845d03de6698cd96ccc07f2f9e4ac3678d2a31
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "tools/gn/target.h"
7 #include "base/bind.h"
8 #include "tools/gn/config_values_extractors.h"
9 #include "tools/gn/scheduler.h"
11 namespace {
13 typedef std::set<const Config*> ConfigSet;
15 // Merges the dependent configs from the given target to the given config list.
16 // The unique_configs list is used for de-duping so values already added will
17 // not be added again.
18 void MergeDirectDependentConfigsFrom(const Target* from_target,
19 ConfigSet* unique_configs,
20 LabelConfigVector* dest) {
21 const LabelConfigVector& direct = from_target->direct_dependent_configs();
22 for (size_t i = 0; i < direct.size(); i++) {
23 if (unique_configs->find(direct[i].ptr) == unique_configs->end()) {
24 unique_configs->insert(direct[i].ptr);
25 dest->push_back(direct[i]);
30 // Like MergeDirectDependentConfigsFrom above except does the "all dependent"
31 // ones. This additionally adds all configs to the all_dependent_configs_ of
32 // the dest target given in *all_dest.
33 void MergeAllDependentConfigsFrom(const Target* from_target,
34 ConfigSet* unique_configs,
35 LabelConfigVector* dest,
36 LabelConfigVector* all_dest) {
37 const LabelConfigVector& all = from_target->all_dependent_configs();
38 for (size_t i = 0; i < all.size(); i++) {
39 // Always add it to all_dependent_configs_ since it might not be in that
40 // list even if we've seen it applied to this target before. This may
41 // introduce some duplicates in all_dependent_configs_, but those will
42 // we removed when they're actually applied to a target.
43 all_dest->push_back(all[i]);
44 if (unique_configs->find(all[i].ptr) == unique_configs->end()) {
45 // One we haven't seen yet, also apply it to ourselves.
46 dest->push_back(all[i]);
47 unique_configs->insert(all[i].ptr);
52 } // namespace
54 Target::Target(const Settings* settings, const Label& label)
55 : Item(settings, label),
56 output_type_(UNKNOWN),
57 all_headers_public_(true),
58 hard_dep_(false) {
61 Target::~Target() {
64 // static
65 const char* Target::GetStringForOutputType(OutputType type) {
66 switch (type) {
67 case UNKNOWN:
68 return "Unknown";
69 case GROUP:
70 return "Group";
71 case EXECUTABLE:
72 return "Executable";
73 case SHARED_LIBRARY:
74 return "Shared library";
75 case STATIC_LIBRARY:
76 return "Static library";
77 case COPY_FILES:
78 return "Copy";
79 case ACTION:
80 return "Action";
81 case ACTION_FOREACH:
82 return "ActionForEach";
83 default:
84 return "";
88 Target* Target::AsTarget() {
89 return this;
92 const Target* Target::AsTarget() const {
93 return this;
96 void Target::OnResolved() {
97 DCHECK(output_type_ != UNKNOWN);
99 // Convert any groups we depend on to just direct dependencies on that
100 // group's deps. We insert the new deps immediately after the group so that
101 // the ordering is preserved. We need to keep the original group so that any
102 // flags, etc. that it specifies itself are applied to us.
103 size_t original_deps_size = deps_.size();
104 for (size_t i = 0; i < original_deps_size; i++) {
105 const Target* dep = deps_[i].ptr;
106 if (dep->output_type_ == GROUP) {
107 deps_.insert(deps_.begin() + i + 1, dep->deps_.begin(), dep->deps_.end());
108 i += dep->deps_.size();
112 // Only add each config once. First remember the target's configs.
113 ConfigSet unique_configs;
114 for (size_t i = 0; i < configs_.size(); i++)
115 unique_configs.insert(configs_[i].ptr);
117 // Copy our own dependent configs to the list of configs applying to us.
118 for (size_t i = 0; i < all_dependent_configs_.size(); i++) {
119 if (unique_configs.find(all_dependent_configs_[i].ptr) ==
120 unique_configs.end()) {
121 unique_configs.insert(all_dependent_configs_[i].ptr);
122 configs_.push_back(all_dependent_configs_[i]);
125 for (size_t i = 0; i < direct_dependent_configs_.size(); i++) {
126 if (unique_configs.find(direct_dependent_configs_[i].ptr) ==
127 unique_configs.end()) {
128 unique_configs.insert(direct_dependent_configs_[i].ptr);
129 configs_.push_back(direct_dependent_configs_[i]);
133 // Copy our own libs and lib_dirs to the final set. This will be from our
134 // target and all of our configs. We do this specially since these must be
135 // inherited through the dependency tree (other flags don't work this way).
136 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
137 const ConfigValues& cur = iter.cur();
138 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end());
139 all_libs_.append(cur.libs().begin(), cur.libs().end());
142 if (output_type_ != GROUP) {
143 // Don't pull target info like libraries and configs from dependencies into
144 // a group target. When A depends on a group G, the G's dependents will
145 // be treated as direct dependencies of A, so this is unnecessary and will
146 // actually result in duplicated settings (since settings will also be
147 // pulled from G to A in case G has configs directly on it).
148 PullDependentTargetInfo(&unique_configs);
150 PullForwardedDependentConfigs();
151 PullRecursiveHardDeps();
154 bool Target::IsLinkable() const {
155 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY;
158 void Target::PullDependentTargetInfo(std::set<const Config*>* unique_configs) {
159 // Gather info from our dependents we need.
160 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) {
161 const Target* dep = deps_[dep_i].ptr;
162 MergeAllDependentConfigsFrom(dep, unique_configs, &configs_,
163 &all_dependent_configs_);
164 MergeDirectDependentConfigsFrom(dep, unique_configs, &configs_);
166 // Direct dependent libraries.
167 if (dep->output_type() == STATIC_LIBRARY ||
168 dep->output_type() == SHARED_LIBRARY ||
169 dep->output_type() == SOURCE_SET)
170 inherited_libraries_.insert(dep);
172 // Inherited libraries and flags are inherited across static library
173 // boundaries.
174 if (dep->output_type() != SHARED_LIBRARY &&
175 dep->output_type() != EXECUTABLE) {
176 const std::set<const Target*> inherited = dep->inherited_libraries();
177 for (std::set<const Target*>::const_iterator i = inherited.begin();
178 i != inherited.end(); ++i)
179 inherited_libraries_.insert(*i);
181 // Inherited library settings.
182 all_lib_dirs_.append(dep->all_lib_dirs());
183 all_libs_.append(dep->all_libs());
188 void Target::PullForwardedDependentConfigs() {
189 // Groups implicitly forward all if its dependency's configs.
190 if (output_type() == GROUP)
191 forward_dependent_configs_ = deps_;
193 // Forward direct dependent configs if requested.
194 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) {
195 const Target* from_target = forward_dependent_configs_[dep].ptr;
197 // The forward_dependent_configs_ must be in the deps already, so we
198 // don't need to bother copying to our configs, only forwarding.
199 DCHECK(std::find_if(deps_.begin(), deps_.end(),
200 LabelPtrPtrEquals<Target>(from_target)) !=
201 deps_.end());
202 direct_dependent_configs_.insert(
203 direct_dependent_configs_.end(),
204 from_target->direct_dependent_configs().begin(),
205 from_target->direct_dependent_configs().end());
209 void Target::PullRecursiveHardDeps() {
210 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) {
211 const Target* dep = deps_[dep_i].ptr;
212 if (dep->hard_dep())
213 recursive_hard_deps_.insert(dep);
214 recursive_hard_deps_.insert(dep->recursive_hard_deps().begin(),
215 dep->recursive_hard_deps().end());