OLD | NEW |
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/deps_iterator.h" |
11 #include "tools/gn/filesystem_utils.h" | 12 #include "tools/gn/filesystem_utils.h" |
12 #include "tools/gn/scheduler.h" | 13 #include "tools/gn/scheduler.h" |
13 #include "tools/gn/substitution_writer.h" | 14 #include "tools/gn/substitution_writer.h" |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 typedef std::set<const Config*> ConfigSet; | 18 typedef std::set<const Config*> ConfigSet; |
18 | 19 |
19 // Merges the dependent configs from the given target to the given config list. | 20 // Merges the public configs from the given target to the given config list. |
20 void MergeDirectDependentConfigsFrom(const Target* from_target, | 21 void MergePublicConfigsFrom(const Target* from_target, |
21 UniqueVector<LabelConfigPair>* dest) { | 22 UniqueVector<LabelConfigPair>* dest) { |
22 const UniqueVector<LabelConfigPair>& direct = | 23 const UniqueVector<LabelConfigPair>& pub = from_target->public_configs(); |
23 from_target->direct_dependent_configs(); | 24 for (size_t i = 0; i < pub.size(); i++) |
24 for (size_t i = 0; i < direct.size(); i++) | 25 dest->push_back(pub[i]); |
25 dest->push_back(direct[i]); | |
26 } | 26 } |
27 | 27 |
28 // Like MergeDirectDependentConfigsFrom above except does the "all dependent" | 28 // Like MergePublicConfigsFrom above except does the "all dependent" ones. This |
29 // ones. This additionally adds all configs to the all_dependent_configs_ of | 29 // additionally adds all configs to the all_dependent_configs_ of the dest |
30 // the dest target given in *all_dest. | 30 // target given in *all_dest. |
31 void MergeAllDependentConfigsFrom(const Target* from_target, | 31 void MergeAllDependentConfigsFrom(const Target* from_target, |
32 UniqueVector<LabelConfigPair>* dest, | 32 UniqueVector<LabelConfigPair>* dest, |
33 UniqueVector<LabelConfigPair>* all_dest) { | 33 UniqueVector<LabelConfigPair>* all_dest) { |
34 const UniqueVector<LabelConfigPair>& all = | 34 const UniqueVector<LabelConfigPair>& all = |
35 from_target->all_dependent_configs(); | 35 from_target->all_dependent_configs(); |
36 for (size_t i = 0; i < all.size(); i++) { | 36 for (size_t i = 0; i < all.size(); i++) { |
37 all_dest->push_back(all[i]); | 37 all_dest->push_back(all[i]); |
38 dest->push_back(all[i]); | 38 dest->push_back(all[i]); |
39 } | 39 } |
40 } | 40 } |
41 | 41 |
42 Err MakeTestOnlyError(const Target* from, const Target* to) { | 42 Err MakeTestOnlyError(const Target* from, const Target* to) { |
43 return Err(from->defined_from(), "Test-only dependency not allowed.", | 43 return Err(from->defined_from(), "Test-only dependency not allowed.", |
44 from->label().GetUserVisibleName(false) + "\n" | 44 from->label().GetUserVisibleName(false) + "\n" |
45 "which is NOT marked testonly can't depend on\n" + | 45 "which is NOT marked testonly can't depend on\n" + |
46 to->label().GetUserVisibleName(false) + "\n" | 46 to->label().GetUserVisibleName(false) + "\n" |
47 "which is marked testonly. Only targets with \"testonly = true\"\n" | 47 "which is marked testonly. Only targets with \"testonly = true\"\n" |
48 "can depend on other test-only targets.\n" | 48 "can depend on other test-only targets.\n" |
49 "\n" | 49 "\n" |
50 "Either mark it test-only or don't do this dependency."); | 50 "Either mark it test-only or don't do this dependency."); |
51 } | 51 } |
52 | 52 |
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 | 53 } // namespace |
70 | 54 |
71 Target::Target(const Settings* settings, const Label& label) | 55 Target::Target(const Settings* settings, const Label& label) |
72 : Item(settings, label), | 56 : Item(settings, label), |
73 output_type_(UNKNOWN), | 57 output_type_(UNKNOWN), |
74 all_headers_public_(true), | 58 all_headers_public_(true), |
75 check_includes_(true), | 59 check_includes_(true), |
76 complete_static_lib_(false), | 60 complete_static_lib_(false), |
77 testonly_(false), | 61 testonly_(false), |
78 hard_dep_(false), | 62 hard_dep_(false), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 } | 97 } |
114 | 98 |
115 const Target* Target::AsTarget() const { | 99 const Target* Target::AsTarget() const { |
116 return this; | 100 return this; |
117 } | 101 } |
118 | 102 |
119 bool Target::OnResolved(Err* err) { | 103 bool Target::OnResolved(Err* err) { |
120 DCHECK(output_type_ != UNKNOWN); | 104 DCHECK(output_type_ != UNKNOWN); |
121 DCHECK(toolchain_) << "Toolchain should have been set before resolving."; | 105 DCHECK(toolchain_) << "Toolchain should have been set before resolving."; |
122 | 106 |
123 ExpandGroups(); | |
124 | |
125 // Copy our own dependent configs to the list of configs applying to us. | 107 // Copy our own dependent configs to the list of configs applying to us. |
126 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end()); | 108 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end()); |
127 configs_.Append(direct_dependent_configs_.begin(), | 109 configs_.Append(public_configs_.begin(), public_configs_.end()); |
128 direct_dependent_configs_.end()); | |
129 | 110 |
130 // Copy our own libs and lib_dirs to the final set. This will be from our | 111 // 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 | 112 // 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). | 113 // inherited through the dependency tree (other flags don't work this way). |
133 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) { | 114 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) { |
134 const ConfigValues& cur = iter.cur(); | 115 const ConfigValues& cur = iter.cur(); |
135 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end()); | 116 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end()); |
136 all_libs_.append(cur.libs().begin(), cur.libs().end()); | 117 all_libs_.append(cur.libs().begin(), cur.libs().end()); |
137 } | 118 } |
138 | 119 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 "Alas, I can not continue.", | 187 "Alas, I can not continue.", |
207 label().GetUserVisibleName(false).c_str(), | 188 label().GetUserVisibleName(false).c_str(), |
208 GetStringForOutputType(output_type_), | 189 GetStringForOutputType(output_type_), |
209 label().GetToolchainLabel().GetUserVisibleName(false).c_str(), | 190 label().GetToolchainLabel().GetUserVisibleName(false).c_str(), |
210 Toolchain::ToolTypeToName( | 191 Toolchain::ToolTypeToName( |
211 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str())); | 192 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str())); |
212 } | 193 } |
213 return false; | 194 return false; |
214 } | 195 } |
215 | 196 |
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() { | 197 void Target::PullDependentTargetInfo() { |
230 // Gather info from our dependents we need. | 198 // Gather info from our dependents we need. |
231 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { | 199 for (DepsIterator iter(this, DepsIterator::LINKED_ONLY); !iter.done(); |
232 const Target* dep = deps_[dep_i].ptr; | 200 iter.Advance()) { |
| 201 const Target* dep = iter.target(); |
233 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_); | 202 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_); |
234 MergeDirectDependentConfigsFrom(dep, &configs_); | 203 MergePublicConfigsFrom(dep, &configs_); |
235 | 204 |
236 // Direct dependent libraries. | 205 // Direct dependent libraries. |
237 if (dep->output_type() == STATIC_LIBRARY || | 206 if (dep->output_type() == STATIC_LIBRARY || |
238 dep->output_type() == SHARED_LIBRARY || | 207 dep->output_type() == SHARED_LIBRARY || |
239 dep->output_type() == SOURCE_SET) | 208 dep->output_type() == SOURCE_SET) |
240 inherited_libraries_.push_back(dep); | 209 inherited_libraries_.push_back(dep); |
241 | 210 |
242 // Inherited libraries and flags are inherited across static library | 211 // Inherited libraries and flags are inherited across static library |
243 // boundaries. | 212 // boundaries. |
244 if (!dep->IsFinal()) { | 213 if (!dep->IsFinal()) { |
245 inherited_libraries_.Append(dep->inherited_libraries().begin(), | 214 inherited_libraries_.Append(dep->inherited_libraries().begin(), |
246 dep->inherited_libraries().end()); | 215 dep->inherited_libraries().end()); |
247 | 216 |
248 // Inherited library settings. | 217 // Inherited library settings. |
249 all_lib_dirs_.append(dep->all_lib_dirs()); | 218 all_lib_dirs_.append(dep->all_lib_dirs()); |
250 all_libs_.append(dep->all_libs()); | 219 all_libs_.append(dep->all_libs()); |
251 } | 220 } |
252 } | 221 } |
253 } | 222 } |
254 | 223 |
255 void Target::PullForwardedDependentConfigs() { | 224 void Target::PullForwardedDependentConfigs() { |
256 // Groups implicitly forward all if its dependency's configs. | 225 // Pull public configs from each of our dependency's public deps. |
257 if (output_type() == GROUP) { | 226 for (size_t dep = 0; dep < public_deps_.size(); dep++) |
258 for (size_t i = 0; i < deps_.size(); i++) | 227 PullForwardedDependentConfigsFrom(public_deps_[dep].ptr); |
259 forward_dependent_configs_.push_back(deps_[i]); | |
260 } | |
261 | 228 |
262 // Forward direct dependent configs if requested. | 229 // Forward public configs if explicitly requested. |
263 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) { | 230 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) { |
264 const Target* from_target = forward_dependent_configs_[dep].ptr; | 231 const Target* from_target = forward_dependent_configs_[dep].ptr; |
265 | 232 |
266 // The forward_dependent_configs_ must be in the deps already, so we | 233 // The forward_dependent_configs_ must be in the deps (public or private) |
267 // don't need to bother copying to our configs, only forwarding. | 234 // already, so we don't need to bother copying to our configs, only |
268 DCHECK(std::find_if(deps_.begin(), deps_.end(), | 235 // forwarding. |
| 236 DCHECK(std::find_if(private_deps_.begin(), private_deps_.end(), |
269 LabelPtrPtrEquals<Target>(from_target)) != | 237 LabelPtrPtrEquals<Target>(from_target)) != |
270 deps_.end()); | 238 private_deps_.end() || |
271 direct_dependent_configs_.Append( | 239 std::find_if(public_deps_.begin(), public_deps_.end(), |
272 from_target->direct_dependent_configs().begin(), | 240 LabelPtrPtrEquals<Target>(from_target)) != |
273 from_target->direct_dependent_configs().end()); | 241 public_deps_.end()); |
| 242 |
| 243 PullForwardedDependentConfigsFrom(from_target); |
274 } | 244 } |
275 } | 245 } |
276 | 246 |
| 247 void Target::PullForwardedDependentConfigsFrom(const Target* from) { |
| 248 public_configs_.Append(from->public_configs().begin(), |
| 249 from->public_configs().end()); |
| 250 } |
| 251 |
277 void Target::PullRecursiveHardDeps() { | 252 void Target::PullRecursiveHardDeps() { |
278 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { | 253 for (DepsIterator iter(this, DepsIterator::LINKED_ONLY); !iter.done(); |
279 const Target* dep = deps_[dep_i].ptr; | 254 iter.Advance()) { |
280 if (dep->hard_dep()) | 255 if (iter.target()->hard_dep()) |
281 recursive_hard_deps_.insert(dep); | 256 recursive_hard_deps_.insert(iter.target()); |
282 | 257 |
283 // Android STL doesn't like insert(begin, end) so do it manually. | 258 // 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 | 259 // TODO(brettw) this can be changed to |
285 // Android uses a better STL. | 260 // insert(iter.target()->begin(), iter.target()->end()) |
| 261 // when Android uses a better STL. |
286 for (std::set<const Target*>::const_iterator cur = | 262 for (std::set<const Target*>::const_iterator cur = |
287 dep->recursive_hard_deps().begin(); | 263 iter.target()->recursive_hard_deps().begin(); |
288 cur != dep->recursive_hard_deps().end(); ++cur) | 264 cur != iter.target()->recursive_hard_deps().end(); ++cur) |
289 recursive_hard_deps_.insert(*cur); | 265 recursive_hard_deps_.insert(*cur); |
290 } | 266 } |
291 } | 267 } |
292 | 268 |
293 void Target::FillOutputFiles() { | 269 void Target::FillOutputFiles() { |
294 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this); | 270 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this); |
295 switch (output_type_) { | 271 switch (output_type_) { |
296 case GROUP: | 272 case GROUP: |
297 case SOURCE_SET: | 273 case SOURCE_SET: |
298 case COPY_FILES: | 274 case COPY_FILES: |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 } | 319 } |
344 } | 320 } |
345 break; | 321 break; |
346 case UNKNOWN: | 322 case UNKNOWN: |
347 default: | 323 default: |
348 NOTREACHED(); | 324 NOTREACHED(); |
349 } | 325 } |
350 } | 326 } |
351 | 327 |
352 bool Target::CheckVisibility(Err* err) const { | 328 bool Target::CheckVisibility(Err* err) const { |
353 // Only check visibility when the origin of the dependency is non-null. These | 329 for (DepsIterator iter(this); !iter.done(); iter.Advance()) { |
354 // are dependencies added by the GN files. Internally added dependencies | 330 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; | 331 return false; |
362 } | 332 } |
363 | |
364 for (size_t i = 0; i < datadeps_.size(); i++) { | |
365 if (datadeps_[i].origin && | |
366 !Visibility::CheckItemVisibility(this, datadeps_[i].ptr, err)) | |
367 return false; | |
368 } | |
369 | |
370 return true; | 333 return true; |
371 } | 334 } |
372 | 335 |
373 bool Target::CheckTestonly(Err* err) const { | 336 bool Target::CheckTestonly(Err* err) const { |
374 // If there current target is marked testonly, it can include both testonly | 337 // If there current target is marked testonly, it can include both testonly |
375 // and non-testonly targets, so there's nothing to check. | 338 // and non-testonly targets, so there's nothing to check. |
376 if (testonly()) | 339 if (testonly()) |
377 return true; | 340 return true; |
378 | 341 |
379 // Verify no deps have "testonly" set. | 342 // Verify no deps have "testonly" set. |
380 for (size_t i = 0; i < deps_.size(); i++) { | 343 for (DepsIterator iter(this); !iter.done(); iter.Advance()) { |
381 if (deps_[i].ptr->testonly()) { | 344 if (iter.target()->testonly()) { |
382 *err = MakeTestOnlyError(this, deps_[i].ptr); | 345 *err = MakeTestOnlyError(this, iter.target()); |
383 return false; | 346 return false; |
384 } | 347 } |
385 } | 348 } |
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; | |
391 } | |
392 } | |
393 | 349 |
394 return true; | 350 return true; |
395 } | 351 } |
OLD | NEW |