Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: tools/gn/target.cc

Issue 1607423002: Allow .o files for GN generated inputs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment fix Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/target.h ('k') | tools/gn/target_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
10
9 #include "base/bind.h" 11 #include "base/bind.h"
10 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
12 #include "tools/gn/config_values_extractors.h" 14 #include "tools/gn/config_values_extractors.h"
13 #include "tools/gn/deps_iterator.h" 15 #include "tools/gn/deps_iterator.h"
14 #include "tools/gn/filesystem_utils.h" 16 #include "tools/gn/filesystem_utils.h"
15 #include "tools/gn/scheduler.h" 17 #include "tools/gn/scheduler.h"
18 #include "tools/gn/source_file_type.h"
16 #include "tools/gn/substitution_writer.h" 19 #include "tools/gn/substitution_writer.h"
20 #include "tools/gn/tool.h"
21 #include "tools/gn/toolchain.h"
17 #include "tools/gn/trace.h" 22 #include "tools/gn/trace.h"
18 23
19 namespace { 24 namespace {
20 25
21 typedef std::set<const Config*> ConfigSet; 26 typedef std::set<const Config*> ConfigSet;
22 27
23 // Merges the public configs from the given target to the given config list. 28 // Merges the public configs from the given target to the given config list.
24 void MergePublicConfigsFrom(const Target* from_target, 29 void MergePublicConfigsFrom(const Target* from_target,
25 UniqueVector<LabelConfigPair>* dest) { 30 UniqueVector<LabelConfigPair>* dest) {
26 const UniqueVector<LabelConfigPair>& pub = from_target->public_configs(); 31 const UniqueVector<LabelConfigPair>& pub = from_target->public_configs();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 "\n" 67 "\n"
63 "Use source sets for intermediate targets instead."); 68 "Use source sets for intermediate targets instead.");
64 } 69 }
65 70
66 // Set check_private_deps to true for the first invocation since a target 71 // Set check_private_deps to true for the first invocation since a target
67 // can see all of its dependencies. For recursive invocations this will be set 72 // can see all of its dependencies. For recursive invocations this will be set
68 // to false to follow only public dependency paths. 73 // to false to follow only public dependency paths.
69 // 74 //
70 // Pass a pointer to an empty set for the first invocation. This will be used 75 // Pass a pointer to an empty set for the first invocation. This will be used
71 // to avoid duplicate checking. 76 // to avoid duplicate checking.
77 //
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
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.
72 bool EnsureFileIsGeneratedByDependency(const Target* target, 82 bool EnsureFileIsGeneratedByDependency(const Target* target,
73 const OutputFile& file, 83 const OutputFile& file,
74 bool check_private_deps, 84 bool check_private_deps,
85 bool consider_object_files,
75 std::set<const Target*>* seen_targets) { 86 std::set<const Target*>* seen_targets) {
76 if (seen_targets->find(target) != seen_targets->end()) 87 if (seen_targets->find(target) != seen_targets->end())
77 return false; // Already checked this one and it's not found. 88 return false; // Already checked this one and it's not found.
78 seen_targets->insert(target); 89 seen_targets->insert(target);
79 90
80 // Assume that we have relatively few generated inputs so brute-force 91 // Assume that we have relatively few generated inputs so brute-force
81 // searching here is OK. If this becomes a bottleneck, consider storing 92 // searching here is OK. If this becomes a bottleneck, consider storing
82 // computed_outputs as a hash set. 93 // computed_outputs as a hash set.
83 for (const OutputFile& cur : target->computed_outputs()) { 94 for (const OutputFile& cur : target->computed_outputs()) {
84 if (file == cur) 95 if (file == cur)
85 return true; 96 return true;
86 } 97 }
87 98
99 // Check binary target intermediate files if requested.
100 if (consider_object_files && target->IsBinary()) {
101 std::vector<OutputFile> source_outputs;
102 for (const SourceFile& source : target->sources()) {
103 Toolchain::ToolType tool_type;
104 if (!target->GetOutputFilesForSource(source, &tool_type, &source_outputs))
105 continue;
106 if (std::find(source_outputs.begin(), source_outputs.end(), file) !=
107 source_outputs.end())
108 return true;
109 }
110 }
111
88 // Check all public dependencies (don't do data ones since those are 112 // Check all public dependencies (don't do data ones since those are
89 // runtime-only). 113 // runtime-only).
90 for (const auto& pair : target->public_deps()) { 114 for (const auto& pair : target->public_deps()) {
91 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, 115 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
92 seen_targets)) 116 consider_object_files, seen_targets))
93 return true; // Found a path. 117 return true; // Found a path.
94 } 118 }
95 119
96 // Only check private deps if requested. 120 // Only check private deps if requested.
97 if (check_private_deps) { 121 if (check_private_deps) {
98 for (const auto& pair : target->private_deps()) { 122 for (const auto& pair : target->private_deps()) {
99 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false, 123 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
124 consider_object_files,
100 seen_targets)) 125 seen_targets))
101 return true; // Found a path. 126 return true; // Found a path.
102 } 127 }
103 } 128 }
104 return false; 129 return false;
105 } 130 }
106 131
107 } // namespace 132 } // namespace
108 133
109 Target::Target(const Settings* settings, const Label& label) 134 Target::Target(const Settings* settings, const Label& label)
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 if (!CheckTestonly(err)) 233 if (!CheckTestonly(err))
209 return false; 234 return false;
210 if (!CheckNoNestedStaticLibs(err)) 235 if (!CheckNoNestedStaticLibs(err))
211 return false; 236 return false;
212 CheckSourcesGenerated(); 237 CheckSourcesGenerated();
213 } 238 }
214 239
215 return true; 240 return true;
216 } 241 }
217 242
243 bool Target::IsBinary() const {
244 return output_type_ == EXECUTABLE ||
245 output_type_ == SHARED_LIBRARY ||
246 output_type_ == LOADABLE_MODULE ||
247 output_type_ == STATIC_LIBRARY ||
248 output_type_ == SOURCE_SET;
249 }
250
218 bool Target::IsLinkable() const { 251 bool Target::IsLinkable() const {
219 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY; 252 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY;
220 } 253 }
221 254
222 bool Target::IsFinal() const { 255 bool Target::IsFinal() const {
223 return output_type_ == EXECUTABLE || 256 return output_type_ == EXECUTABLE ||
224 output_type_ == SHARED_LIBRARY || 257 output_type_ == SHARED_LIBRARY ||
225 output_type_ == LOADABLE_MODULE || 258 output_type_ == LOADABLE_MODULE ||
226 output_type_ == ACTION || 259 output_type_ == ACTION ||
227 output_type_ == ACTION_FOREACH || 260 output_type_ == ACTION_FOREACH ||
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 "Alas, I can not continue.", 313 "Alas, I can not continue.",
281 label().GetUserVisibleName(false).c_str(), 314 label().GetUserVisibleName(false).c_str(),
282 GetStringForOutputType(output_type_), 315 GetStringForOutputType(output_type_),
283 label().GetToolchainLabel().GetUserVisibleName(false).c_str(), 316 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
284 Toolchain::ToolTypeToName( 317 Toolchain::ToolTypeToName(
285 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str())); 318 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str()));
286 } 319 }
287 return false; 320 return false;
288 } 321 }
289 322
323 bool Target::GetOutputFilesForSource(const SourceFile& source,
324 Toolchain::ToolType* computed_tool_type,
325 std::vector<OutputFile>* outputs) const {
326 outputs->clear();
327 *computed_tool_type = Toolchain::TYPE_NONE;
328
329 SourceFileType file_type = GetSourceFileType(source);
330 if (file_type == SOURCE_UNKNOWN)
331 return false;
332 if (file_type == SOURCE_O) {
333 // Object files just get passed to the output and not compiled.
334 outputs->push_back(OutputFile(settings()->build_settings(), source));
335 return true;
336 }
337
338 *computed_tool_type = toolchain_->GetToolTypeForSourceType(file_type);
339 if (*computed_tool_type == Toolchain::TYPE_NONE)
340 return false; // No tool for this file (it's a header file or something).
341 const Tool* tool = toolchain_->GetTool(*computed_tool_type);
342 if (!tool)
343 return false; // Tool does not apply for this toolchain.file.
344
345 // Figure out what output(s) this compiler produces.
346 SubstitutionWriter::ApplyListToCompilerAsOutputFile(
347 this, source, tool->outputs(), outputs);
348 return !outputs->empty();
349 }
350
290 void Target::PullDependentTargetConfigsFrom(const Target* dep) { 351 void Target::PullDependentTargetConfigsFrom(const Target* dep) {
291 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_); 352 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_);
292 MergePublicConfigsFrom(dep, &configs_); 353 MergePublicConfigsFrom(dep, &configs_);
293 } 354 }
294 355
295 void Target::PullDependentTargetConfigs() { 356 void Target::PullDependentTargetConfigs() {
296 for (const auto& pair : GetDeps(DEPS_LINKED)) 357 for (const auto& pair : GetDeps(DEPS_LINKED))
297 PullDependentTargetConfigsFrom(pair.ptr); 358 PullDependentTargetConfigsFrom(pair.ptr);
298 } 359 }
299 360
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 void Target::CheckSourceGenerated(const SourceFile& source) const { 622 void Target::CheckSourceGenerated(const SourceFile& source) const {
562 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(), 623 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(),
563 source.value())) 624 source.value()))
564 return; // Not in output dir, this is OK. 625 return; // Not in output dir, this is OK.
565 626
566 // Tell the scheduler about unknown files. This will be noted for later so 627 // Tell the scheduler about unknown files. This will be noted for later so
567 // the list of files written by the GN build itself (often response files) 628 // the list of files written by the GN build itself (often response files)
568 // can be filtered out of this list. 629 // can be filtered out of this list.
569 OutputFile out_file(settings()->build_settings(), source); 630 OutputFile out_file(settings()->build_settings(), source);
570 std::set<const Target*> seen_targets; 631 std::set<const Target*> seen_targets;
571 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, &seen_targets)) 632 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, false,
572 g_scheduler->AddUnknownGeneratedInput(this, source); 633 &seen_targets)) {
634 // Check object files (much slower and very rare) only if the "normal"
635 // output check failed.
636 seen_targets.clear();
637 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, true,
638 &seen_targets))
639 g_scheduler->AddUnknownGeneratedInput(this, source);
640 }
573 } 641 }
OLDNEW
« no previous file with comments | « tools/gn/target.h ('k') | tools/gn/target_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698