| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 // to avoid duplicate checking. | 76 // to avoid duplicate checking. |
| 77 // | 77 // |
| 78 // Checking of object files is optional because it is much slower. This allows | 78 // Checking of object files is optional because it is much slower. This allows |
| 79 // us to check targets for normal outputs, and then as a second pass check | 79 // us to check targets for normal outputs, and then as a second pass check |
| 80 // object files (since we know it will be an error otherwise). This allows | 80 // object files (since we know it will be an error otherwise). This allows |
| 81 // us to avoid computing all object file names in the common case. | 81 // us to avoid computing all object file names in the common case. |
| 82 bool EnsureFileIsGeneratedByDependency(const Target* target, | 82 bool EnsureFileIsGeneratedByDependency(const Target* target, |
| 83 const OutputFile& file, | 83 const OutputFile& file, |
| 84 bool check_private_deps, | 84 bool check_private_deps, |
| 85 bool consider_object_files, | 85 bool consider_object_files, |
| 86 bool check_data_deps, |
| 86 std::set<const Target*>* seen_targets) { | 87 std::set<const Target*>* seen_targets) { |
| 87 if (seen_targets->find(target) != seen_targets->end()) | 88 if (seen_targets->find(target) != seen_targets->end()) |
| 88 return false; // Already checked this one and it's not found. | 89 return false; // Already checked this one and it's not found. |
| 89 seen_targets->insert(target); | 90 seen_targets->insert(target); |
| 90 | 91 |
| 91 // Assume that we have relatively few generated inputs so brute-force | 92 // Assume that we have relatively few generated inputs so brute-force |
| 92 // searching here is OK. If this becomes a bottleneck, consider storing | 93 // searching here is OK. If this becomes a bottleneck, consider storing |
| 93 // computed_outputs as a hash set. | 94 // computed_outputs as a hash set. |
| 94 for (const OutputFile& cur : target->computed_outputs()) { | 95 for (const OutputFile& cur : target->computed_outputs()) { |
| 95 if (file == cur) | 96 if (file == cur) |
| 96 return true; | 97 return true; |
| 97 } | 98 } |
| 98 | 99 |
| 100 if (file == target->write_runtime_deps_output()) |
| 101 return true; |
| 102 |
| 99 // Check binary target intermediate files if requested. | 103 // Check binary target intermediate files if requested. |
| 100 if (consider_object_files && target->IsBinary()) { | 104 if (consider_object_files && target->IsBinary()) { |
| 101 std::vector<OutputFile> source_outputs; | 105 std::vector<OutputFile> source_outputs; |
| 102 for (const SourceFile& source : target->sources()) { | 106 for (const SourceFile& source : target->sources()) { |
| 103 Toolchain::ToolType tool_type; | 107 Toolchain::ToolType tool_type; |
| 104 if (!target->GetOutputFilesForSource(source, &tool_type, &source_outputs)) | 108 if (!target->GetOutputFilesForSource(source, &tool_type, &source_outputs)) |
| 105 continue; | 109 continue; |
| 106 if (std::find(source_outputs.begin(), source_outputs.end(), file) != | 110 if (std::find(source_outputs.begin(), source_outputs.end(), file) != |
| 107 source_outputs.end()) | 111 source_outputs.end()) |
| 108 return true; | 112 return true; |
| 109 } | 113 } |
| 110 } | 114 } |
| 111 | 115 |
| 116 if (check_data_deps) { |
| 117 check_data_deps = false; // Consider only direct data_deps. |
| 118 for (const auto& pair : target->data_deps()) { |
| 119 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, |
| 120 consider_object_files, |
| 121 check_data_deps, seen_targets)) |
| 122 return true; // Found a path. |
| 123 } |
| 124 } |
| 125 |
| 112 // Check all public dependencies (don't do data ones since those are | 126 // Check all public dependencies (don't do data ones since those are |
| 113 // runtime-only). | 127 // runtime-only). |
| 114 for (const auto& pair : target->public_deps()) { | 128 for (const auto& pair : target->public_deps()) { |
| 115 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, | 129 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, |
| 116 consider_object_files, seen_targets)) | 130 consider_object_files, |
| 131 check_data_deps, seen_targets)) |
| 117 return true; // Found a path. | 132 return true; // Found a path. |
| 118 } | 133 } |
| 119 | 134 |
| 120 // Only check private deps if requested. | 135 // Only check private deps if requested. |
| 121 if (check_private_deps) { | 136 if (check_private_deps) { |
| 122 for (const auto& pair : target->private_deps()) { | 137 for (const auto& pair : target->private_deps()) { |
| 123 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, | 138 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, |
| 124 consider_object_files, | 139 consider_object_files, |
| 125 seen_targets)) | 140 check_data_deps, seen_targets)) |
| 126 return true; // Found a path. | 141 return true; // Found a path. |
| 127 } | 142 } |
| 128 if (target->output_type() == Target::CREATE_BUNDLE) { | 143 if (target->output_type() == Target::CREATE_BUNDLE) { |
| 129 for (const auto& dep : target->bundle_data().bundle_deps()) { | 144 for (const auto& dep : target->bundle_data().bundle_deps()) { |
| 130 if (EnsureFileIsGeneratedByDependency(dep, file, false, | 145 if (EnsureFileIsGeneratedByDependency(dep, file, false, |
| 131 consider_object_files, | 146 consider_object_files, |
| 132 seen_targets)) | 147 check_data_deps, seen_targets)) |
| 133 return true; // Found a path. | 148 return true; // Found a path. |
| 134 } | 149 } |
| 135 } | 150 } |
| 136 } | 151 } |
| 137 return false; | 152 return false; |
| 138 } | 153 } |
| 139 | 154 |
| 140 // check_this indicates if the given target should be matched against the | 155 // check_this indicates if the given target should be matched against the |
| 141 // patterns. It should be set to false for the first call since assert_no_deps | 156 // patterns. It should be set to false for the first call since assert_no_deps |
| 142 // shouldn't match the target itself. | 157 // shouldn't match the target itself. |
| (...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 void Target::CheckSourceGenerated(const SourceFile& source) const { | 760 void Target::CheckSourceGenerated(const SourceFile& source) const { |
| 746 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(), | 761 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(), |
| 747 source.value())) | 762 source.value())) |
| 748 return; // Not in output dir, this is OK. | 763 return; // Not in output dir, this is OK. |
| 749 | 764 |
| 750 // Tell the scheduler about unknown files. This will be noted for later so | 765 // Tell the scheduler about unknown files. This will be noted for later so |
| 751 // the list of files written by the GN build itself (often response files) | 766 // the list of files written by the GN build itself (often response files) |
| 752 // can be filtered out of this list. | 767 // can be filtered out of this list. |
| 753 OutputFile out_file(settings()->build_settings(), source); | 768 OutputFile out_file(settings()->build_settings(), source); |
| 754 std::set<const Target*> seen_targets; | 769 std::set<const Target*> seen_targets; |
| 755 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, false, | 770 bool check_data_deps = false; |
| 771 bool consider_object_files = false; |
| 772 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, |
| 773 consider_object_files, check_data_deps, |
| 756 &seen_targets)) { | 774 &seen_targets)) { |
| 775 seen_targets.clear(); |
| 776 // Allow dependency to be through data_deps for files generated by gn. |
| 777 check_data_deps = g_scheduler->IsFileGeneratedByWriteRuntimeDeps(out_file); |
| 757 // Check object files (much slower and very rare) only if the "normal" | 778 // Check object files (much slower and very rare) only if the "normal" |
| 758 // output check failed. | 779 // output check failed. |
| 759 seen_targets.clear(); | 780 consider_object_files = !check_data_deps; |
| 760 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, true, | 781 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, |
| 761 &seen_targets)) | 782 consider_object_files, |
| 783 check_data_deps, &seen_targets)) |
| 762 g_scheduler->AddUnknownGeneratedInput(this, source); | 784 g_scheduler->AddUnknownGeneratedInput(this, source); |
| 763 } | 785 } |
| 764 } | 786 } |
| OLD | NEW |