| 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 |