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
3 // found in the LICENSE file.
4
5 #include "gn/target.h"
6
7 #include <stddef.h>
8
9 #include "base/stl_util.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "gn/c_tool.h"
13 #include "gn/config_values_extractors.h"
14 #include "gn/deps_iterator.h"
15 #include "gn/filesystem_utils.h"
16 #include "gn/functions.h"
17 #include "gn/scheduler.h"
18 #include "gn/substitution_writer.h"
19 #include "gn/tool.h"
20 #include "gn/toolchain.h"
21 #include "gn/trace.h"
22
23 namespace {
24
25 using ConfigSet = std::set<const Config*>;
26
27 // Merges the public configs from the given target to the given config list.
MergePublicConfigsFrom(const Target * from_target,UniqueVector<LabelConfigPair> * dest)28 void MergePublicConfigsFrom(const Target* from_target,
29 UniqueVector<LabelConfigPair>* dest) {
30 const UniqueVector<LabelConfigPair>& pub = from_target->public_configs();
31 dest->Append(pub.begin(), pub.end());
32 }
33
34 // Like MergePublicConfigsFrom above except does the "all dependent" ones. This
35 // additionally adds all configs to the all_dependent_configs_ of the dest
36 // target given in *all_dest.
MergeAllDependentConfigsFrom(const Target * from_target,UniqueVector<LabelConfigPair> * dest,UniqueVector<LabelConfigPair> * all_dest)37 void MergeAllDependentConfigsFrom(const Target* from_target,
38 UniqueVector<LabelConfigPair>* dest,
39 UniqueVector<LabelConfigPair>* all_dest) {
40 for (const auto& pair : from_target->all_dependent_configs()) {
41 all_dest->push_back(pair);
42 dest->push_back(pair);
43 }
44 }
45
MakeTestOnlyError(const Item * from,const Item * to)46 Err MakeTestOnlyError(const Item* from, const Item* to) {
47 return Err(
48 from->defined_from(), "Test-only dependency not allowed.",
49 from->label().GetUserVisibleName(false) +
50 "\n"
51 "which is NOT marked testonly can't depend on\n" +
52 to->label().GetUserVisibleName(false) +
53 "\n"
54 "which is marked testonly. Only targets with \"testonly = true\"\n"
55 "can depend on other test-only targets.\n"
56 "\n"
57 "Either mark it test-only or don't do this dependency.");
58 }
59
60 // Set check_private_deps to true for the first invocation since a target
61 // can see all of its dependencies. For recursive invocations this will be set
62 // to false to follow only public dependency paths.
63 //
64 // Pass a pointer to an empty set for the first invocation. This will be used
65 // to avoid duplicate checking.
66 //
67 // Checking of object files is optional because it is much slower. This allows
68 // us to check targets for normal outputs, and then as a second pass check
69 // object files (since we know it will be an error otherwise). This allows
70 // us to avoid computing all object file names in the common case.
EnsureFileIsGeneratedByDependency(const Target * target,const OutputFile & file,bool check_private_deps,bool consider_object_files,bool check_data_deps,TargetSet * seen_targets)71 bool EnsureFileIsGeneratedByDependency(const Target* target,
72 const OutputFile& file,
73 bool check_private_deps,
74 bool consider_object_files,
75 bool check_data_deps,
76 TargetSet* seen_targets) {
77 if (!seen_targets->add(target))
78 return false; // Already checked this one and it's not found.
79
80 // Assume that we have relatively few generated inputs so brute-force
81 // searching here is OK. If this becomes a bottleneck, consider storing
82 // computed_outputs as a hash set.
83 for (const OutputFile& cur : target->computed_outputs()) {
84 if (file == cur)
85 return true;
86 }
87
88 if (file == target->write_runtime_deps_output())
89 return true;
90
91 // Check binary target intermediate files if requested.
92 if (consider_object_files && target->IsBinary()) {
93 std::vector<OutputFile> source_outputs;
94 for (const SourceFile& source : target->sources()) {
95 const char* tool_name;
96 if (!target->GetOutputFilesForSource(source, &tool_name, &source_outputs))
97 continue;
98 if (base::ContainsValue(source_outputs, file))
99 return true;
100 }
101 }
102
103 if (check_data_deps) {
104 check_data_deps = false; // Consider only direct data_deps.
105 for (const auto& pair : target->data_deps()) {
106 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
107 consider_object_files,
108 check_data_deps, seen_targets))
109 return true; // Found a path.
110 }
111 }
112
113 // Check all public dependencies (don't do data ones since those are
114 // runtime-only).
115 for (const auto& pair : target->public_deps()) {
116 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
117 consider_object_files,
118 check_data_deps, seen_targets))
119 return true; // Found a path.
120 }
121
122 // Only check private deps if requested.
123 if (check_private_deps) {
124 for (const auto& pair : target->private_deps()) {
125 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
126 consider_object_files,
127 check_data_deps, seen_targets))
128 return true; // Found a path.
129 }
130 if (target->output_type() == Target::CREATE_BUNDLE) {
131 for (auto* dep : target->bundle_data().bundle_deps()) {
132 if (EnsureFileIsGeneratedByDependency(dep, file, false,
133 consider_object_files,
134 check_data_deps, seen_targets))
135 return true; // Found a path.
136 }
137 }
138 }
139 return false;
140 }
141
142 // check_this indicates if the given target should be matched against the
143 // patterns. It should be set to false for the first call since assert_no_deps
144 // shouldn't match the target itself.
145 //
146 // visited should point to an empty set, this will be used to prevent
147 // multiple visits.
148 //
149 // *failure_path_str will be filled with a string describing the path of the
150 // dependency failure, and failure_pattern will indicate the pattern in
151 // assert_no that matched the target.
152 //
153 // Returns true if everything is OK. failure_path_str and failure_pattern_index
154 // will be unchanged in this case.
RecursiveCheckAssertNoDeps(const Target * target,bool check_this,const std::vector<LabelPattern> & assert_no,TargetSet * visited,std::string * failure_path_str,const LabelPattern ** failure_pattern)155 bool RecursiveCheckAssertNoDeps(const Target* target,
156 bool check_this,
157 const std::vector<LabelPattern>& assert_no,
158 TargetSet* visited,
159 std::string* failure_path_str,
160 const LabelPattern** failure_pattern) {
161 static const char kIndentPath[] = " ";
162
163 if (!visited->add(target))
164 return true; // Already checked this target.
165
166 if (check_this) {
167 // Check this target against the given list of patterns.
168 for (const LabelPattern& pattern : assert_no) {
169 if (pattern.Matches(target->label())) {
170 // Found a match.
171 *failure_pattern = &pattern;
172 *failure_path_str =
173 kIndentPath + target->label().GetUserVisibleName(false);
174 return false;
175 }
176 }
177 }
178
179 // Recursively check dependencies.
180 for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) {
181 if (pair.ptr->output_type() == Target::EXECUTABLE)
182 continue;
183 if (!RecursiveCheckAssertNoDeps(pair.ptr, true, assert_no, visited,
184 failure_path_str, failure_pattern)) {
185 // To reconstruct the path, prepend the current target to the error.
186 std::string prepend_path =
187 kIndentPath + target->label().GetUserVisibleName(false) + " ->\n";
188 failure_path_str->insert(0, prepend_path);
189 return false;
190 }
191 }
192
193 return true;
194 }
195
196 } // namespace
197
198 const char kExecution_Help[] =
199 R"(Build graph and execution overview
200
201 Overall build flow
202
203 1. Look for ".gn" file (see "gn help dotfile") in the current directory and
204 walk up the directory tree until one is found. Set this directory to be
205 the "source root" and interpret this file to find the name of the build
206 config file.
207
208 2. Execute the build config file identified by .gn to set up the global
209 variables and default toolchain name. Any arguments, variables, defaults,
210 etc. set up in this file will be visible to all files in the build.
211
212 3. Load the //BUILD.gn (in the source root directory).
213
214 4. Recursively evaluate rules and load BUILD.gn in other directories as
215 necessary to resolve dependencies. If a BUILD file isn't found in the
216 specified location, GN will look in the corresponding location inside
217 the secondary_source defined in the dotfile (see "gn help dotfile").
218
219 5. When a target's dependencies are resolved, write out the `.ninja`
220 file to disk.
221
222 6. When all targets are resolved, write out the root build.ninja file.
223
224 Note that the BUILD.gn file name may be modulated by .gn arguments such as
225 build_file_extension.
226
227 Executing target definitions and templates
228
229 Build files are loaded in parallel. This means it is impossible to
230 interrogate a target from GN code for any information not derivable from its
231 label (see "gn help label"). The exception is the get_target_outputs()
232 function which requires the target being interrogated to have been defined
233 previously in the same file.
234
235 Targets are declared by their type and given a name:
236
237 static_library("my_static_library") {
238 ... target parameter definitions ...
239 }
240
241 There is also a generic "target" function for programmatically defined types
242 (see "gn help target"). You can define new types using templates (see "gn
243 help template"). A template defines some custom code that expands to one or
244 more other targets.
245
246 Before executing the code inside the target's { }, the target defaults are
247 applied (see "gn help set_defaults"). It will inject implicit variable
248 definitions that can be overridden by the target code as necessary. Typically
249 this mechanism is used to inject a default set of configs that define the
250 global compiler and linker flags.
251
252 Which targets are built
253
254 All targets encountered in the default toolchain (see "gn help toolchain")
255 will have build rules generated for them, even if no other targets reference
256 them. Their dependencies must resolve and they will be added to the implicit
257 "all" rule (see "gn help ninja_rules").
258
259 Targets in non-default toolchains will only be generated when they are
260 required (directly or transitively) to build a target in the default
261 toolchain.
262
263 Some targets might be associated but without a formal build dependency (for
264 example, related tools or optional variants). A target that is marked as
265 "generated" can propagate its generated state to an associated target using
266 "gen_deps". This will make the referenced dependency have Ninja rules
267 generated in the same cases the source target has but without a build-time
268 dependency and even in non-default toolchains.
269
270 See also "gn help ninja_rules".
271
272 Dependencies
273
274 The only difference between "public_deps" and "deps" except for pushing
275 configs around the build tree and allowing includes for the purposes of "gn
276 check".
277
278 A target's "data_deps" are guaranteed to be built whenever the target is
279 built, but the ordering is not defined. The meaning of this is dependencies
280 required at runtime. Currently data deps will be complete before the target
281 is linked, but this is not semantically guaranteed and this is undesirable
282 from a build performance perspective. Since we hope to change this in the
283 future, do not rely on this behavior.
284 )";
285
Target(const Settings * settings,const Label & label,const SourceFileSet & build_dependency_files)286 Target::Target(const Settings* settings,
287 const Label& label,
288 const SourceFileSet& build_dependency_files)
289 : Item(settings, label, build_dependency_files) {}
290
291 Target::~Target() = default;
292
293 // A technical note on accessors defined below: Using a static global
294 // constant is much faster at runtime than using a static local one.
295 //
296 // In other words:
297 //
298 // static const Foo kEmptyFoo;
299 //
300 // const Foo& Target::foo() const {
301 // return foo_ ? *foo_ : kEmptyFoo;
302 // }
303 //
304 // Is considerably faster than:
305 //
306 // const Foo& Target::foo() const {
307 // if (foo_) {
308 // return *foo_;
309 // } else {
310 // static const Foo kEmptyFoo;
311 // return kEmptyFoo;
312 // }
313 // }
314 //
315 // Because the latter requires relatively expensive atomic operations
316 // in the second branch.
317 //
318
319 static const BundleData kEmptyBundleData;
320
bundle_data() const321 const BundleData& Target::bundle_data() const {
322 return bundle_data_ ? *bundle_data_ : kEmptyBundleData;
323 }
324
bundle_data()325 BundleData& Target::bundle_data() {
326 if (!bundle_data_)
327 bundle_data_ = std::make_unique<BundleData>();
328 return *bundle_data_;
329 }
330
331 static ConfigValues kEmptyConfigValues;
332
config_values() const333 const ConfigValues& Target::config_values() const {
334 return config_values_ ? *config_values_ : kEmptyConfigValues;
335 }
336
config_values()337 ConfigValues& Target::config_values() {
338 if (!config_values_)
339 config_values_ = std::make_unique<ConfigValues>();
340 return *config_values_;
341 }
342
343 static const ActionValues kEmptyActionValues;
344
action_values() const345 const ActionValues& Target::action_values() const {
346 return action_values_ ? *action_values_ : kEmptyActionValues;
347 }
348
action_values()349 ActionValues& Target::action_values() {
350 if (!action_values_)
351 action_values_ = std::make_unique<ActionValues>();
352 return *action_values_;
353 }
354
355 static const RustValues kEmptyRustValues;
356
rust_values() const357 const RustValues& Target::rust_values() const {
358 return rust_values_ ? *rust_values_ : kEmptyRustValues;
359 }
360
rust_values()361 RustValues& Target::rust_values() {
362 if (!rust_values_)
363 rust_values_ = std::make_unique<RustValues>();
364 return *rust_values_;
365 }
366
367 static const SwiftValues kEmptySwiftValues;
368
swift_values() const369 const SwiftValues& Target::swift_values() const {
370 return swift_values_ ? *swift_values_ : kEmptySwiftValues;
371 }
372
swift_values()373 SwiftValues& Target::swift_values() {
374 if (!swift_values_)
375 swift_values_ = std::make_unique<SwiftValues>();
376 return *swift_values_;
377 }
378
379 static const Metadata kEmptyMetadata;
380
metadata() const381 const Metadata& Target::metadata() const {
382 return metadata_ ? *metadata_ : kEmptyMetadata;
383 }
384
metadata()385 Metadata& Target::metadata() {
386 if (!metadata_)
387 metadata_ = std::make_unique<Metadata>();
388 return *metadata_;
389 }
390
391 static const Target::GeneratedFile kEmptyGeneratedFile;
392
generated_file() const393 const Target::GeneratedFile& Target::generated_file() const {
394 return generated_file_ ? *generated_file_ : kEmptyGeneratedFile;
395 }
396
generated_file()397 Target::GeneratedFile& Target::generated_file() {
398 if (!generated_file_)
399 generated_file_ = std::make_unique<Target::GeneratedFile>();
400 return *generated_file_;
401 }
402
403 // static
GetStringForOutputType(OutputType type)404 const char* Target::GetStringForOutputType(OutputType type) {
405 switch (type) {
406 case UNKNOWN:
407 return "unknown";
408 case GROUP:
409 return functions::kGroup;
410 case EXECUTABLE:
411 return functions::kExecutable;
412 case LOADABLE_MODULE:
413 return functions::kLoadableModule;
414 case SHARED_LIBRARY:
415 return functions::kSharedLibrary;
416 case STATIC_LIBRARY:
417 return functions::kStaticLibrary;
418 case SOURCE_SET:
419 return functions::kSourceSet;
420 case COPY_FILES:
421 return functions::kCopy;
422 case ACTION:
423 return functions::kAction;
424 case ACTION_FOREACH:
425 return functions::kActionForEach;
426 case BUNDLE_DATA:
427 return functions::kBundleData;
428 case CREATE_BUNDLE:
429 return functions::kCreateBundle;
430 case GENERATED_FILE:
431 return functions::kGeneratedFile;
432 case RUST_LIBRARY:
433 return functions::kRustLibrary;
434 case RUST_PROC_MACRO:
435 return functions::kRustProcMacro;
436 default:
437 return "";
438 }
439 }
440
AsTarget()441 Target* Target::AsTarget() {
442 return this;
443 }
444
AsTarget() const445 const Target* Target::AsTarget() const {
446 return this;
447 }
448
OnResolved(Err * err)449 bool Target::OnResolved(Err* err) {
450 DCHECK(output_type_ != UNKNOWN);
451 DCHECK(toolchain_) << "Toolchain should have been set before resolving.";
452
453 ScopedTrace trace(TraceItem::TRACE_ON_RESOLVED, label());
454 trace.SetToolchain(settings()->toolchain_label());
455
456 // Copy this target's own dependent and public configs to the list of configs
457 // applying to it.
458 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end());
459 MergePublicConfigsFrom(this, &configs_);
460
461 // Check visibility for just this target's own configs, before dependents are
462 // added, but after public_configs and all_dependent_configs are merged.
463 if (!CheckConfigVisibility(err))
464 return false;
465
466 // Copy public configs from all dependencies into the list of configs
467 // applying to this target (configs_).
468 PullDependentTargetConfigs();
469
470 // Copies public dependencies' public configs to this target's public
471 // configs. These configs have already been applied to this target by
472 // PullDependentTargetConfigs above, along with the public configs from
473 // private deps. This step re-exports them as public configs for targets that
474 // depend on this one.
475 for (const auto& dep : public_deps_) {
476 if (dep.ptr->toolchain() == toolchain() ||
477 dep.ptr->toolchain()->propagates_configs())
478 public_configs_.Append(dep.ptr->public_configs().begin(),
479 dep.ptr->public_configs().end());
480 }
481
482 // Copy our own libs and lib_dirs to the final set. This will be from our
483 // target and all of our configs. We do this specially since these must be
484 // inherited through the dependency tree (other flags don't work this way).
485 //
486 // This needs to happen after we pull dependent target configs for the
487 // public config's libs to be included here. And it needs to happen
488 // before pulling the dependent target libs so the libs are in the correct
489 // order (local ones first, then the dependency's).
490 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
491 const ConfigValues& cur = iter.cur();
492 all_lib_dirs_.Append(cur.lib_dirs().begin(), cur.lib_dirs().end());
493 all_libs_.Append(cur.libs().begin(), cur.libs().end());
494
495 all_framework_dirs_.Append(cur.framework_dirs().begin(),
496 cur.framework_dirs().end());
497 all_frameworks_.Append(cur.frameworks().begin(), cur.frameworks().end());
498 all_weak_frameworks_.Append(cur.weak_frameworks().begin(),
499 cur.weak_frameworks().end());
500 }
501
502 PullRecursiveBundleData();
503 PullDependentTargetLibs();
504 PullRecursiveHardDeps();
505 if (!ResolvePrecompiledHeaders(err))
506 return false;
507
508 if (!FillOutputFiles(err))
509 return false;
510
511 if (!SwiftValues::OnTargetResolved(this, err))
512 return false;
513
514 if (!CheckSourceSetLanguages(err))
515 return false;
516 if (!CheckVisibility(err))
517 return false;
518 if (!CheckTestonly(err))
519 return false;
520 if (!CheckAssertNoDeps(err))
521 return false;
522 CheckSourcesGenerated();
523
524 if (!write_runtime_deps_output_.value().empty())
525 g_scheduler->AddWriteRuntimeDepsTarget(this);
526
527 if (output_type_ == GENERATED_FILE) {
528 DCHECK(!computed_outputs_.empty());
529 g_scheduler->AddGeneratedFile(
530 computed_outputs_[0].AsSourceFile(settings()->build_settings()));
531 }
532
533 return true;
534 }
535
IsBinary() const536 bool Target::IsBinary() const {
537 return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
538 output_type_ == LOADABLE_MODULE || output_type_ == STATIC_LIBRARY ||
539 output_type_ == SOURCE_SET || output_type_ == RUST_LIBRARY ||
540 output_type_ == RUST_PROC_MACRO;
541 }
542
IsLinkable() const543 bool Target::IsLinkable() const {
544 if (output_type_ == COPY_FILES) {
545 return copy_linkable_file();
546 }
547 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY ||
548 output_type_ == RUST_LIBRARY || output_type_ == RUST_PROC_MACRO;
549 }
550
IsFinal() const551 bool Target::IsFinal() const {
552 return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
553 output_type_ == LOADABLE_MODULE || output_type_ == ACTION ||
554 output_type_ == ACTION_FOREACH || output_type_ == COPY_FILES ||
555 output_type_ == CREATE_BUNDLE || output_type_ == RUST_PROC_MACRO ||
556 (output_type_ == STATIC_LIBRARY && complete_static_lib_);
557 }
558
IsDataOnly() const559 bool Target::IsDataOnly() const {
560 // BUNDLE_DATA exists only to declare inputs to subsequent CREATE_BUNDLE
561 // targets. Changing only contents of the bundle data target should not cause
562 // a binary to be re-linked. It should affect only the CREATE_BUNDLE steps
563 // instead. As a result, normal targets should treat this as a data
564 // dependency.
565 return output_type_ == BUNDLE_DATA;
566 }
567
GetDeps(DepsIterationType type) const568 DepsIteratorRange Target::GetDeps(DepsIterationType type) const {
569 if (type == DEPS_LINKED) {
570 return DepsIteratorRange(
571 DepsIterator(&public_deps_, &private_deps_, nullptr));
572 }
573 // All deps.
574 return DepsIteratorRange(
575 DepsIterator(&public_deps_, &private_deps_, &data_deps_));
576 }
577
GetComputedOutputName() const578 std::string Target::GetComputedOutputName() const {
579 DCHECK(toolchain_)
580 << "Toolchain must be specified before getting the computed output name.";
581
582 const std::string& name =
583 output_name_.empty() ? label().name() : output_name_;
584
585 std::string result;
586 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
587 if (tool) {
588 // Only add the prefix if the name doesn't already have it and it's not
589 // being overridden.
590 if (!output_prefix_override_ &&
591 !base::StartsWith(name, tool->output_prefix(),
592 base::CompareCase::SENSITIVE))
593 result = tool->output_prefix();
594 }
595 result.append(name);
596 return result;
597 }
598
SetToolchain(const Toolchain * toolchain,Err * err)599 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
600 DCHECK(!toolchain_);
601 DCHECK_NE(UNKNOWN, output_type_);
602 toolchain_ = toolchain;
603
604 const Tool* tool = toolchain->GetToolForTargetFinalOutput(this);
605 if (tool)
606 return true;
607
608 // Tool not specified for this target type.
609 if (err) {
610 *err =
611 Err(defined_from(), "This target uses an undefined tool.",
612 base::StringPrintf(
613 "The target %s\n"
614 "of type \"%s\"\n"
615 "uses toolchain %s\n"
616 "which doesn't have the tool \"%s\" defined.\n\n"
617 "Alas, I can not continue.",
618 label().GetUserVisibleName(false).c_str(),
619 GetStringForOutputType(output_type_),
620 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
621 Tool::GetToolTypeForTargetFinalOutput(this)));
622 }
623 return false;
624 }
625
GetOutputsAsSourceFiles(const LocationRange & loc_for_error,bool build_complete,std::vector<SourceFile> * outputs,Err * err) const626 bool Target::GetOutputsAsSourceFiles(const LocationRange& loc_for_error,
627 bool build_complete,
628 std::vector<SourceFile>* outputs,
629 Err* err) const {
630 const static char kBuildIncompleteMsg[] =
631 "This target is a binary target which can't be queried for its "
632 "outputs\nduring the build. It will work for action, action_foreach, "
633 "generated_file,\nand copy targets.";
634
635 outputs->clear();
636
637 std::vector<SourceFile> files;
638 if (output_type() == Target::ACTION || output_type() == Target::COPY_FILES ||
639 output_type() == Target::ACTION_FOREACH ||
640 output_type() == Target::GENERATED_FILE) {
641 action_values().GetOutputsAsSourceFiles(this, outputs);
642 } else if (output_type() == Target::CREATE_BUNDLE) {
643 if (!bundle_data().GetOutputsAsSourceFiles(settings(), this, outputs, err))
644 return false;
645 } else if (IsBinary() && output_type() != Target::SOURCE_SET) {
646 // Binary target with normal outputs (source sets have stamp outputs like
647 // groups).
648 DCHECK(IsBinary()) << static_cast<int>(output_type());
649 if (!build_complete) {
650 // Can't access the toolchain for a target before the build is complete.
651 // Otherwise it will race with loading and setting the toolchain
652 // definition.
653 *err = Err(loc_for_error, kBuildIncompleteMsg);
654 return false;
655 }
656
657 const Tool* tool = toolchain()->GetToolForTargetFinalOutput(this);
658
659 std::vector<OutputFile> output_files;
660 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
661 this, tool, tool->outputs(), &output_files);
662 for (const OutputFile& output_file : output_files) {
663 outputs->push_back(
664 output_file.AsSourceFile(settings()->build_settings()));
665 }
666 } else {
667 // Everything else (like a group or bundle_data) has a stamp output. The
668 // dependency output file should have computed what this is. This won't be
669 // valid unless the build is complete.
670 if (!build_complete) {
671 *err = Err(loc_for_error, kBuildIncompleteMsg);
672 return false;
673 }
674 outputs->push_back(
675 dependency_output_file().AsSourceFile(settings()->build_settings()));
676 }
677 return true;
678 }
679
GetOutputFilesForSource(const SourceFile & source,const char ** computed_tool_type,std::vector<OutputFile> * outputs) const680 bool Target::GetOutputFilesForSource(const SourceFile& source,
681 const char** computed_tool_type,
682 std::vector<OutputFile>* outputs) const {
683 DCHECK(toolchain()); // Should be resolved before calling.
684
685 outputs->clear();
686 *computed_tool_type = Tool::kToolNone;
687
688 if (output_type() == Target::COPY_FILES ||
689 output_type() == Target::ACTION_FOREACH) {
690 // These target types apply the output pattern to the input.
691 std::vector<SourceFile> output_files;
692 SubstitutionWriter::ApplyListToSourceAsOutputFile(
693 this, settings(), action_values().outputs(), source, outputs);
694 } else if (!IsBinary()) {
695 // All other non-binary target types just return the target outputs. We
696 // don't know if the build is complete and it doesn't matter for non-binary
697 // targets, so just assume it's not and pass "false".
698 std::vector<SourceFile> outputs_as_source_files;
699 Err err; // We can ignore the error and return empty for failure.
700 GetOutputsAsSourceFiles(LocationRange(), false, &outputs_as_source_files,
701 &err);
702
703 // Convert to output files.
704 for (const auto& cur : outputs_as_source_files)
705 outputs->emplace_back(OutputFile(settings()->build_settings(), cur));
706 } else {
707 // All binary targets do a tool lookup.
708 DCHECK(IsBinary());
709
710 const SourceFile::Type file_type = source.GetType();
711 if (file_type == SourceFile::SOURCE_UNKNOWN)
712 return false;
713 if (file_type == SourceFile::SOURCE_O) {
714 // Object files just get passed to the output and not compiled.
715 outputs->emplace_back(OutputFile(settings()->build_settings(), source));
716 return true;
717 }
718
719 // Rust generates on a module level, not source.
720 if (file_type == SourceFile::SOURCE_RS)
721 return false;
722
723 *computed_tool_type = Tool::GetToolTypeForSourceType(file_type);
724 if (*computed_tool_type == Tool::kToolNone)
725 return false; // No tool for this file (it's a header file or something).
726 const Tool* tool = toolchain_->GetTool(*computed_tool_type);
727 if (!tool)
728 return false; // Tool does not apply for this toolchain.file.
729
730 // Swift may generate on a module or source level.
731 if (file_type == SourceFile::SOURCE_SWIFT) {
732 if (tool->partial_outputs().list().empty())
733 return false;
734 }
735
736 const SubstitutionList& substitution_list =
737 file_type == SourceFile::SOURCE_SWIFT ? tool->partial_outputs()
738 : tool->outputs();
739
740 // Figure out what output(s) this compiler produces.
741 SubstitutionWriter::ApplyListToCompilerAsOutputFile(
742 this, source, substitution_list, outputs);
743 }
744 return !outputs->empty();
745 }
746
PullDependentTargetConfigs()747 void Target::PullDependentTargetConfigs() {
748 for (const auto& pair : GetDeps(DEPS_LINKED)) {
749 if (pair.ptr->toolchain() == toolchain() ||
750 pair.ptr->toolchain()->propagates_configs())
751 MergeAllDependentConfigsFrom(pair.ptr, &configs_,
752 &all_dependent_configs_);
753 }
754 for (const auto& pair : GetDeps(DEPS_LINKED)) {
755 if (pair.ptr->toolchain() == toolchain() ||
756 pair.ptr->toolchain()->propagates_configs())
757 MergePublicConfigsFrom(pair.ptr, &configs_);
758 }
759 }
760
PullDependentTargetLibsFrom(const Target * dep,bool is_public)761 void Target::PullDependentTargetLibsFrom(const Target* dep, bool is_public) {
762 // Direct dependent libraries.
763 if (dep->output_type() == STATIC_LIBRARY ||
764 dep->output_type() == SHARED_LIBRARY ||
765 dep->output_type() == RUST_LIBRARY ||
766 dep->output_type() == SOURCE_SET ||
767 (dep->output_type() == CREATE_BUNDLE &&
768 dep->bundle_data().is_framework()) ||
769 (dep->output_type() == COPY_FILES &&
770 dep->copy_linkable_file())) {
771 inherited_libraries_.Append(dep, is_public);
772 }
773
774 // Collect Rust libraries that are accessible from the current target, or
775 // transitively part of the current target.
776 if (dep->output_type() == STATIC_LIBRARY ||
777 dep->output_type() == SHARED_LIBRARY ||
778 dep->output_type() == SOURCE_SET || dep->output_type() == RUST_LIBRARY ||
779 dep->output_type() == GROUP ||
780 (dep->output_type() == COPY_FILES &&
781 dep->copy_linkable_file())) {
782 // Here we have: `this` --[depends-on]--> `dep`
783 //
784 // The `this` target has direct access to `dep` since its a direct
785 // dependency, regardless of the edge being a public_dep or not, so we pass
786 // true for public-ness. Whereas, anything depending on `this` can only gain
787 // direct access to `dep` if the edge between `this` and `dep` is public, so
788 // we pass `is_public`.
789 //
790 // TODO(danakj): We should only need to track Rust rlibs or dylibs here, as
791 // it's used for passing to rustc with --extern. We currently track
792 // everything then drop non-Rust libs in ninja_rust_binary_target_writer.cc.
793 rust_transitive_inherited_libs_.Append(dep, true);
794 rust_transitive_inheritable_libs_.Append(dep, is_public);
795
796 rust_transitive_inherited_libs_.AppendInherited(
797 dep->rust_transitive_inheritable_libs(), true);
798 rust_transitive_inheritable_libs_.AppendInherited(
799 dep->rust_transitive_inheritable_libs(), is_public);
800 } else if (dep->output_type() == RUST_PROC_MACRO) {
801 // Proc-macros are inherited as a transitive dependency, but the things they
802 // depend on can't be used elsewhere, as the proc macro is not linked into
803 // the target (as it's only used during compilation).
804 rust_transitive_inherited_libs_.Append(dep, true);
805 rust_transitive_inheritable_libs_.Append(dep, is_public);
806 }
807
808 if ((dep->output_type() == SHARED_LIBRARY) ||
809 (dep->output_type() == COPY_FILES &&
810 dep->copy_linkable_file())) {
811 // Shared library dependendencies are inherited across public shared
812 // library boundaries.
813 //
814 // In this case:
815 // EXE -> INTERMEDIATE_SHLIB --[public]--> FINAL_SHLIB
816 // The EXE will also link to to FINAL_SHLIB. The public dependency means
817 // that the EXE can use the headers in FINAL_SHLIB so the FINAL_SHLIB
818 // will need to appear on EXE's link line.
819 //
820 // However, if the dependency is private:
821 // EXE -> INTERMEDIATE_SHLIB --[private]--> FINAL_SHLIB
822 // the dependency will not be propagated because INTERMEDIATE_SHLIB is
823 // not granting permission to call functions from FINAL_SHLIB. If EXE
824 // wants to use functions (and link to) FINAL_SHLIB, it will need to do
825 // so explicitly.
826 //
827 // Static libraries and source sets aren't inherited across shared
828 // library boundaries because they will be linked into the shared
829 // library. Rust dylib deps are handled above and transitive deps are
830 // resolved by the compiler.
831 inherited_libraries_.AppendPublicSharedLibraries(dep->inherited_libraries(),
832 is_public);
833 } else {
834 InheritedLibraries transitive;
835
836 if (!dep->IsFinal()) {
837 // The current target isn't linked, so propagate linked deps and
838 // libraries up the dependency tree.
839 for (const auto& [inherited, inherited_is_public] :
840 dep->inherited_libraries().GetOrderedAndPublicFlag()) {
841 transitive.Append(inherited, is_public && inherited_is_public);
842 }
843 } else if (dep->complete_static_lib()) {
844 // Inherit only final targets through _complete_ static libraries.
845 //
846 // Inherited final libraries aren't linked into complete static libraries.
847 // They are forwarded here so that targets that depend on complete
848 // static libraries can link them in. Conversely, since complete static
849 // libraries link in non-final targets they shouldn't be inherited.
850 for (const auto& [inherited, inherited_is_public] :
851 dep->inherited_libraries().GetOrderedAndPublicFlag()) {
852 if (inherited->IsFinal()) {
853 transitive.Append(inherited, is_public && inherited_is_public);
854 }
855 }
856 }
857
858 for (const auto& [target, pub] : transitive.GetOrderedAndPublicFlag()) {
859 // Proc macros are not linked into targets that depend on them, so do not
860 // get inherited; they are consumed by the Rust compiler and only need to
861 // be specified in --extern.
862 if (target->output_type() != RUST_PROC_MACRO) {
863 inherited_libraries_.Append(target, pub);
864 }
865 }
866 }
867
868 // Library settings are always inherited across static library boundaries.
869 if (!dep->IsFinal() || dep->output_type() == STATIC_LIBRARY) {
870 all_lib_dirs_.Append(dep->all_lib_dirs());
871 all_libs_.Append(dep->all_libs());
872
873 all_framework_dirs_.Append(dep->all_framework_dirs());
874 all_frameworks_.Append(dep->all_frameworks());
875 all_weak_frameworks_.Append(dep->all_weak_frameworks());
876 }
877 }
878
PullDependentTargetLibs()879 void Target::PullDependentTargetLibs() {
880 for (const auto& dep : public_deps_)
881 PullDependentTargetLibsFrom(dep.ptr, true);
882 for (const auto& dep : private_deps_)
883 PullDependentTargetLibsFrom(dep.ptr, false);
884 }
885
PullRecursiveHardDeps()886 void Target::PullRecursiveHardDeps() {
887 for (const auto& pair : GetDeps(DEPS_LINKED)) {
888 // Direct hard dependencies.
889 if (hard_dep() || pair.ptr->hard_dep()) {
890 recursive_hard_deps_.insert(pair.ptr);
891 continue;
892 }
893
894 // If |pair.ptr| is binary target and |pair.ptr| has no public header,
895 // |this| target does not need to have |pair.ptr|'s hard_deps as its
896 // hard_deps to start compiles earlier. Unless the target compiles a
897 // Swift module (since they also generate a header that can be used
898 // by the current target).
899 if (pair.ptr->IsBinary() && !pair.ptr->all_headers_public() &&
900 pair.ptr->public_headers().empty() &&
901 !pair.ptr->builds_swift_module()) {
902 continue;
903 }
904
905 // Recursive hard dependencies of all dependencies.
906 recursive_hard_deps_.insert(pair.ptr->recursive_hard_deps().begin(),
907 pair.ptr->recursive_hard_deps().end());
908 }
909 }
910
PullRecursiveBundleData()911 void Target::PullRecursiveBundleData() {
912 for (const auto& pair : GetDeps(DEPS_LINKED)) {
913 // Don't propagate bundle_data once they are added to a bundle.
914 if (pair.ptr->output_type() == CREATE_BUNDLE)
915 continue;
916
917 // Don't propagate across toolchain.
918 if (pair.ptr->toolchain() != toolchain())
919 continue;
920
921 // Direct dependency on a bundle_data target.
922 if (pair.ptr->output_type() == BUNDLE_DATA) {
923 bundle_data().AddBundleData(pair.ptr);
924 }
925
926 // Recursive bundle_data informations from all dependencies.
927 if (pair.ptr->has_bundle_data()) {
928 for (auto* target : pair.ptr->bundle_data().bundle_deps())
929 bundle_data().AddBundleData(target);
930 }
931 }
932
933 if (has_bundle_data())
934 bundle_data().OnTargetResolved(this);
935 }
936
FillOutputFiles(Err * err)937 bool Target::FillOutputFiles(Err* err) {
938 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
939 bool check_tool_outputs = false;
940 switch (output_type_) {
941 case GROUP:
942 case BUNDLE_DATA:
943 case CREATE_BUNDLE:
944 case SOURCE_SET:
945 case COPY_FILES:
946 case ACTION:
947 case ACTION_FOREACH:
948 case GENERATED_FILE: {
949 // These don't get linked to and use stamps which should be the first
950 // entry in the outputs. These stamps are named
951 // "<target_out_dir>/<targetname>.stamp". Setting "output_name" does not
952 // affect the stamp file name: it is always based on the original target
953 // name.
954 dependency_output_file_ =
955 GetBuildDirForTargetAsOutputFile(this, BuildDirType::OBJ);
956 dependency_output_file_.value().append(label().name());
957 dependency_output_file_.value().append(".stamp");
958 break;
959 }
960 case EXECUTABLE:
961 case LOADABLE_MODULE:
962 // Executables and loadable modules don't get linked to, but the first
963 // output is used for dependency management.
964 CHECK_GE(tool->outputs().list().size(), 1u);
965 check_tool_outputs = true;
966 dependency_output_file_ =
967 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
968 this, tool, tool->outputs().list()[0]);
969
970 if (tool->runtime_outputs().list().empty()) {
971 // Default to the first output for the runtime output.
972 runtime_outputs_.push_back(dependency_output_file_);
973 } else {
974 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
975 this, tool, tool->runtime_outputs(), &runtime_outputs_);
976 }
977 break;
978 case RUST_LIBRARY:
979 case STATIC_LIBRARY:
980 // Static libraries both have dependencies and linking going off of the
981 // first output.
982 CHECK(tool->outputs().list().size() >= 1);
983 check_tool_outputs = true;
984 link_output_file_ = dependency_output_file_ =
985 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
986 this, tool, tool->outputs().list()[0]);
987 break;
988 case RUST_PROC_MACRO:
989 case SHARED_LIBRARY:
990 CHECK(tool->outputs().list().size() >= 1);
991 check_tool_outputs = true;
992 if (const CTool* ctool = tool->AsC()) {
993 if (ctool->link_output().empty() && ctool->depend_output().empty()) {
994 // Default behavior, use the first output file for both.
995 link_output_file_ = dependency_output_file_ =
996 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
997 this, tool, tool->outputs().list()[0]);
998 } else {
999 // Use the tool-specified ones.
1000 if (!ctool->link_output().empty()) {
1001 link_output_file_ =
1002 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
1003 this, tool, ctool->link_output());
1004 }
1005 if (!ctool->depend_output().empty()) {
1006 dependency_output_file_ =
1007 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
1008 this, tool, ctool->depend_output());
1009 }
1010 }
1011 if (tool->runtime_outputs().list().empty()) {
1012 // Default to the link output for the runtime output.
1013 runtime_outputs_.push_back(link_output_file_);
1014 } else {
1015 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
1016 this, tool, tool->runtime_outputs(), &runtime_outputs_);
1017 }
1018 } else if (tool->AsRust()) {
1019 // Default behavior, use the first output file for both.
1020 link_output_file_ = dependency_output_file_ =
1021 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
1022 this, tool, tool->outputs().list()[0]);
1023 }
1024 break;
1025 case UNKNOWN:
1026 default:
1027 NOTREACHED();
1028 }
1029
1030 // Count anything generated from bundle_data dependencies.
1031 if (output_type_ == CREATE_BUNDLE) {
1032 if (!bundle_data().GetOutputFiles(settings(), this, &computed_outputs_,
1033 err))
1034 return false;
1035 }
1036
1037 // Count all outputs from this tool as something generated by this target.
1038 if (check_tool_outputs) {
1039 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
1040 this, tool, tool->outputs(), &computed_outputs_);
1041
1042 // Output names aren't canonicalized in the same way that source files
1043 // are. For example, the tool outputs often use
1044 // {{some_var}}/{{output_name}} which expands to "./foo", but this won't
1045 // match "foo" which is what we'll compute when converting a SourceFile to
1046 // an OutputFile.
1047 for (auto& out : computed_outputs_)
1048 NormalizePath(&out.value());
1049 }
1050
1051 // Also count anything the target has declared to be an output.
1052 if (action_values_.get()) {
1053 std::vector<SourceFile> outputs_as_sources;
1054 action_values_->GetOutputsAsSourceFiles(this, &outputs_as_sources);
1055 for (const SourceFile& out : outputs_as_sources)
1056 computed_outputs_.push_back(
1057 OutputFile(settings()->build_settings(), out));
1058 }
1059
1060 if ((output_type_ == COPY_FILES) && copy_linkable_file()) {
1061 std::vector<OutputFile> tool_outputs;
1062 link_output_file_ = computed_outputs()[0];
1063 }
1064
1065 return true;
1066 }
1067
ResolvePrecompiledHeaders(Err * err)1068 bool Target::ResolvePrecompiledHeaders(Err* err) {
1069 // Precompiled headers are stored on a ConfigValues struct. This way, the
1070 // build can set all the precompiled header settings in a config and apply
1071 // it to many targets. Likewise, the precompiled header values may be
1072 // specified directly on a target.
1073 //
1074 // Unlike other values on configs which are lists that just get concatenated,
1075 // the precompiled header settings are unique values. We allow them to be
1076 // specified anywhere, but if they are specified in more than one place all
1077 // places must match.
1078
1079 // Track where the current settings came from for issuing errors.
1080 bool has_precompiled_headers =
1081 config_values_.get() && config_values_->has_precompiled_headers();
1082 const Label* pch_header_settings_from = NULL;
1083 if (has_precompiled_headers)
1084 pch_header_settings_from = &label();
1085
1086 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1087 if (!iter.GetCurrentConfig())
1088 continue; // Skip the one on the target itself.
1089
1090 const Config* config = iter.GetCurrentConfig();
1091 const ConfigValues& cur = config->resolved_values();
1092 if (!cur.has_precompiled_headers())
1093 continue; // This one has no precompiled header info, skip.
1094
1095 if (has_precompiled_headers) {
1096 // Already have a precompiled header values, the settings must match.
1097 if (config_values_->precompiled_header() != cur.precompiled_header() ||
1098 config_values_->precompiled_source() != cur.precompiled_source()) {
1099 *err = Err(
1100 defined_from(), "Precompiled header setting conflict.",
1101 "The target " + label().GetUserVisibleName(false) +
1102 "\n"
1103 "has conflicting precompiled header settings.\n"
1104 "\n"
1105 "From " +
1106 pch_header_settings_from->GetUserVisibleName(false) +
1107 "\n header: " + config_values_->precompiled_header() +
1108 "\n source: " + config_values_->precompiled_source().value() +
1109 "\n\n"
1110 "From " +
1111 config->label().GetUserVisibleName(false) +
1112 "\n header: " + cur.precompiled_header() +
1113 "\n source: " + cur.precompiled_source().value());
1114 return false;
1115 }
1116 } else {
1117 // Have settings from a config, apply them to ourselves.
1118 pch_header_settings_from = &config->label();
1119 config_values().set_precompiled_header(cur.precompiled_header());
1120 config_values().set_precompiled_source(cur.precompiled_source());
1121 }
1122 }
1123
1124 return true;
1125 }
1126
CheckVisibility(Err * err) const1127 bool Target::CheckVisibility(Err* err) const {
1128 for (const auto& pair : GetDeps(DEPS_ALL)) {
1129 if (!Visibility::CheckItemVisibility(this, pair.ptr, pair.is_external_deps, err))
1130 return false;
1131 }
1132 return true;
1133 }
1134
CheckConfigVisibility(Err * err) const1135 bool Target::CheckConfigVisibility(Err* err) const {
1136 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1137 if (const Config* config = iter.GetCurrentConfig())
1138 if (!Visibility::CheckItemVisibility(this, config, false, err))
1139 return false;
1140 }
1141 return true;
1142 }
1143
CheckSourceSetLanguages(Err * err) const1144 bool Target::CheckSourceSetLanguages(Err* err) const {
1145 if (output_type() == Target::SOURCE_SET &&
1146 source_types_used().RustSourceUsed()) {
1147 *err = Err(defined_from(), "source_set contained Rust code.",
1148 label().GetUserVisibleName(false) +
1149 " has Rust code. Only C/C++ source_sets are supported.");
1150 return false;
1151 }
1152 return true;
1153 }
1154
CheckTestonly(Err * err) const1155 bool Target::CheckTestonly(Err* err) const {
1156 // If the current target is marked testonly, it can include both testonly
1157 // and non-testonly targets, so there's nothing to check.
1158 if (testonly())
1159 return true;
1160
1161 // Verify no deps have "testonly" set.
1162 for (const auto& pair : GetDeps(DEPS_ALL)) {
1163 if (pair.ptr->testonly()) {
1164 *err = MakeTestOnlyError(this, pair.ptr);
1165 return false;
1166 }
1167 }
1168
1169 // Verify no configs have "testonly" set.
1170 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1171 if (const Config* config = iter.GetCurrentConfig()) {
1172 if (config->testonly()) {
1173 *err = MakeTestOnlyError(this, config);
1174 return false;
1175 }
1176 }
1177 }
1178
1179 return true;
1180 }
1181
CheckAssertNoDeps(Err * err) const1182 bool Target::CheckAssertNoDeps(Err* err) const {
1183 if (assert_no_deps_.empty())
1184 return true;
1185
1186 TargetSet visited;
1187 std::string failure_path_str;
1188 const LabelPattern* failure_pattern = nullptr;
1189
1190 if (!RecursiveCheckAssertNoDeps(this, false, assert_no_deps_, &visited,
1191 &failure_path_str, &failure_pattern)) {
1192 *err = Err(
1193 defined_from(), "assert_no_deps failed.",
1194 label().GetUserVisibleName(false) +
1195 " has an assert_no_deps entry:\n " + failure_pattern->Describe() +
1196 "\nwhich fails for the dependency path:\n" + failure_path_str);
1197 return false;
1198 }
1199 return true;
1200 }
1201
CheckSourcesGenerated() const1202 void Target::CheckSourcesGenerated() const {
1203 // Checks that any inputs or sources to this target that are in the build
1204 // directory are generated by a target that this one transitively depends on
1205 // in some way. We already guarantee that all generated files are written
1206 // to the build dir.
1207 //
1208 // See Scheduler::AddUnknownGeneratedInput's declaration for more.
1209 for (const SourceFile& file : sources_)
1210 CheckSourceGenerated(file);
1211 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1212 for (const SourceFile& file : iter.cur().inputs())
1213 CheckSourceGenerated(file);
1214 }
1215 // TODO(agrieve): Check all_libs_ here as well (those that are source files).
1216 // http://crbug.com/571731
1217 }
1218
CheckSourceGenerated(const SourceFile & source) const1219 void Target::CheckSourceGenerated(const SourceFile& source) const {
1220 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(),
1221 source.value()))
1222 return; // Not in output dir, this is OK.
1223
1224 // Tell the scheduler about unknown files. This will be noted for later so
1225 // the list of files written by the GN build itself (often response files)
1226 // can be filtered out of this list.
1227 OutputFile out_file(settings()->build_settings(), source);
1228 TargetSet seen_targets;
1229 bool check_data_deps = false;
1230 bool consider_object_files = false;
1231 if (!EnsureFileIsGeneratedByDependency(this, out_file, true,
1232 consider_object_files, check_data_deps,
1233 &seen_targets)) {
1234 seen_targets.clear();
1235 // Allow dependency to be through data_deps for files generated by gn.
1236 check_data_deps =
1237 g_scheduler->IsFileGeneratedByWriteRuntimeDeps(out_file) ||
1238 g_scheduler->IsFileGeneratedByTarget(source);
1239 // Check object files (much slower and very rare) only if the "normal"
1240 // output check failed.
1241 consider_object_files = !check_data_deps;
1242 if (!EnsureFileIsGeneratedByDependency(this, out_file, true,
1243 consider_object_files,
1244 check_data_deps, &seen_targets))
1245 g_scheduler->AddUnknownGeneratedInput(this, source);
1246 }
1247 }
1248
GetMetadata(const std::vector<std::string> & keys_to_extract,const std::vector<std::string> & keys_to_walk,const SourceDir & rebase_dir,bool deps_only,std::vector<Value> * result,TargetSet * targets_walked,Err * err) const1249 bool Target::GetMetadata(const std::vector<std::string>& keys_to_extract,
1250 const std::vector<std::string>& keys_to_walk,
1251 const SourceDir& rebase_dir,
1252 bool deps_only,
1253 std::vector<Value>* result,
1254 TargetSet* targets_walked,
1255 Err* err) const {
1256 std::vector<Value> next_walk_keys;
1257 std::vector<Value> current_result;
1258 // If deps_only, this is the top-level target and thus we don't want to
1259 // collect its metadata, only that of its deps and data_deps.
1260 if (deps_only) {
1261 // Empty string will be converted below to mean all deps and data_deps.
1262 // Origin is null because this isn't declared anywhere, and should never
1263 // trigger any errors.
1264 next_walk_keys.push_back(Value(nullptr, ""));
1265 } else {
1266 // Otherwise, we walk this target and collect the appropriate data.
1267 // NOTE: Always call WalkStep() even when have_metadata() is false,
1268 // because WalkStep() will append to 'next_walk_keys' in this case.
1269 // See https://crbug.com/1273069.
1270 if (!metadata().WalkStep(settings()->build_settings(), keys_to_extract,
1271 keys_to_walk, rebase_dir, &next_walk_keys,
1272 ¤t_result, err))
1273 return false;
1274 }
1275
1276 // Gather walk keys and find the appropriate target. Targets identified in
1277 // the walk key set must be deps or data_deps of the declaring target.
1278 const DepsIteratorRange& all_deps = GetDeps(Target::DEPS_ALL);
1279 const SourceDir& current_dir = label().dir();
1280 for (const auto& next : next_walk_keys) {
1281 DCHECK(next.type() == Value::STRING);
1282
1283 // If we hit an empty string in this list, add all deps and data_deps. The
1284 // ordering in the resulting list of values as a result will be the data
1285 // from each explicitly listed dep prior to this, followed by all data in
1286 // walk order of the remaining deps.
1287 if (next.string_value().empty()) {
1288 for (const auto& dep : all_deps) {
1289 // If we haven't walked this dep yet, go down into it.
1290 if (targets_walked->add(dep.ptr)) {
1291 if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
1292 false, result, targets_walked, err))
1293 return false;
1294 }
1295 }
1296
1297 // Any other walk keys are superfluous, as they can only be a subset of
1298 // all deps.
1299 break;
1300 }
1301
1302 // Otherwise, look through the target's deps for the specified one.
1303 // Canonicalize the label if possible.
1304 Label next_label = Label::Resolve(
1305 current_dir, settings()->build_settings()->root_path_utf8(),
1306 settings()->toolchain_label(), next, err);
1307 if (next_label.is_null()) {
1308 *err = Err(next.origin(), std::string("Failed to canonicalize ") +
1309 next.string_value() + std::string("."));
1310 }
1311 std::string canonicalize_next_label = next_label.GetUserVisibleName(true);
1312
1313 bool found_next = false;
1314 for (const auto& dep : all_deps) {
1315 // Match against the label with the toolchain.
1316 if (dep.label.GetUserVisibleName(true) == canonicalize_next_label) {
1317 // If we haven't walked this dep yet, go down into it.
1318 if (targets_walked->add(dep.ptr)) {
1319 if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
1320 false, result, targets_walked, err))
1321 return false;
1322 }
1323 // We found it, so we can exit this search now.
1324 found_next = true;
1325 break;
1326 }
1327 }
1328 // If we didn't find the specified dep in the target, that's an error.
1329 // Propagate it back to the user.
1330 if (!found_next) {
1331 *err = Err(next.origin(),
1332 std::string("I was expecting ") + canonicalize_next_label +
1333 std::string(" to be a dependency of ") +
1334 label().GetUserVisibleName(true) +
1335 ". Make sure it's included in the deps or data_deps, and "
1336 "that you've specified the appropriate toolchain.");
1337 return false;
1338 }
1339 }
1340 result->insert(result->end(), std::make_move_iterator(current_result.begin()),
1341 std::make_move_iterator(current_result.end()));
1342 return true;
1343 }
1344