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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 for (const auto& pair : target->private_deps()) { | 122 for (const auto& pair : target->private_deps()) { |
123 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, | 123 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, |
124 consider_object_files, | 124 consider_object_files, |
125 seen_targets)) | 125 seen_targets)) |
126 return true; // Found a path. | 126 return true; // Found a path. |
127 } | 127 } |
128 } | 128 } |
129 return false; | 129 return false; |
130 } | 130 } |
131 | 131 |
| 132 // check_this indicates if the given target should be matched against the |
| 133 // patterns. It should be set to false for the first call since assert_no_deps |
| 134 // shouldn't match the target itself. |
| 135 // |
| 136 // visited should point to an empty set, this will be used to prevent |
| 137 // multiple visits. |
| 138 // |
| 139 // *failure_path_str will be filled with a string describing the path of the |
| 140 // dependency failure, and failure_pattern will indicate the pattern in |
| 141 // assert_no that matched the target. |
| 142 // |
| 143 // Returns true if everything is OK. failure_path_str and failure_pattern_index |
| 144 // will be unchanged in this case. |
| 145 bool RecursiveCheckAssertNoDeps(const Target* target, |
| 146 bool check_this, |
| 147 const std::vector<LabelPattern>& assert_no, |
| 148 std::set<const Target*>* visited, |
| 149 std::string* failure_path_str, |
| 150 const LabelPattern** failure_pattern) { |
| 151 static const char kIndentPath[] = " "; |
| 152 |
| 153 if (visited->find(target) != visited->end()) |
| 154 return true; // Already checked this target. |
| 155 visited->insert(target); |
| 156 |
| 157 if (check_this) { |
| 158 // Check this target against the given list of patterns. |
| 159 for (const LabelPattern& pattern : assert_no) { |
| 160 if (pattern.Matches(target->label())) { |
| 161 // Found a match. |
| 162 *failure_pattern = &pattern; |
| 163 *failure_path_str = |
| 164 kIndentPath + target->label().GetUserVisibleName(false); |
| 165 return false; |
| 166 } |
| 167 } |
| 168 } |
| 169 |
| 170 // Recursively check dependencies. |
| 171 for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) { |
| 172 if (pair.ptr->output_type() == Target::EXECUTABLE) |
| 173 continue; |
| 174 if (!RecursiveCheckAssertNoDeps(pair.ptr, true, assert_no, visited, |
| 175 failure_path_str, failure_pattern)) { |
| 176 // To reconstruct the path, prepend the current target to the error. |
| 177 std::string prepend_path = |
| 178 kIndentPath + target->label().GetUserVisibleName(false) + " ->\n"; |
| 179 failure_path_str->insert(0, prepend_path); |
| 180 return false; |
| 181 } |
| 182 } |
| 183 |
| 184 return true; |
| 185 } |
| 186 |
132 } // namespace | 187 } // namespace |
133 | 188 |
134 Target::Target(const Settings* settings, const Label& label) | 189 Target::Target(const Settings* settings, const Label& label) |
135 : Item(settings, label), | 190 : Item(settings, label), |
136 output_type_(UNKNOWN), | 191 output_type_(UNKNOWN), |
137 all_headers_public_(true), | 192 all_headers_public_(true), |
138 check_includes_(true), | 193 check_includes_(true), |
139 complete_static_lib_(false), | 194 complete_static_lib_(false), |
140 testonly_(false), | 195 testonly_(false), |
141 toolchain_(nullptr) { | 196 toolchain_(nullptr) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 282 |
228 FillOutputFiles(); | 283 FillOutputFiles(); |
229 | 284 |
230 if (settings()->build_settings()->check_for_bad_items()) { | 285 if (settings()->build_settings()->check_for_bad_items()) { |
231 if (!CheckVisibility(err)) | 286 if (!CheckVisibility(err)) |
232 return false; | 287 return false; |
233 if (!CheckTestonly(err)) | 288 if (!CheckTestonly(err)) |
234 return false; | 289 return false; |
235 if (!CheckNoNestedStaticLibs(err)) | 290 if (!CheckNoNestedStaticLibs(err)) |
236 return false; | 291 return false; |
| 292 if (!CheckAssertNoDeps(err)) |
| 293 return false; |
237 CheckSourcesGenerated(); | 294 CheckSourcesGenerated(); |
238 } | 295 } |
239 | 296 |
240 return true; | 297 return true; |
241 } | 298 } |
242 | 299 |
243 bool Target::IsBinary() const { | 300 bool Target::IsBinary() const { |
244 return output_type_ == EXECUTABLE || | 301 return output_type_ == EXECUTABLE || |
245 output_type_ == SHARED_LIBRARY || | 302 output_type_ == SHARED_LIBRARY || |
246 output_type_ == LOADABLE_MODULE || | 303 output_type_ == LOADABLE_MODULE || |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 // Verify no inherited libraries are static libraries. | 654 // Verify no inherited libraries are static libraries. |
598 for (const auto& lib : inherited_libraries().GetOrdered()) { | 655 for (const auto& lib : inherited_libraries().GetOrdered()) { |
599 if (lib->output_type() == Target::STATIC_LIBRARY) { | 656 if (lib->output_type() == Target::STATIC_LIBRARY) { |
600 *err = MakeStaticLibDepsError(this, lib); | 657 *err = MakeStaticLibDepsError(this, lib); |
601 return false; | 658 return false; |
602 } | 659 } |
603 } | 660 } |
604 return true; | 661 return true; |
605 } | 662 } |
606 | 663 |
| 664 bool Target::CheckAssertNoDeps(Err* err) const { |
| 665 if (assert_no_deps_.empty()) |
| 666 return true; |
| 667 |
| 668 std::set<const Target*> visited; |
| 669 std::string failure_path_str; |
| 670 const LabelPattern* failure_pattern = nullptr; |
| 671 |
| 672 if (!RecursiveCheckAssertNoDeps(this, false, assert_no_deps_, &visited, |
| 673 &failure_path_str, &failure_pattern)) { |
| 674 *err = Err(defined_from(), "assert_no_deps failed.", |
| 675 label().GetUserVisibleName(false) + |
| 676 " has an assert_no_deps entry:\n " + |
| 677 failure_pattern->Describe() + |
| 678 "\nwhich fails for the dependency path:\n" + |
| 679 failure_path_str); |
| 680 return false; |
| 681 } |
| 682 return true; |
| 683 } |
| 684 |
607 void Target::CheckSourcesGenerated() const { | 685 void Target::CheckSourcesGenerated() const { |
608 // Checks that any inputs or sources to this target that are in the build | 686 // Checks that any inputs or sources to this target that are in the build |
609 // directory are generated by a target that this one transitively depends on | 687 // directory are generated by a target that this one transitively depends on |
610 // in some way. We already guarantee that all generated files are written | 688 // in some way. We already guarantee that all generated files are written |
611 // to the build dir. | 689 // to the build dir. |
612 // | 690 // |
613 // See Scheduler::AddUnknownGeneratedInput's declaration for more. | 691 // See Scheduler::AddUnknownGeneratedInput's declaration for more. |
614 for (const SourceFile& file : sources_) | 692 for (const SourceFile& file : sources_) |
615 CheckSourceGenerated(file); | 693 CheckSourceGenerated(file); |
616 for (const SourceFile& file : inputs_) | 694 for (const SourceFile& file : inputs_) |
(...skipping 15 matching lines...) Expand all Loading... |
632 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, false, | 710 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, false, |
633 &seen_targets)) { | 711 &seen_targets)) { |
634 // Check object files (much slower and very rare) only if the "normal" | 712 // Check object files (much slower and very rare) only if the "normal" |
635 // output check failed. | 713 // output check failed. |
636 seen_targets.clear(); | 714 seen_targets.clear(); |
637 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, true, | 715 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, true, |
638 &seen_targets)) | 716 &seen_targets)) |
639 g_scheduler->AddUnknownGeneratedInput(this, source); | 717 g_scheduler->AddUnknownGeneratedInput(this, source); |
640 } | 718 } |
641 } | 719 } |
OLD | NEW |