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 bool with_toolchain = from->settings()->ShouldShowToolchain({
48 &from->label(),
49 &to->label(),
50 });
51 return Err(
52 from->defined_from(), "Test-only dependency not allowed.",
53 from->label().GetUserVisibleName(with_toolchain) +
54 "\n"
55 "which is NOT marked testonly can't depend on\n" +
56 to->label().GetUserVisibleName(with_toolchain) +
57 "\n"
58 "which is marked testonly. Only targets with \"testonly = true\"\n"
59 "can depend on other test-only targets.\n"
60 "\n"
61 "Either mark it test-only or don't do this dependency.");
62 }
63
64 // Set check_private_deps to true for the first invocation since a target
65 // can see all of its dependencies. For recursive invocations this will be set
66 // to false to follow only public dependency paths.
67 //
68 // Pass a pointer to an empty set for the first invocation. This will be used
69 // to avoid duplicate checking.
70 //
71 // Checking of object files is optional because it is much slower. This allows
72 // us to check targets for normal outputs, and then as a second pass check
73 // object files (since we know it will be an error otherwise). This allows
74 // 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)75 bool EnsureFileIsGeneratedByDependency(const Target* target,
76 const OutputFile& file,
77 bool check_private_deps,
78 bool consider_object_files,
79 bool check_data_deps,
80 TargetSet* seen_targets) {
81 if (!seen_targets->add(target))
82 return false; // Already checked this one and it's not found.
83
84 // Assume that we have relatively few generated inputs so brute-force
85 // searching here is OK. If this becomes a bottleneck, consider storing
86 // computed_outputs as a hash set.
87 for (const OutputFile& cur : target->computed_outputs()) {
88 if (file == cur)
89 return true;
90 }
91
92 if (file == target->write_runtime_deps_output())
93 return true;
94
95 // Check binary target intermediate files if requested.
96 if (consider_object_files && target->IsBinary()) {
97 std::vector<OutputFile> source_outputs;
98 for (const SourceFile& source : target->sources()) {
99 const char* tool_name;
100 if (!target->GetOutputFilesForSource(source, &tool_name, &source_outputs))
101 continue;
102 if (base::ContainsValue(source_outputs, file))
103 return true;
104 }
105 }
106
107 if (check_data_deps) {
108 check_data_deps = false; // Consider only direct data_deps.
109 for (const auto& pair : target->data_deps()) {
110 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
111 consider_object_files,
112 check_data_deps, seen_targets))
113 return true; // Found a path.
114 }
115 }
116
117 // Check all public dependencies (don't do data ones since those are
118 // runtime-only).
119 for (const auto& pair : target->public_deps()) {
120 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
121 consider_object_files,
122 check_data_deps, seen_targets))
123 return true; // Found a path.
124 }
125
126 // Only check private deps if requested.
127 if (check_private_deps) {
128 for (const auto& pair : target->private_deps()) {
129 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
130 consider_object_files,
131 check_data_deps, seen_targets))
132 return true; // Found a path.
133 }
134 if (target->output_type() == Target::CREATE_BUNDLE) {
135 for (const auto* dep : target->bundle_data().bundle_deps()) {
136 if (EnsureFileIsGeneratedByDependency(dep, file, false,
137 consider_object_files,
138 check_data_deps, seen_targets))
139 return true; // Found a path.
140 }
141 }
142 }
143 return false;
144 }
145
146 // check_this indicates if the given target should be matched against the
147 // patterns. It should be set to false for the first call since assert_no_deps
148 // shouldn't match the target itself.
149 //
150 // visited should point to an empty set, this will be used to prevent
151 // multiple visits.
152 //
153 // *failure_path_str will be filled with a string describing the path of the
154 // dependency failure, and failure_pattern will indicate the pattern in
155 // assert_no that matched the target.
156 //
157 // Returns true if everything is OK. failure_path_str and failure_pattern_index
158 // 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)159 bool RecursiveCheckAssertNoDeps(const Target* target,
160 bool check_this,
161 const std::vector<LabelPattern>& assert_no,
162 TargetSet* visited,
163 std::string* failure_path_str,
164 const LabelPattern** failure_pattern) {
165 static const char kIndentPath[] = " ";
166
167 if (!visited->add(target))
168 return true; // Already checked this target.
169
170 if (check_this) {
171 // Check this target against the given list of patterns.
172 for (const LabelPattern& pattern : assert_no) {
173 if (pattern.Matches(target->label())) {
174 // Found a match.
175 *failure_pattern = &pattern;
176 *failure_path_str =
177 kIndentPath + target->label().GetUserVisibleName(false);
178 return false;
179 }
180 }
181 }
182
183 // Recursively check dependencies.
184 for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) {
185 if (pair.ptr->output_type() == Target::EXECUTABLE)
186 continue;
187 if (!RecursiveCheckAssertNoDeps(pair.ptr, true, assert_no, visited,
188 failure_path_str, failure_pattern)) {
189 // To reconstruct the path, prepend the current target to the error.
190 std::string prepend_path =
191 kIndentPath + target->label().GetUserVisibleName(false) + " ->\n";
192 failure_path_str->insert(0, prepend_path);
193 return false;
194 }
195 }
196
197 return true;
198 }
199
200 } // namespace
201
202 const char kExecution_Help[] =
203 R"(Build graph and execution overview
204
205 Overall build flow
206
207 1. Look for ".gn" file (see "gn help dotfile") in the current directory and
208 walk up the directory tree until one is found. Set this directory to be
209 the "source root" and interpret this file to find the name of the build
210 config file.
211
212 2. Execute the build config file identified by .gn to set up the global
213 variables and default toolchain name. Any arguments, variables, defaults,
214 etc. set up in this file will be visible to all files in the build.
215
216 3. Load the //BUILD.gn (in the source root directory).
217
218 4. Recursively evaluate rules and load BUILD.gn in other directories as
219 necessary to resolve dependencies. If a BUILD file isn't found in the
220 specified location, GN will look in the corresponding location inside
221 the secondary_source defined in the dotfile (see "gn help dotfile").
222
223 5. When a target's dependencies are resolved, write out the `.ninja`
224 file to disk.
225
226 6. When all targets are resolved, write out the root build.ninja file.
227
228 Note that the BUILD.gn file name may be modulated by .gn arguments such as
229 build_file_extension.
230
231 Executing target definitions and templates
232
233 Build files are loaded in parallel. This means it is impossible to
234 interrogate a target from GN code for any information not derivable from its
235 label (see "gn help label"). The exception is the get_target_outputs()
236 function which requires the target being interrogated to have been defined
237 previously in the same file.
238
239 Targets are declared by their type and given a name:
240
241 static_library("my_static_library") {
242 ... target parameter definitions ...
243 }
244
245 There is also a generic "target" function for programmatically defined types
246 (see "gn help target"). You can define new types using templates (see "gn
247 help template"). A template defines some custom code that expands to one or
248 more other targets.
249
250 Before executing the code inside the target's { }, the target defaults are
251 applied (see "gn help set_defaults"). It will inject implicit variable
252 definitions that can be overridden by the target code as necessary. Typically
253 this mechanism is used to inject a default set of configs that define the
254 global compiler and linker flags.
255
256 Which targets are built
257
258 All targets encountered in the default toolchain (see "gn help toolchain")
259 will have build rules generated for them, even if no other targets reference
260 them. Their dependencies must resolve and they will be added to the implicit
261 "all" rule (see "gn help ninja_rules").
262
263 Targets in non-default toolchains will only be generated when they are
264 required (directly or transitively) to build a target in the default
265 toolchain.
266
267 Some targets might be associated but without a formal build dependency (for
268 example, related tools or optional variants). A target that is marked as
269 "generated" can propagate its generated state to an associated target using
270 "gen_deps". This will make the referenced dependency have Ninja rules
271 generated in the same cases the source target has but without a build-time
272 dependency and even in non-default toolchains.
273
274 See also "gn help ninja_rules".
275
276 Dependencies
277
278 The only difference between "public_deps" and "deps" except for pushing
279 configs around the build tree and allowing includes for the purposes of "gn
280 check".
281
282 A target's "data_deps" are guaranteed to be built whenever the target is
283 built, but the ordering is not defined. The meaning of this is dependencies
284 required at runtime. Currently data deps will be complete before the target
285 is linked, but this is not semantically guaranteed and this is undesirable
286 from a build performance perspective. Since we hope to change this in the
287 future, do not rely on this behavior.
288 )";
289
Target(const Settings * settings,const Label & label,const SourceFileSet & build_dependency_files)290 Target::Target(const Settings* settings,
291 const Label& label,
292 const SourceFileSet& build_dependency_files)
293 : Item(settings, label, build_dependency_files) {}
294
295 Target::~Target() = default;
296
297 // A technical note on accessors defined below: Using a static global
298 // constant is much faster at runtime than using a static local one.
299 //
300 // In other words:
301 //
302 // static const Foo kEmptyFoo;
303 //
304 // const Foo& Target::foo() const {
305 // return foo_ ? *foo_ : kEmptyFoo;
306 // }
307 //
308 // Is considerably faster than:
309 //
310 // const Foo& Target::foo() const {
311 // if (foo_) {
312 // return *foo_;
313 // } else {
314 // static const Foo kEmptyFoo;
315 // return kEmptyFoo;
316 // }
317 // }
318 //
319 // Because the latter requires relatively expensive atomic operations
320 // in the second branch.
321 //
322
323 static const BundleData kEmptyBundleData;
324
bundle_data() const325 const BundleData& Target::bundle_data() const {
326 return bundle_data_ ? *bundle_data_ : kEmptyBundleData;
327 }
328
bundle_data()329 BundleData& Target::bundle_data() {
330 if (!bundle_data_)
331 bundle_data_ = std::make_unique<BundleData>();
332 return *bundle_data_;
333 }
334
335 static ConfigValues kEmptyConfigValues;
336
config_values() const337 const ConfigValues& Target::config_values() const {
338 return config_values_ ? *config_values_ : kEmptyConfigValues;
339 }
340
config_values()341 ConfigValues& Target::config_values() {
342 if (!config_values_)
343 config_values_ = std::make_unique<ConfigValues>();
344 return *config_values_;
345 }
346
347 static const ActionValues kEmptyActionValues;
348
action_values() const349 const ActionValues& Target::action_values() const {
350 return action_values_ ? *action_values_ : kEmptyActionValues;
351 }
352
action_values()353 ActionValues& Target::action_values() {
354 if (!action_values_)
355 action_values_ = std::make_unique<ActionValues>();
356 return *action_values_;
357 }
358
359 static const RustValues kEmptyRustValues;
360
rust_values() const361 const RustValues& Target::rust_values() const {
362 return rust_values_ ? *rust_values_ : kEmptyRustValues;
363 }
364
rust_values()365 RustValues& Target::rust_values() {
366 if (!rust_values_)
367 rust_values_ = std::make_unique<RustValues>();
368 return *rust_values_;
369 }
370
371 static const SwiftValues kEmptySwiftValues;
372
swift_values() const373 const SwiftValues& Target::swift_values() const {
374 return swift_values_ ? *swift_values_ : kEmptySwiftValues;
375 }
376
swift_values()377 SwiftValues& Target::swift_values() {
378 if (!swift_values_)
379 swift_values_ = std::make_unique<SwiftValues>();
380 return *swift_values_;
381 }
382
383 static const Metadata kEmptyMetadata;
384
metadata() const385 const Metadata& Target::metadata() const {
386 return metadata_ ? *metadata_ : kEmptyMetadata;
387 }
388
metadata()389 Metadata& Target::metadata() {
390 if (!metadata_)
391 metadata_ = std::make_unique<Metadata>();
392 return *metadata_;
393 }
394
395 static const Target::GeneratedFile kEmptyGeneratedFile;
396
generated_file() const397 const Target::GeneratedFile& Target::generated_file() const {
398 return generated_file_ ? *generated_file_ : kEmptyGeneratedFile;
399 }
400
generated_file()401 Target::GeneratedFile& Target::generated_file() {
402 if (!generated_file_)
403 generated_file_ = std::make_unique<Target::GeneratedFile>();
404 return *generated_file_;
405 }
406
407 // static
GetStringForOutputType(OutputType type)408 const char* Target::GetStringForOutputType(OutputType type) {
409 switch (type) {
410 case UNKNOWN:
411 return "unknown";
412 case GROUP:
413 return functions::kGroup;
414 case EXECUTABLE:
415 return functions::kExecutable;
416 case LOADABLE_MODULE:
417 return functions::kLoadableModule;
418 case SHARED_LIBRARY:
419 return functions::kSharedLibrary;
420 case STATIC_LIBRARY:
421 return functions::kStaticLibrary;
422 case SOURCE_SET:
423 return functions::kSourceSet;
424 case COPY_FILES:
425 return functions::kCopy;
426 case ACTION:
427 return functions::kAction;
428 case ACTION_FOREACH:
429 return functions::kActionForEach;
430 case BUNDLE_DATA:
431 return functions::kBundleData;
432 case CREATE_BUNDLE:
433 return functions::kCreateBundle;
434 case GENERATED_FILE:
435 return functions::kGeneratedFile;
436 case RUST_LIBRARY:
437 return functions::kRustLibrary;
438 case RUST_PROC_MACRO:
439 return functions::kRustProcMacro;
440 default:
441 return "";
442 }
443 }
444
AsTarget()445 Target* Target::AsTarget() {
446 return this;
447 }
448
AsTarget() const449 const Target* Target::AsTarget() const {
450 return this;
451 }
452
OnResolved(Err * err)453 bool Target::OnResolved(Err* err) {
454 DCHECK(output_type_ != UNKNOWN);
455 DCHECK(toolchain_) << "Toolchain should have been set before resolving.";
456
457 ScopedTrace trace(TraceItem::TRACE_ON_RESOLVED, label());
458 trace.SetToolchain(settings()->toolchain_label());
459
460 // Copy this target's own dependent and public configs to the list of configs
461 // applying to it.
462 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end());
463 MergePublicConfigsFrom(this, &configs_);
464
465 // Check visibility for just this target's own configs, before dependents are
466 // added, but after public_configs and all_dependent_configs are merged.
467 if (!CheckConfigVisibility(err))
468 return false;
469
470 // Copy public configs from all dependencies into the list of configs
471 // applying to this target (configs_).
472 PullDependentTargetConfigs();
473
474 // Copies public dependencies' public configs to this target's public
475 // configs. These configs have already been applied to this target by
476 // PullDependentTargetConfigs above, along with the public configs from
477 // private deps. This step re-exports them as public configs for targets that
478 // depend on this one.
479 for (const auto& dep : public_deps_) {
480 if (dep.ptr->toolchain() == toolchain() ||
481 dep.ptr->toolchain()->propagates_configs())
482 public_configs_.Append(dep.ptr->public_configs().begin(),
483 dep.ptr->public_configs().end());
484 }
485
486
487
488 PullRecursiveBundleData();
489 if (!ResolvePrecompiledHeaders(err))
490 return false;
491
492 if (!FillOutputFiles(err))
493 return false;
494
495 if (!SwiftValues::OnTargetResolved(this, err))
496 return false;
497
498 if (!CheckSourceSetLanguages(err))
499 return false;
500 if (!CheckVisibility(err))
501 return false;
502 if (!CheckTestonly(err))
503 return false;
504 if (!CheckAssertNoDeps(err))
505 return false;
506 CheckSourcesGenerated();
507
508 if (!write_runtime_deps_output_.value().empty())
509 g_scheduler->AddWriteRuntimeDepsTarget(this);
510
511 if (output_type_ == GENERATED_FILE) {
512 DCHECK(!computed_outputs_.empty());
513 g_scheduler->AddGeneratedFile(
514 computed_outputs_[0].AsSourceFile(settings()->build_settings()));
515 }
516
517 return true;
518 }
519
IsBinary() const520 bool Target::IsBinary() const {
521 return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
522 output_type_ == LOADABLE_MODULE || output_type_ == STATIC_LIBRARY ||
523 output_type_ == SOURCE_SET || output_type_ == RUST_LIBRARY ||
524 output_type_ == RUST_PROC_MACRO;
525 }
526
IsLinkable() const527 bool Target::IsLinkable() const {
528 if (output_type_ == COPY_FILES) {
529 return copy_linkable_file();
530 }
531 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY ||
532 output_type_ == RUST_LIBRARY || output_type_ == RUST_PROC_MACRO;
533 }
534
IsFinal() const535 bool Target::IsFinal() const {
536 return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
537 output_type_ == LOADABLE_MODULE || output_type_ == ACTION ||
538 output_type_ == ACTION_FOREACH || output_type_ == COPY_FILES ||
539 output_type_ == CREATE_BUNDLE || output_type_ == RUST_PROC_MACRO ||
540 (output_type_ == STATIC_LIBRARY && complete_static_lib_);
541 }
542
IsDataOnly() const543 bool Target::IsDataOnly() const {
544 // BUNDLE_DATA exists only to declare inputs to subsequent CREATE_BUNDLE
545 // targets. Changing only contents of the bundle data target should not cause
546 // a binary to be re-linked. It should affect only the CREATE_BUNDLE steps
547 // instead. As a result, normal targets should treat this as a data
548 // dependency.
549 return output_type_ == BUNDLE_DATA;
550 }
551
ShouldGenerate() const552 bool Target::ShouldGenerate() const {
553 const auto& root_patterns = settings()->build_settings()->root_patterns();
554 if (root_patterns.empty()) {
555 // By default, generate all targets that belong to the default toolchain.
556 return settings()->is_default();
557 }
558 return LabelPattern::VectorMatches(root_patterns, label());
559 }
560
GetDeps(DepsIterationType type) const561 DepsIteratorRange Target::GetDeps(DepsIterationType type) const {
562 if (type == DEPS_LINKED) {
563 return DepsIteratorRange(
564 DepsIterator(&public_deps_, &private_deps_, nullptr));
565 }
566 // All deps.
567 return DepsIteratorRange(
568 DepsIterator(&public_deps_, &private_deps_, &data_deps_));
569 }
570
GetComputedOutputName() const571 std::string Target::GetComputedOutputName() const {
572 DCHECK(toolchain_)
573 << "Toolchain must be specified before getting the computed output name.";
574
575 const std::string& name =
576 output_name_.empty() ? label().name() : output_name_;
577
578 std::string result;
579 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
580 if (tool) {
581 // Only add the prefix if the name doesn't already have it and it's not
582 // being overridden.
583 if (!output_prefix_override_ && !base::starts_with(name, tool->output_prefix()))
584 result = tool->output_prefix();
585 }
586 result.append(name);
587 return result;
588 }
589
SetToolchain(const Toolchain * toolchain,Err * err)590 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
591 DCHECK(!toolchain_);
592 DCHECK_NE(UNKNOWN, output_type_);
593 toolchain_ = toolchain;
594
595 const Tool* tool = toolchain->GetToolForTargetFinalOutput(this);
596 if (tool)
597 return true;
598
599 // Tool not specified for this target type.
600 if (err) {
601 *err =
602 Err(defined_from(), "This target uses an undefined tool.",
603 base::StringPrintf(
604 "The target %s\n"
605 "of type \"%s\"\n"
606 "uses toolchain %s\n"
607 "which doesn't have the tool \"%s\" defined.\n\n"
608 "Alas, I can not continue.",
609 label().GetUserVisibleName(false).c_str(),
610 GetStringForOutputType(output_type_),
611 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
612 Tool::GetToolTypeForTargetFinalOutput(this)));
613 }
614 return false;
615 }
616
GetOutputsAsSourceFiles(const LocationRange & loc_for_error,bool build_complete,std::vector<SourceFile> * outputs,Err * err) const617 bool Target::GetOutputsAsSourceFiles(const LocationRange& loc_for_error,
618 bool build_complete,
619 std::vector<SourceFile>* outputs,
620 Err* err) const {
621 const static char kBuildIncompleteMsg[] =
622 "This target is a binary target which can't be queried for its "
623 "outputs\nduring the build. It will work for action, action_foreach, "
624 "generated_file,\nand copy targets.";
625
626 outputs->clear();
627
628 std::vector<SourceFile> files;
629 if (output_type() == Target::ACTION || output_type() == Target::COPY_FILES ||
630 output_type() == Target::ACTION_FOREACH ||
631 output_type() == Target::GENERATED_FILE) {
632 action_values().GetOutputsAsSourceFiles(this, outputs);
633 } else if (output_type() == Target::CREATE_BUNDLE) {
634 if (!bundle_data().GetOutputsAsSourceFiles(settings(), this, outputs, err))
635 return false;
636 } else if (IsBinary() && output_type() != Target::SOURCE_SET) {
637 // Binary target with normal outputs (source sets have stamp outputs like
638 // groups).
639 DCHECK(IsBinary()) << static_cast<int>(output_type());
640 if (!build_complete) {
641 // Can't access the toolchain for a target before the build is complete.
642 // Otherwise it will race with loading and setting the toolchain
643 // definition.
644 *err = Err(loc_for_error, kBuildIncompleteMsg);
645 return false;
646 }
647
648 const Tool* tool = toolchain()->GetToolForTargetFinalOutput(this);
649
650 std::vector<OutputFile> output_files;
651 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
652 this, tool, tool->outputs(), &output_files);
653 for (const OutputFile& output_file : output_files) {
654 outputs->push_back(
655 output_file.AsSourceFile(settings()->build_settings()));
656 }
657 } else {
658 // Everything else (like a group or bundle_data) has a stamp output. The
659 // dependency output file should have computed what this is. This won't be
660 // valid unless the build is complete.
661 if (!build_complete) {
662 *err = Err(loc_for_error, kBuildIncompleteMsg);
663 return false;
664 }
665 outputs->push_back(
666 dependency_output_file().AsSourceFile(settings()->build_settings()));
667 }
668 return true;
669 }
670
GetOutputFilesForSource(const SourceFile & source,const char ** computed_tool_type,std::vector<OutputFile> * outputs) const671 bool Target::GetOutputFilesForSource(const SourceFile& source,
672 const char** computed_tool_type,
673 std::vector<OutputFile>* outputs) const {
674 DCHECK(toolchain()); // Should be resolved before calling.
675
676 outputs->clear();
677 *computed_tool_type = Tool::kToolNone;
678
679 if (output_type() == Target::COPY_FILES ||
680 output_type() == Target::ACTION_FOREACH) {
681 // These target types apply the output pattern to the input.
682 std::vector<SourceFile> output_files;
683 SubstitutionWriter::ApplyListToSourceAsOutputFile(
684 this, settings(), action_values().outputs(), source, outputs);
685 } else if (!IsBinary()) {
686 // All other non-binary target types just return the target outputs. We
687 // don't know if the build is complete and it doesn't matter for non-binary
688 // targets, so just assume it's not and pass "false".
689 std::vector<SourceFile> outputs_as_source_files;
690 Err err; // We can ignore the error and return empty for failure.
691 GetOutputsAsSourceFiles(LocationRange(), false, &outputs_as_source_files,
692 &err);
693
694 // Convert to output files.
695 for (const auto& cur : outputs_as_source_files)
696 outputs->emplace_back(OutputFile(settings()->build_settings(), cur));
697 } else {
698 // All binary targets do a tool lookup.
699 DCHECK(IsBinary());
700
701 const SourceFile::Type file_type = source.GetType();
702 if (file_type == SourceFile::SOURCE_UNKNOWN)
703 return false;
704 if (file_type == SourceFile::SOURCE_O) {
705 // Object files just get passed to the output and not compiled.
706 outputs->emplace_back(OutputFile(settings()->build_settings(), source));
707 return true;
708 }
709
710 // Rust generates on a module level, not source.
711 if (file_type == SourceFile::SOURCE_RS)
712 return false;
713
714 *computed_tool_type = Tool::GetToolTypeForSourceType(file_type);
715 if (*computed_tool_type == Tool::kToolNone)
716 return false; // No tool for this file (it's a header file or something).
717 const Tool* tool = toolchain_->GetTool(*computed_tool_type);
718 if (!tool)
719 return false; // Tool does not apply for this toolchain.file.
720
721 // Swift may generate on a module or source level.
722 if (file_type == SourceFile::SOURCE_SWIFT) {
723 if (tool->partial_outputs().list().empty())
724 return false;
725 }
726
727 const SubstitutionList& substitution_list =
728 file_type == SourceFile::SOURCE_SWIFT ? tool->partial_outputs()
729 : tool->outputs();
730
731 // Figure out what output(s) this compiler produces.
732 SubstitutionWriter::ApplyListToCompilerAsOutputFile(
733 this, source, substitution_list, outputs);
734 }
735 return !outputs->empty();
736 }
737
PullDependentTargetConfigs()738 void Target::PullDependentTargetConfigs() {
739 for (const auto& pair : GetDeps(DEPS_LINKED)) {
740 if (pair.ptr->toolchain() == toolchain() ||
741 pair.ptr->toolchain()->propagates_configs())
742 MergeAllDependentConfigsFrom(pair.ptr, &configs_,
743 &all_dependent_configs_);
744 }
745 for (const auto& pair : GetDeps(DEPS_LINKED)) {
746 if (pair.ptr->toolchain() == toolchain() ||
747 pair.ptr->toolchain()->propagates_configs())
748 MergePublicConfigsFrom(pair.ptr, &configs_);
749 }
750 }
751
752
PullDependentTargetLibsFrom(const Target * dep,bool is_public)753 void Target::PullDependentTargetLibsFrom(const Target* dep, bool is_public) {
754 // Direct dependent libraries.
755 if (dep->output_type() == STATIC_LIBRARY ||
756 dep->output_type() == SHARED_LIBRARY ||
757 dep->output_type() == RUST_LIBRARY ||
758 dep->output_type() == SOURCE_SET ||
759 (dep->output_type() == CREATE_BUNDLE &&
760 dep->bundle_data().is_framework()) ||
761 (dep->output_type() == COPY_FILES &&
762 dep->copy_linkable_file())) {
763 inherited_libraries_.Append(dep, is_public);
764 }
765
766 // Collect Rust libraries that are accessible from the current target, or
767 // transitively part of the current target.
768 if (dep->output_type() == STATIC_LIBRARY ||
769 dep->output_type() == SHARED_LIBRARY ||
770 dep->output_type() == SOURCE_SET || dep->output_type() == RUST_LIBRARY ||
771 dep->output_type() == GROUP ||
772 (dep->output_type() == COPY_FILES &&
773 dep->copy_linkable_file())) {
774 // Here we have: `this` --[depends-on]--> `dep`
775 //
776 // The `this` target has direct access to `dep` since its a direct
777 // dependency, regardless of the edge being a public_dep or not, so we pass
778 // true for public-ness. Whereas, anything depending on `this` can only gain
779 // direct access to `dep` if the edge between `this` and `dep` is public, so
780 // we pass `is_public`.
781 //
782 // TODO(danakj): We should only need to track Rust rlibs or dylibs here, as
783 // it's used for passing to rustc with --extern. We currently track
784 // everything then drop non-Rust libs in ninja_rust_binary_target_writer.cc.
785 rust_transitive_inherited_libs_.Append(dep, true);
786 rust_transitive_inheritable_libs_.Append(dep, is_public);
787
788 rust_transitive_inherited_libs_.AppendInherited(
789 dep->rust_transitive_inheritable_libs(), true);
790 rust_transitive_inheritable_libs_.AppendInherited(
791 dep->rust_transitive_inheritable_libs(), is_public);
792 } else if (dep->output_type() == RUST_PROC_MACRO) {
793 // Proc-macros are inherited as a transitive dependency, but the things they
794 // depend on can't be used elsewhere, as the proc macro is not linked into
795 // the target (as it's only used during compilation).
796 rust_transitive_inherited_libs_.Append(dep, true);
797 rust_transitive_inheritable_libs_.Append(dep, is_public);
798 }
799
800 if ((dep->output_type() == SHARED_LIBRARY) ||
801 (dep->output_type() == COPY_FILES &&
802 dep->copy_linkable_file())) {
803 // Shared library dependendencies are inherited across public shared
804 // library boundaries.
805 //
806 // In this case:
807 // EXE -> INTERMEDIATE_SHLIB --[public]--> FINAL_SHLIB
808 // The EXE will also link to to FINAL_SHLIB. The public dependency means
809 // that the EXE can use the headers in FINAL_SHLIB so the FINAL_SHLIB
810 // will need to appear on EXE's link line.
811 //
812 // However, if the dependency is private:
813 // EXE -> INTERMEDIATE_SHLIB --[private]--> FINAL_SHLIB
814 // the dependency will not be propagated because INTERMEDIATE_SHLIB is
815 // not granting permission to call functions from FINAL_SHLIB. If EXE
816 // wants to use functions (and link to) FINAL_SHLIB, it will need to do
817 // so explicitly.
818 //
819 // Static libraries and source sets aren't inherited across shared
820 // library boundaries because they will be linked into the shared
821 // library. Rust dylib deps are handled above and transitive deps are
822 // resolved by the compiler.
823 inherited_libraries_.AppendPublicSharedLibraries(dep->inherited_libraries(),
824 is_public);
825 } else {
826 InheritedLibraries transitive;
827
828 if (!dep->IsFinal()) {
829 // The current target isn't linked, so propagate linked deps and
830 // libraries up the dependency tree.
831 for (const auto& [inherited, inherited_is_public] :
832 dep->inherited_libraries().GetOrderedAndPublicFlag()) {
833 transitive.Append(inherited, is_public && inherited_is_public);
834 }
835 } else if (dep->complete_static_lib()) {
836 // Inherit only final targets through _complete_ static libraries.
837 //
838 // Inherited final libraries aren't linked into complete static libraries.
839 // They are forwarded here so that targets that depend on complete
840 // static libraries can link them in. Conversely, since complete static
841 // libraries link in non-final targets they shouldn't be inherited.
842 for (const auto& [inherited, inherited_is_public] :
843 dep->inherited_libraries().GetOrderedAndPublicFlag()) {
844 if (inherited->IsFinal()) {
845 transitive.Append(inherited, is_public && inherited_is_public);
846 }
847 }
848 }
849
850 for (const auto& [target, pub] : transitive.GetOrderedAndPublicFlag()) {
851 // Proc macros are not linked into targets that depend on them, so do not
852 // get inherited; they are consumed by the Rust compiler and only need to
853 // be specified in --extern.
854 if (target->output_type() != RUST_PROC_MACRO) {
855 inherited_libraries_.Append(target, pub);
856 }
857 }
858 }
859
860 // Library settings are always inherited across static library boundaries.
861 if (!dep->IsFinal() || dep->output_type() == STATIC_LIBRARY) {
862 all_lib_dirs_.Append(dep->all_lib_dirs());
863 all_libs_.Append(dep->all_libs());
864
865 all_framework_dirs_.Append(dep->all_framework_dirs());
866 all_frameworks_.Append(dep->all_frameworks());
867 all_weak_frameworks_.Append(dep->all_weak_frameworks());
868 }
869 }
870
PullDependentTargetLibs()871 void Target::PullDependentTargetLibs() {
872 for (const auto& dep : public_deps_)
873 PullDependentTargetLibsFrom(dep.ptr, true);
874 for (const auto& dep : private_deps_)
875 PullDependentTargetLibsFrom(dep.ptr, false);
876 }
877
PullRecursiveHardDeps()878 void Target::PullRecursiveHardDeps() {
879 for (const auto& pair : GetDeps(DEPS_LINKED)) {
880 // Direct hard dependencies.
881 if (hard_dep() || pair.ptr->hard_dep()) {
882 recursive_hard_deps_.insert(pair.ptr);
883 continue;
884 }
885
886 // If |pair.ptr| is binary target and |pair.ptr| has no public header,
887 // |this| target does not need to have |pair.ptr|'s hard_deps as its
888 // hard_deps to start compiles earlier. Unless the target compiles a
889 // Swift module (since they also generate a header that can be used
890 // by the current target).
891 if (pair.ptr->IsBinary() && !pair.ptr->all_headers_public() &&
892 pair.ptr->public_headers().empty() &&
893 !pair.ptr->builds_swift_module()) {
894 continue;
895 }
896
897 // Recursive hard dependencies of all dependencies.
898 recursive_hard_deps_.insert(pair.ptr->recursive_hard_deps().begin(),
899 pair.ptr->recursive_hard_deps().end());
900 }
901 }
902
PullRecursiveBundleData()903 void Target::PullRecursiveBundleData() {
904 const bool is_create_bundle = output_type_ == CREATE_BUNDLE;
905 for (const auto& pair : GetDeps(DEPS_LINKED)) {
906 // Don't propagate across toolchain.
907 if (pair.ptr->toolchain() != toolchain())
908 continue;
909
910 // Don't propagete through create_bundle, unless it is transparent.
911 if (pair.ptr->output_type() == CREATE_BUNDLE &&
912 !pair.ptr->bundle_data().transparent()) {
913 continue;
914 }
915
916 // Direct dependency on a bundle_data target.
917 if (pair.ptr->output_type() == BUNDLE_DATA) {
918 bundle_data().AddBundleData(pair.ptr, is_create_bundle);
919 }
920
921 // Recursive bundle_data informations from all dependencies.
922 if (pair.ptr->has_bundle_data()) {
923 for (const auto* target : pair.ptr->bundle_data().forwarded_bundle_deps())
924 bundle_data().AddBundleData(target, is_create_bundle);
925 }
926 }
927
928 if (has_bundle_data())
929 bundle_data().OnTargetResolved(this);
930 }
931
FillOutputFiles(Err * err)932 bool Target::FillOutputFiles(Err* err) {
933 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
934 bool check_tool_outputs = false;
935 switch (output_type_) {
936 case GROUP:
937 case BUNDLE_DATA:
938 case CREATE_BUNDLE:
939 case SOURCE_SET:
940 case COPY_FILES:
941 case ACTION:
942 case ACTION_FOREACH:
943 case GENERATED_FILE: {
944 // These don't get linked to and use stamps which should be the first
945 // entry in the outputs. These stamps are named
946 // "<target_out_dir>/<targetname>.stamp". Setting "output_name" does not
947 // affect the stamp file name: it is always based on the original target
948 // name.
949 dependency_output_file_ =
950 GetBuildDirForTargetAsOutputFile(this, BuildDirType::OBJ);
951 dependency_output_file_.value().append(label().name());
952 dependency_output_file_.value().append(".stamp");
953 break;
954 }
955 case EXECUTABLE:
956 case LOADABLE_MODULE:
957 // Executables and loadable modules don't get linked to, but the first
958 // output is used for dependency management.
959 CHECK_GE(tool->outputs().list().size(), 1u);
960 check_tool_outputs = true;
961 dependency_output_file_ =
962 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
963 this, tool, tool->outputs().list()[0]);
964
965 if (tool->runtime_outputs().list().empty()) {
966 // Default to the first output for the runtime output.
967 runtime_outputs_.push_back(dependency_output_file_);
968 } else {
969 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
970 this, tool, tool->runtime_outputs(), &runtime_outputs_);
971 }
972 break;
973 case RUST_LIBRARY:
974 case STATIC_LIBRARY:
975 // Static libraries both have dependencies and linking going off of the
976 // first output.
977 CHECK(tool->outputs().list().size() >= 1);
978 check_tool_outputs = true;
979 link_output_file_ = dependency_output_file_ =
980 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
981 this, tool, tool->outputs().list()[0]);
982 break;
983 case RUST_PROC_MACRO:
984 case SHARED_LIBRARY:
985 CHECK(tool->outputs().list().size() >= 1);
986 check_tool_outputs = true;
987 if (const CTool* ctool = tool->AsC()) {
988 if (ctool->link_output().empty() && ctool->depend_output().empty()) {
989 // Default behavior, use the first output file for both.
990 link_output_file_ = dependency_output_file_ =
991 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
992 this, tool, tool->outputs().list()[0]);
993 } else {
994 // Use the tool-specified ones.
995 if (!ctool->link_output().empty()) {
996 link_output_file_ =
997 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
998 this, tool, ctool->link_output());
999 }
1000 if (!ctool->depend_output().empty()) {
1001 dependency_output_file_ =
1002 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
1003 this, tool, ctool->depend_output());
1004 }
1005 }
1006 if (tool->runtime_outputs().list().empty()) {
1007 // Default to the link output for the runtime output.
1008 runtime_outputs_.push_back(link_output_file_);
1009 } else {
1010 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
1011 this, tool, tool->runtime_outputs(), &runtime_outputs_);
1012 }
1013 } else if (tool->AsRust()) {
1014 // Default behavior, use the first output file for both.
1015 link_output_file_ = dependency_output_file_ =
1016 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
1017 this, tool, tool->outputs().list()[0]);
1018 }
1019 break;
1020 case UNKNOWN:
1021 default:
1022 NOTREACHED();
1023 }
1024
1025 // Count anything generated from bundle_data dependencies.
1026 if (output_type_ == CREATE_BUNDLE) {
1027 if (!bundle_data().GetOutputFiles(settings(), this, &computed_outputs_,
1028 err))
1029 return false;
1030 }
1031
1032 // Count all outputs from this tool as something generated by this target.
1033 if (check_tool_outputs) {
1034 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
1035 this, tool, tool->outputs(), &computed_outputs_);
1036
1037 // Output names aren't canonicalized in the same way that source files
1038 // are. For example, the tool outputs often use
1039 // {{some_var}}/{{output_name}} which expands to "./foo", but this won't
1040 // match "foo" which is what we'll compute when converting a SourceFile to
1041 // an OutputFile.
1042 for (auto& out : computed_outputs_)
1043 NormalizePath(&out.value());
1044 }
1045
1046 // Also count anything the target has declared to be an output.
1047 if (action_values_.get()) {
1048 std::vector<SourceFile> outputs_as_sources;
1049 action_values_->GetOutputsAsSourceFiles(this, &outputs_as_sources);
1050 for (const SourceFile& out : outputs_as_sources)
1051 computed_outputs_.push_back(
1052 OutputFile(settings()->build_settings(), out));
1053 }
1054
1055 if ((output_type_ == COPY_FILES) && copy_linkable_file()) {
1056 std::vector<OutputFile> tool_outputs;
1057 link_output_file_ = computed_outputs()[0];
1058 }
1059
1060 return true;
1061 }
1062
ResolvePrecompiledHeaders(Err * err)1063 bool Target::ResolvePrecompiledHeaders(Err* err) {
1064 // Precompiled headers are stored on a ConfigValues struct. This way, the
1065 // build can set all the precompiled header settings in a config and apply
1066 // it to many targets. Likewise, the precompiled header values may be
1067 // specified directly on a target.
1068 //
1069 // Unlike other values on configs which are lists that just get concatenated,
1070 // the precompiled header settings are unique values. We allow them to be
1071 // specified anywhere, but if they are specified in more than one place all
1072 // places must match.
1073
1074 // Track where the current settings came from for issuing errors.
1075 bool has_precompiled_headers =
1076 config_values_.get() && config_values_->has_precompiled_headers();
1077 const Label* pch_header_settings_from = NULL;
1078 if (has_precompiled_headers)
1079 pch_header_settings_from = &label();
1080
1081 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1082 if (!iter.GetCurrentConfig())
1083 continue; // Skip the one on the target itself.
1084
1085 const Config* config = iter.GetCurrentConfig();
1086 const ConfigValues& cur = config->resolved_values();
1087 if (!cur.has_precompiled_headers())
1088 continue; // This one has no precompiled header info, skip.
1089
1090 if (has_precompiled_headers) {
1091 // Already have a precompiled header values, the settings must match.
1092 if (config_values_->precompiled_header() != cur.precompiled_header() ||
1093 config_values_->precompiled_source() != cur.precompiled_source()) {
1094 bool with_toolchain = settings()->ShouldShowToolchain({
1095 &label(),
1096 pch_header_settings_from,
1097 &config->label(),
1098 });
1099 *err = Err(
1100 defined_from(), "Precompiled header setting conflict.",
1101 "The target " + label().GetUserVisibleName(with_toolchain) +
1102 "\n"
1103 "has conflicting precompiled header settings.\n"
1104 "\n"
1105 "From " +
1106 pch_header_settings_from->GetUserVisibleName(with_toolchain) +
1107 "\n header: " + config_values_->precompiled_header() +
1108 "\n source: " + config_values_->precompiled_source().value() +
1109 "\n\n"
1110 "From " +
1111 config->label().GetUserVisibleName(with_toolchain) +
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(!settings()->is_default()) +
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(!settings()->is_default()) +
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