Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: tools/gn/target.cc

Issue 561273003: Add public deps to GN (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/target.h" 5 #include "tools/gn/target.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "tools/gn/config_values_extractors.h" 10 #include "tools/gn/config_values_extractors.h"
11 #include "tools/gn/filesystem_utils.h" 11 #include "tools/gn/filesystem_utils.h"
12 #include "tools/gn/scheduler.h" 12 #include "tools/gn/scheduler.h"
13 #include "tools/gn/substitution_writer.h" 13 #include "tools/gn/substitution_writer.h"
14 14
15 namespace { 15 namespace {
16 16
17 typedef std::set<const Config*> ConfigSet; 17 typedef std::set<const Config*> ConfigSet;
18 18
19 // Merges the dependent configs from the given target to the given config list. 19 // Merges the public configs from the given target to the given config list.
20 void MergeDirectDependentConfigsFrom(const Target* from_target, 20 void MergePublicConfigsFrom(const Target* from_target,
21 UniqueVector<LabelConfigPair>* dest) { 21 UniqueVector<LabelConfigPair>* dest) {
22 const UniqueVector<LabelConfigPair>& direct = 22 const UniqueVector<LabelConfigPair>& pub = from_target->public_configs();
23 from_target->direct_dependent_configs(); 23 for (size_t i = 0; i < pub.size(); i++)
24 for (size_t i = 0; i < direct.size(); i++) 24 dest->push_back(pub[i]);
25 dest->push_back(direct[i]);
26 } 25 }
27 26
28 // Like MergeDirectDependentConfigsFrom above except does the "all dependent" 27 // Like MergePublicConfigsFrom above except does the "all dependent" ones. This
29 // ones. This additionally adds all configs to the all_dependent_configs_ of 28 // additionally adds all configs to the all_dependent_configs_ of the dest
30 // the dest target given in *all_dest. 29 // target given in *all_dest.
31 void MergeAllDependentConfigsFrom(const Target* from_target, 30 void MergeAllDependentConfigsFrom(const Target* from_target,
32 UniqueVector<LabelConfigPair>* dest, 31 UniqueVector<LabelConfigPair>* dest,
33 UniqueVector<LabelConfigPair>* all_dest) { 32 UniqueVector<LabelConfigPair>* all_dest) {
34 const UniqueVector<LabelConfigPair>& all = 33 const UniqueVector<LabelConfigPair>& all =
35 from_target->all_dependent_configs(); 34 from_target->all_dependent_configs();
36 for (size_t i = 0; i < all.size(); i++) { 35 for (size_t i = 0; i < all.size(); i++) {
37 all_dest->push_back(all[i]); 36 all_dest->push_back(all[i]);
38 dest->push_back(all[i]); 37 dest->push_back(all[i]);
39 } 38 }
40 } 39 }
41 40
42 Err MakeTestOnlyError(const Target* from, const Target* to) { 41 Err MakeTestOnlyError(const Target* from, const Target* to) {
43 return Err(from->defined_from(), "Test-only dependency not allowed.", 42 return Err(from->defined_from(), "Test-only dependency not allowed.",
44 from->label().GetUserVisibleName(false) + "\n" 43 from->label().GetUserVisibleName(false) + "\n"
45 "which is NOT marked testonly can't depend on\n" + 44 "which is NOT marked testonly can't depend on\n" +
46 to->label().GetUserVisibleName(false) + "\n" 45 to->label().GetUserVisibleName(false) + "\n"
47 "which is marked testonly. Only targets with \"testonly = true\"\n" 46 "which is marked testonly. Only targets with \"testonly = true\"\n"
48 "can depend on other test-only targets.\n" 47 "can depend on other test-only targets.\n"
49 "\n" 48 "\n"
50 "Either mark it test-only or don't do this dependency."); 49 "Either mark it test-only or don't do this dependency.");
51 } 50 }
52 51
53 // Inserts the given groups dependencies, starting at the given index of the
54 // given vector. Returns the number of items inserted.
55 size_t InsertGroupDeps(LabelTargetVector* vector,
56 size_t insert_at,
57 const Target* group) {
58 const LabelTargetVector& deps = group->deps();
59 vector->insert(vector->begin() + insert_at, deps.begin(), deps.end());
60
61 // Clear the origin of each of the insertions. This marks these dependencies
62 // as internally generated.
63 for (size_t i = insert_at; i < deps.size() + insert_at; i++)
64 (*vector)[i].origin = NULL;
65
66 return deps.size();
67 }
68
69 } // namespace 52 } // namespace
70 53
71 Target::Target(const Settings* settings, const Label& label) 54 Target::Target(const Settings* settings, const Label& label)
72 : Item(settings, label), 55 : Item(settings, label),
73 output_type_(UNKNOWN), 56 output_type_(UNKNOWN),
74 all_headers_public_(true), 57 all_headers_public_(true),
75 check_includes_(true), 58 check_includes_(true),
76 complete_static_lib_(false), 59 complete_static_lib_(false),
77 testonly_(false), 60 testonly_(false),
78 hard_dep_(false), 61 hard_dep_(false),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 96 }
114 97
115 const Target* Target::AsTarget() const { 98 const Target* Target::AsTarget() const {
116 return this; 99 return this;
117 } 100 }
118 101
119 bool Target::OnResolved(Err* err) { 102 bool Target::OnResolved(Err* err) {
120 DCHECK(output_type_ != UNKNOWN); 103 DCHECK(output_type_ != UNKNOWN);
121 DCHECK(toolchain_) << "Toolchain should have been set before resolving."; 104 DCHECK(toolchain_) << "Toolchain should have been set before resolving.";
122 105
123 ExpandGroups();
124
125 // Copy our own dependent configs to the list of configs applying to us. 106 // Copy our own dependent configs to the list of configs applying to us.
126 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end()); 107 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end());
127 configs_.Append(direct_dependent_configs_.begin(), 108 configs_.Append(public_configs_.begin(), public_configs_.end());
128 direct_dependent_configs_.end());
129 109
130 // Copy our own libs and lib_dirs to the final set. This will be from our 110 // Copy our own libs and lib_dirs to the final set. This will be from our
131 // target and all of our configs. We do this specially since these must be 111 // target and all of our configs. We do this specially since these must be
132 // inherited through the dependency tree (other flags don't work this way). 112 // inherited through the dependency tree (other flags don't work this way).
133 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) { 113 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
134 const ConfigValues& cur = iter.cur(); 114 const ConfigValues& cur = iter.cur();
135 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end()); 115 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end());
136 all_libs_.append(cur.libs().begin(), cur.libs().end()); 116 all_libs_.append(cur.libs().begin(), cur.libs().end());
137 } 117 }
138 118
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 "Alas, I can not continue.", 186 "Alas, I can not continue.",
207 label().GetUserVisibleName(false).c_str(), 187 label().GetUserVisibleName(false).c_str(),
208 GetStringForOutputType(output_type_), 188 GetStringForOutputType(output_type_),
209 label().GetToolchainLabel().GetUserVisibleName(false).c_str(), 189 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
210 Toolchain::ToolTypeToName( 190 Toolchain::ToolTypeToName(
211 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str())); 191 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str()));
212 } 192 }
213 return false; 193 return false;
214 } 194 }
215 195
216 void Target::ExpandGroups() {
217 // Convert any groups we depend on to just direct dependencies on that
218 // group's deps. We insert the new deps immediately after the group so that
219 // the ordering is preserved. We need to keep the original group so that any
220 // flags, etc. that it specifies itself are applied to us.
221 // TODO(brettw) bug 403488 this should also handle datadeps.
222 for (size_t i = 0; i < deps_.size(); i++) {
223 const Target* dep = deps_[i].ptr;
224 if (dep->output_type_ == GROUP)
225 i += InsertGroupDeps(&deps_, i + 1, dep);
226 }
227 }
228
229 void Target::PullDependentTargetInfo() { 196 void Target::PullDependentTargetInfo() {
230 // Gather info from our dependents we need. 197 // Gather info from our dependents we need.
231 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { 198 for (DepsIterator iter(this, DepsIterator::LINKED_ONLY); !iter.done();
232 const Target* dep = deps_[dep_i].ptr; 199 iter.Advance()) {
200 const Target* dep = iter.target();
233 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_); 201 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_);
234 MergeDirectDependentConfigsFrom(dep, &configs_); 202 MergePublicConfigsFrom(dep, &configs_);
235 203
236 // Direct dependent libraries. 204 // Direct dependent libraries.
237 if (dep->output_type() == STATIC_LIBRARY || 205 if (dep->output_type() == STATIC_LIBRARY ||
238 dep->output_type() == SHARED_LIBRARY || 206 dep->output_type() == SHARED_LIBRARY ||
239 dep->output_type() == SOURCE_SET) 207 dep->output_type() == SOURCE_SET)
240 inherited_libraries_.push_back(dep); 208 inherited_libraries_.push_back(dep);
241 209
242 // Inherited libraries and flags are inherited across static library 210 // Inherited libraries and flags are inherited across static library
243 // boundaries. 211 // boundaries.
244 if (!dep->IsFinal()) { 212 if (!dep->IsFinal()) {
245 inherited_libraries_.Append(dep->inherited_libraries().begin(), 213 inherited_libraries_.Append(dep->inherited_libraries().begin(),
246 dep->inherited_libraries().end()); 214 dep->inherited_libraries().end());
247 215
248 // Inherited library settings. 216 // Inherited library settings.
249 all_lib_dirs_.append(dep->all_lib_dirs()); 217 all_lib_dirs_.append(dep->all_lib_dirs());
250 all_libs_.append(dep->all_libs()); 218 all_libs_.append(dep->all_libs());
251 } 219 }
252 } 220 }
253 } 221 }
254 222
255 void Target::PullForwardedDependentConfigs() { 223 void Target::PullForwardedDependentConfigs() {
256 // Groups implicitly forward all if its dependency's configs. 224 // Pull public configs from each of our dependency's public deps.
257 if (output_type() == GROUP) { 225 for (size_t dep = 0; dep < public_deps_.size(); dep++)
258 for (size_t i = 0; i < deps_.size(); i++) 226 PullForwardedDependentConfigsFrom(public_deps_[dep].ptr);
259 forward_dependent_configs_.push_back(deps_[i]);
260 }
261 227
262 // Forward direct dependent configs if requested. 228 // Forward public configs if explicitly requested.
263 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) { 229 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) {
264 const Target* from_target = forward_dependent_configs_[dep].ptr; 230 const Target* from_target = forward_dependent_configs_[dep].ptr;
265 231
266 // The forward_dependent_configs_ must be in the deps already, so we 232 // The forward_dependent_configs_ must be in the deps (public or private)
267 // don't need to bother copying to our configs, only forwarding. 233 // already, so we don't need to bother copying to our configs, only
268 DCHECK(std::find_if(deps_.begin(), deps_.end(), 234 // forwarding.
235 DCHECK(std::find_if(private_deps_.begin(), private_deps_.end(),
269 LabelPtrPtrEquals<Target>(from_target)) != 236 LabelPtrPtrEquals<Target>(from_target)) !=
270 deps_.end()); 237 private_deps_.end() ||
271 direct_dependent_configs_.Append( 238 std::find_if(public_deps_.begin(), public_deps_.end(),
272 from_target->direct_dependent_configs().begin(), 239 LabelPtrPtrEquals<Target>(from_target)) !=
273 from_target->direct_dependent_configs().end()); 240 public_deps_.end());
241
242 PullForwardedDependentConfigsFrom(from_target);
274 } 243 }
275 } 244 }
276 245
246 void Target::PullForwardedDependentConfigsFrom(const Target* from) {
247 public_configs_.Append(from->public_configs().begin(),
248 from->public_configs().end());
249 }
250
277 void Target::PullRecursiveHardDeps() { 251 void Target::PullRecursiveHardDeps() {
278 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { 252 for (DepsIterator iter(this, DepsIterator::LINKED_ONLY); !iter.done();
279 const Target* dep = deps_[dep_i].ptr; 253 iter.Advance()) {
280 if (dep->hard_dep()) 254 if (iter.target()->hard_dep())
281 recursive_hard_deps_.insert(dep); 255 recursive_hard_deps_.insert(iter.target());
282 256
283 // Android STL doesn't like insert(begin, end) so do it manually. 257 // Android STL doesn't like insert(begin, end) so do it manually.
284 // TODO(brettw) this can be changed to insert(dep->begin(), dep->end()) when 258 // TODO(brettw) this can be changed to
285 // Android uses a better STL. 259 // insert(iter.target()->begin(), iter.target()->end())
260 // when Android uses a better STL.
286 for (std::set<const Target*>::const_iterator cur = 261 for (std::set<const Target*>::const_iterator cur =
287 dep->recursive_hard_deps().begin(); 262 iter.target()->recursive_hard_deps().begin();
288 cur != dep->recursive_hard_deps().end(); ++cur) 263 cur != iter.target()->recursive_hard_deps().end(); ++cur)
289 recursive_hard_deps_.insert(*cur); 264 recursive_hard_deps_.insert(*cur);
290 } 265 }
291 } 266 }
292 267
293 void Target::FillOutputFiles() { 268 void Target::FillOutputFiles() {
294 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this); 269 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
295 switch (output_type_) { 270 switch (output_type_) {
296 case GROUP: 271 case GROUP:
297 case SOURCE_SET: 272 case SOURCE_SET:
298 case COPY_FILES: 273 case COPY_FILES:
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 } 318 }
344 } 319 }
345 break; 320 break;
346 case UNKNOWN: 321 case UNKNOWN:
347 default: 322 default:
348 NOTREACHED(); 323 NOTREACHED();
349 } 324 }
350 } 325 }
351 326
352 bool Target::CheckVisibility(Err* err) const { 327 bool Target::CheckVisibility(Err* err) const {
353 // Only check visibility when the origin of the dependency is non-null. These 328 for (DepsIterator iter(this); !iter.done(); iter.Advance()) {
354 // are dependencies added by the GN files. Internally added dependencies 329 if (!Visibility::CheckItemVisibility(this, iter.target(), err))
355 // (expanded groups) will have a null origin. We don't want to check
356 // visibility for these, since the point of a group would often be to
357 // forward visibility.
358 for (size_t i = 0; i < deps_.size(); i++) {
359 if (deps_[i].origin &&
360 !Visibility::CheckItemVisibility(this, deps_[i].ptr, err))
361 return false; 330 return false;
362 } 331 }
363
364 for (size_t i = 0; i < datadeps_.size(); i++) {
365 if (deps_[i].origin &&
366 !Visibility::CheckItemVisibility(this, datadeps_[i].ptr, err))
367 return false;
368 }
369
370 return true; 332 return true;
371 } 333 }
372 334
373 bool Target::CheckTestonly(Err* err) const { 335 bool Target::CheckTestonly(Err* err) const {
374 // If there current target is marked testonly, it can include both testonly 336 // If there current target is marked testonly, it can include both testonly
375 // and non-testonly targets, so there's nothing to check. 337 // and non-testonly targets, so there's nothing to check.
376 if (testonly()) 338 if (testonly())
377 return true; 339 return true;
378 340
379 // Verify no deps have "testonly" set. 341 // Verify no deps have "testonly" set.
380 for (size_t i = 0; i < deps_.size(); i++) { 342 for (DepsIterator iter(this); !iter.done(); iter.Advance()) {
381 if (deps_[i].ptr->testonly()) { 343 if (iter.target()->testonly()) {
382 *err = MakeTestOnlyError(this, deps_[i].ptr); 344 *err = MakeTestOnlyError(this, iter.target());
383 return false;
384 }
385 }
386
387 for (size_t i = 0; i < datadeps_.size(); i++) {
388 if (datadeps_[i].ptr->testonly()) {
389 *err = MakeTestOnlyError(this, datadeps_[i].ptr);
390 return false; 345 return false;
391 } 346 }
392 } 347 }
393 348
394 return true; 349 return true;
395 } 350 }
351
352
353 DepsIterator::DepsIterator(const Target* t) : current_index_(0) {
jamesr 2014/09/16 20:09:24 odd indentation
354 vect_stack_[0] = &t->public_deps();
355 vect_stack_[1] = &t->private_deps();
356 vect_stack_[2] = &t->data_deps();
357
358 if (vect_stack_[0]->empty())
359 Advance();
360 }
361
362 // Iterate over the public and private linked deps, but not the data deps.
363 DepsIterator::DepsIterator(const Target* t, LinkedOnly) : current_index_(0) {
364 vect_stack_[0] = &t->public_deps();
365 vect_stack_[1] = &t->private_deps();
366 vect_stack_[2] = NULL;
367
368 if (vect_stack_[0]->empty())
369 Advance();
370 }
371
372 // Advance to the next position. This assumes there are more vectors.
373 //
374 // For internal use, this function tolerates an initial index equal to the
375 // length of the current vector. In this case, it will advance to the next
376 // one.
377 void DepsIterator::Advance() {
378 DCHECK(vect_stack_[0]);
379
380 current_index_++;
381 if (current_index_ >= vect_stack_[0]->size()) {
382 // Advance to next vect. Shift the elements left by one.
383 vect_stack_[0] = vect_stack_[1];
384 vect_stack_[1] = vect_stack_[2];
385 vect_stack_[2] = NULL;
386
387 current_index_ = 0;
388
389 if (vect_stack_[0] && vect_stack_[0]->empty())
390 Advance();
391 }
392 }
OLDNEW
« tools/gn/target.h ('K') | « tools/gn/target.h ('k') | tools/gn/target_generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698