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 |