• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY ||
545          output_type_ == RUST_LIBRARY || output_type_ == RUST_PROC_MACRO;
546 }
547 
IsFinal() const548 bool Target::IsFinal() const {
549   return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
550          output_type_ == LOADABLE_MODULE || output_type_ == ACTION ||
551          output_type_ == ACTION_FOREACH || output_type_ == COPY_FILES ||
552          output_type_ == CREATE_BUNDLE || output_type_ == RUST_PROC_MACRO ||
553          (output_type_ == STATIC_LIBRARY && complete_static_lib_);
554 }
555 
IsDataOnly() const556 bool Target::IsDataOnly() const {
557   // BUNDLE_DATA exists only to declare inputs to subsequent CREATE_BUNDLE
558   // targets. Changing only contents of the bundle data target should not cause
559   // a binary to be re-linked. It should affect only the CREATE_BUNDLE steps
560   // instead. As a result, normal targets should treat this as a data
561   // dependency.
562   return output_type_ == BUNDLE_DATA;
563 }
564 
GetDeps(DepsIterationType type) const565 DepsIteratorRange Target::GetDeps(DepsIterationType type) const {
566   if (type == DEPS_LINKED) {
567     return DepsIteratorRange(
568         DepsIterator(&public_deps_, &private_deps_, nullptr));
569   }
570   // All deps.
571   return DepsIteratorRange(
572       DepsIterator(&public_deps_, &private_deps_, &data_deps_));
573 }
574 
GetComputedOutputName() const575 std::string Target::GetComputedOutputName() const {
576   DCHECK(toolchain_)
577       << "Toolchain must be specified before getting the computed output name.";
578 
579   const std::string& name =
580       output_name_.empty() ? label().name() : output_name_;
581 
582   std::string result;
583   const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
584   if (tool) {
585     // Only add the prefix if the name doesn't already have it and it's not
586     // being overridden.
587     if (!output_prefix_override_ &&
588         !base::StartsWith(name, tool->output_prefix(),
589                           base::CompareCase::SENSITIVE))
590       result = tool->output_prefix();
591   }
592   result.append(name);
593   return result;
594 }
595 
SetToolchain(const Toolchain * toolchain,Err * err)596 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
597   DCHECK(!toolchain_);
598   DCHECK_NE(UNKNOWN, output_type_);
599   toolchain_ = toolchain;
600 
601   const Tool* tool = toolchain->GetToolForTargetFinalOutput(this);
602   if (tool)
603     return true;
604 
605   // Tool not specified for this target type.
606   if (err) {
607     *err =
608         Err(defined_from(), "This target uses an undefined tool.",
609             base::StringPrintf(
610                 "The target %s\n"
611                 "of type \"%s\"\n"
612                 "uses toolchain %s\n"
613                 "which doesn't have the tool \"%s\" defined.\n\n"
614                 "Alas, I can not continue.",
615                 label().GetUserVisibleName(false).c_str(),
616                 GetStringForOutputType(output_type_),
617                 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
618                 Tool::GetToolTypeForTargetFinalOutput(this)));
619   }
620   return false;
621 }
622 
GetOutputsAsSourceFiles(const LocationRange & loc_for_error,bool build_complete,std::vector<SourceFile> * outputs,Err * err) const623 bool Target::GetOutputsAsSourceFiles(const LocationRange& loc_for_error,
624                                      bool build_complete,
625                                      std::vector<SourceFile>* outputs,
626                                      Err* err) const {
627   const static char kBuildIncompleteMsg[] =
628       "This target is a binary target which can't be queried for its "
629       "outputs\nduring the build. It will work for action, action_foreach, "
630       "generated_file,\nand copy targets.";
631 
632   outputs->clear();
633 
634   std::vector<SourceFile> files;
635   if (output_type() == Target::ACTION || output_type() == Target::COPY_FILES ||
636       output_type() == Target::ACTION_FOREACH ||
637       output_type() == Target::GENERATED_FILE) {
638     action_values().GetOutputsAsSourceFiles(this, outputs);
639   } else if (output_type() == Target::CREATE_BUNDLE) {
640     if (!bundle_data().GetOutputsAsSourceFiles(settings(), this, outputs, err))
641       return false;
642   } else if (IsBinary() && output_type() != Target::SOURCE_SET) {
643     // Binary target with normal outputs (source sets have stamp outputs like
644     // groups).
645     DCHECK(IsBinary()) << static_cast<int>(output_type());
646     if (!build_complete) {
647       // Can't access the toolchain for a target before the build is complete.
648       // Otherwise it will race with loading and setting the toolchain
649       // definition.
650       *err = Err(loc_for_error, kBuildIncompleteMsg);
651       return false;
652     }
653 
654     const Tool* tool = toolchain()->GetToolForTargetFinalOutput(this);
655 
656     std::vector<OutputFile> output_files;
657     SubstitutionWriter::ApplyListToLinkerAsOutputFile(
658         this, tool, tool->outputs(), &output_files);
659     for (const OutputFile& output_file : output_files) {
660       outputs->push_back(
661           output_file.AsSourceFile(settings()->build_settings()));
662     }
663   } else {
664     // Everything else (like a group or bundle_data) has a stamp output. The
665     // dependency output file should have computed what this is. This won't be
666     // valid unless the build is complete.
667     if (!build_complete) {
668       *err = Err(loc_for_error, kBuildIncompleteMsg);
669       return false;
670     }
671     outputs->push_back(
672         dependency_output_file().AsSourceFile(settings()->build_settings()));
673   }
674   return true;
675 }
676 
GetOutputFilesForSource(const SourceFile & source,const char ** computed_tool_type,std::vector<OutputFile> * outputs) const677 bool Target::GetOutputFilesForSource(const SourceFile& source,
678                                      const char** computed_tool_type,
679                                      std::vector<OutputFile>* outputs) const {
680   DCHECK(toolchain());  // Should be resolved before calling.
681 
682   outputs->clear();
683   *computed_tool_type = Tool::kToolNone;
684 
685   if (output_type() == Target::COPY_FILES ||
686       output_type() == Target::ACTION_FOREACH) {
687     // These target types apply the output pattern to the input.
688     std::vector<SourceFile> output_files;
689     SubstitutionWriter::ApplyListToSourceAsOutputFile(
690         this, settings(), action_values().outputs(), source, outputs);
691   } else if (!IsBinary()) {
692     // All other non-binary target types just return the target outputs. We
693     // don't know if the build is complete and it doesn't matter for non-binary
694     // targets, so just assume it's not and pass "false".
695     std::vector<SourceFile> outputs_as_source_files;
696     Err err;  // We can ignore the error and return empty for failure.
697     GetOutputsAsSourceFiles(LocationRange(), false, &outputs_as_source_files,
698                             &err);
699 
700     // Convert to output files.
701     for (const auto& cur : outputs_as_source_files)
702       outputs->emplace_back(OutputFile(settings()->build_settings(), cur));
703   } else {
704     // All binary targets do a tool lookup.
705     DCHECK(IsBinary());
706 
707     const SourceFile::Type file_type = source.GetType();
708     if (file_type == SourceFile::SOURCE_UNKNOWN)
709       return false;
710     if (file_type == SourceFile::SOURCE_O) {
711       // Object files just get passed to the output and not compiled.
712       outputs->emplace_back(OutputFile(settings()->build_settings(), source));
713       return true;
714     }
715 
716     // Rust generates on a module level, not source.
717     if (file_type == SourceFile::SOURCE_RS)
718       return false;
719 
720     *computed_tool_type = Tool::GetToolTypeForSourceType(file_type);
721     if (*computed_tool_type == Tool::kToolNone)
722       return false;  // No tool for this file (it's a header file or something).
723     const Tool* tool = toolchain_->GetTool(*computed_tool_type);
724     if (!tool)
725       return false;  // Tool does not apply for this toolchain.file.
726 
727     // Swift may generate on a module or source level.
728     if (file_type == SourceFile::SOURCE_SWIFT) {
729       if (tool->partial_outputs().list().empty())
730         return false;
731     }
732 
733     const SubstitutionList& substitution_list =
734         file_type == SourceFile::SOURCE_SWIFT ? tool->partial_outputs()
735                                               : tool->outputs();
736 
737     // Figure out what output(s) this compiler produces.
738     SubstitutionWriter::ApplyListToCompilerAsOutputFile(
739         this, source, substitution_list, outputs);
740   }
741   return !outputs->empty();
742 }
743 
PullDependentTargetConfigs()744 void Target::PullDependentTargetConfigs() {
745   for (const auto& pair : GetDeps(DEPS_LINKED)) {
746     if (pair.ptr->toolchain() == toolchain() ||
747         pair.ptr->toolchain()->propagates_configs())
748       MergeAllDependentConfigsFrom(pair.ptr, &configs_,
749                                    &all_dependent_configs_);
750   }
751   for (const auto& pair : GetDeps(DEPS_LINKED)) {
752     if (pair.ptr->toolchain() == toolchain() ||
753         pair.ptr->toolchain()->propagates_configs())
754       MergePublicConfigsFrom(pair.ptr, &configs_);
755   }
756 }
757 
PullDependentTargetLibsFrom(const Target * dep,bool is_public)758 void Target::PullDependentTargetLibsFrom(const Target* dep, bool is_public) {
759   // Direct dependent libraries.
760   if (dep->output_type() == STATIC_LIBRARY ||
761       dep->output_type() == SHARED_LIBRARY ||
762       dep->output_type() == RUST_LIBRARY ||
763       dep->output_type() == SOURCE_SET ||
764       (dep->output_type() == CREATE_BUNDLE &&
765        dep->bundle_data().is_framework())) {
766     inherited_libraries_.Append(dep, is_public);
767   }
768 
769   // Collect Rust libraries that are accessible from the current target, or
770   // transitively part of the current target.
771   if (dep->output_type() == STATIC_LIBRARY ||
772       dep->output_type() == SHARED_LIBRARY ||
773       dep->output_type() == SOURCE_SET || dep->output_type() == RUST_LIBRARY ||
774       dep->output_type() == GROUP) {
775     // Here we have: `this` --[depends-on]--> `dep`
776     //
777     // The `this` target has direct access to `dep` since its a direct
778     // dependency, regardless of the edge being a public_dep or not, so we pass
779     // true for public-ness. Whereas, anything depending on `this` can only gain
780     // direct access to `dep` if the edge between `this` and `dep` is public, so
781     // we pass `is_public`.
782     //
783     // TODO(danakj): We should only need to track Rust rlibs or dylibs here, as
784     // it's used for passing to rustc with --extern. We currently track
785     // everything then drop non-Rust libs in ninja_rust_binary_target_writer.cc.
786     rust_transitive_inherited_libs_.Append(dep, true);
787     rust_transitive_inheritable_libs_.Append(dep, is_public);
788 
789     rust_transitive_inherited_libs_.AppendInherited(
790         dep->rust_transitive_inheritable_libs(), true);
791     rust_transitive_inheritable_libs_.AppendInherited(
792         dep->rust_transitive_inheritable_libs(), is_public);
793   } else if (dep->output_type() == RUST_PROC_MACRO) {
794     // Proc-macros are inherited as a transitive dependency, but the things they
795     // depend on can't be used elsewhere, as the proc macro is not linked into
796     // the target (as it's only used during compilation).
797     rust_transitive_inherited_libs_.Append(dep, true);
798     rust_transitive_inheritable_libs_.Append(dep, is_public);
799   }
800 
801   if (dep->output_type() == SHARED_LIBRARY) {
802     // Shared library dependendencies are inherited across public shared
803     // library boundaries.
804     //
805     // In this case:
806     //   EXE -> INTERMEDIATE_SHLIB --[public]--> FINAL_SHLIB
807     // The EXE will also link to to FINAL_SHLIB. The public dependency means
808     // that the EXE can use the headers in FINAL_SHLIB so the FINAL_SHLIB
809     // will need to appear on EXE's link line.
810     //
811     // However, if the dependency is private:
812     //   EXE -> INTERMEDIATE_SHLIB --[private]--> FINAL_SHLIB
813     // the dependency will not be propagated because INTERMEDIATE_SHLIB is
814     // not granting permission to call functions from FINAL_SHLIB. If EXE
815     // wants to use functions (and link to) FINAL_SHLIB, it will need to do
816     // so explicitly.
817     //
818     // Static libraries and source sets aren't inherited across shared
819     // library boundaries because they will be linked into the shared
820     // library. Rust dylib deps are handled above and transitive deps are
821     // resolved by the compiler.
822     inherited_libraries_.AppendPublicSharedLibraries(dep->inherited_libraries(),
823                                                      is_public);
824   } else {
825     InheritedLibraries transitive;
826 
827     if (!dep->IsFinal()) {
828       // The current target isn't linked, so propagate linked deps and
829       // libraries up the dependency tree.
830       for (const auto& [inherited, inherited_is_public] :
831            dep->inherited_libraries().GetOrderedAndPublicFlag()) {
832         transitive.Append(inherited, is_public && inherited_is_public);
833       }
834     } else if (dep->complete_static_lib()) {
835       // Inherit only final targets through _complete_ static libraries.
836       //
837       // Inherited final libraries aren't linked into complete static libraries.
838       // They are forwarded here so that targets that depend on complete
839       // static libraries can link them in. Conversely, since complete static
840       // libraries link in non-final targets they shouldn't be inherited.
841       for (const auto& [inherited, inherited_is_public] :
842            dep->inherited_libraries().GetOrderedAndPublicFlag()) {
843         if (inherited->IsFinal()) {
844           transitive.Append(inherited, is_public && inherited_is_public);
845         }
846       }
847     }
848 
849     for (const auto& [target, pub] : transitive.GetOrderedAndPublicFlag()) {
850       // Proc macros are not linked into targets that depend on them, so do not
851       // get inherited; they are consumed by the Rust compiler and only need to
852       // be specified in --extern.
853       if (target->output_type() != RUST_PROC_MACRO) {
854         inherited_libraries_.Append(target, pub);
855       }
856     }
857   }
858 
859   // Library settings are always inherited across static library boundaries.
860   if (!dep->IsFinal() || dep->output_type() == STATIC_LIBRARY) {
861     all_lib_dirs_.Append(dep->all_lib_dirs());
862     all_libs_.Append(dep->all_libs());
863 
864     all_framework_dirs_.Append(dep->all_framework_dirs());
865     all_frameworks_.Append(dep->all_frameworks());
866     all_weak_frameworks_.Append(dep->all_weak_frameworks());
867   }
868 }
869 
PullDependentTargetLibs()870 void Target::PullDependentTargetLibs() {
871   for (const auto& dep : public_deps_)
872     PullDependentTargetLibsFrom(dep.ptr, true);
873   for (const auto& dep : private_deps_)
874     PullDependentTargetLibsFrom(dep.ptr, false);
875 }
876 
PullRecursiveHardDeps()877 void Target::PullRecursiveHardDeps() {
878   for (const auto& pair : GetDeps(DEPS_LINKED)) {
879     // Direct hard dependencies.
880     if (hard_dep() || pair.ptr->hard_dep()) {
881       recursive_hard_deps_.insert(pair.ptr);
882       continue;
883     }
884 
885     // If |pair.ptr| is binary target and |pair.ptr| has no public header,
886     // |this| target does not need to have |pair.ptr|'s hard_deps as its
887     // hard_deps to start compiles earlier. Unless the target compiles a
888     // Swift module (since they also generate a header that can be used
889     // by the current target).
890     if (pair.ptr->IsBinary() && !pair.ptr->all_headers_public() &&
891         pair.ptr->public_headers().empty() &&
892         !pair.ptr->builds_swift_module()) {
893       continue;
894     }
895 
896     // Recursive hard dependencies of all dependencies.
897     recursive_hard_deps_.insert(pair.ptr->recursive_hard_deps().begin(),
898                                 pair.ptr->recursive_hard_deps().end());
899   }
900 }
901 
PullRecursiveBundleData()902 void Target::PullRecursiveBundleData() {
903   for (const auto& pair : GetDeps(DEPS_LINKED)) {
904     // Don't propagate bundle_data once they are added to a bundle.
905     if (pair.ptr->output_type() == CREATE_BUNDLE)
906       continue;
907 
908     // Don't propagate across toolchain.
909     if (pair.ptr->toolchain() != toolchain())
910       continue;
911 
912     // Direct dependency on a bundle_data target.
913     if (pair.ptr->output_type() == BUNDLE_DATA) {
914       bundle_data().AddBundleData(pair.ptr);
915     }
916 
917     // Recursive bundle_data informations from all dependencies.
918     if (pair.ptr->has_bundle_data()) {
919       for (auto* target : pair.ptr->bundle_data().bundle_deps())
920         bundle_data().AddBundleData(target);
921     }
922   }
923 
924   if (has_bundle_data())
925     bundle_data().OnTargetResolved(this);
926 }
927 
FillOutputFiles(Err * err)928 bool Target::FillOutputFiles(Err* err) {
929   const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
930   bool check_tool_outputs = false;
931   switch (output_type_) {
932     case GROUP:
933     case BUNDLE_DATA:
934     case CREATE_BUNDLE:
935     case SOURCE_SET:
936     case COPY_FILES:
937     case ACTION:
938     case ACTION_FOREACH:
939     case GENERATED_FILE: {
940       // These don't get linked to and use stamps which should be the first
941       // entry in the outputs. These stamps are named
942       // "<target_out_dir>/<targetname>.stamp". Setting "output_name" does not
943       // affect the stamp file name: it is always based on the original target
944       // name.
945       dependency_output_file_ =
946           GetBuildDirForTargetAsOutputFile(this, BuildDirType::OBJ);
947       dependency_output_file_.value().append(label().name());
948       dependency_output_file_.value().append(".stamp");
949       break;
950     }
951     case EXECUTABLE:
952     case LOADABLE_MODULE:
953       // Executables and loadable modules don't get linked to, but the first
954       // output is used for dependency management.
955       CHECK_GE(tool->outputs().list().size(), 1u);
956       check_tool_outputs = true;
957       dependency_output_file_ =
958           SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
959               this, tool, tool->outputs().list()[0]);
960 
961       if (tool->runtime_outputs().list().empty()) {
962         // Default to the first output for the runtime output.
963         runtime_outputs_.push_back(dependency_output_file_);
964       } else {
965         SubstitutionWriter::ApplyListToLinkerAsOutputFile(
966             this, tool, tool->runtime_outputs(), &runtime_outputs_);
967       }
968       break;
969     case RUST_LIBRARY:
970     case STATIC_LIBRARY:
971       // Static libraries both have dependencies and linking going off of the
972       // first output.
973       CHECK(tool->outputs().list().size() >= 1);
974       check_tool_outputs = true;
975       link_output_file_ = dependency_output_file_ =
976           SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
977               this, tool, tool->outputs().list()[0]);
978       break;
979     case RUST_PROC_MACRO:
980     case SHARED_LIBRARY:
981       CHECK(tool->outputs().list().size() >= 1);
982       check_tool_outputs = true;
983       if (const CTool* ctool = tool->AsC()) {
984         if (ctool->link_output().empty() && ctool->depend_output().empty()) {
985           // Default behavior, use the first output file for both.
986           link_output_file_ = dependency_output_file_ =
987               SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
988                   this, tool, tool->outputs().list()[0]);
989         } else {
990           // Use the tool-specified ones.
991           if (!ctool->link_output().empty()) {
992             link_output_file_ =
993                 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
994                     this, tool, ctool->link_output());
995           }
996           if (!ctool->depend_output().empty()) {
997             dependency_output_file_ =
998                 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
999                     this, tool, ctool->depend_output());
1000           }
1001         }
1002         if (tool->runtime_outputs().list().empty()) {
1003           // Default to the link output for the runtime output.
1004           runtime_outputs_.push_back(link_output_file_);
1005         } else {
1006           SubstitutionWriter::ApplyListToLinkerAsOutputFile(
1007               this, tool, tool->runtime_outputs(), &runtime_outputs_);
1008         }
1009       } else if (tool->AsRust()) {
1010         // Default behavior, use the first output file for both.
1011         link_output_file_ = dependency_output_file_ =
1012             SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
1013                 this, tool, tool->outputs().list()[0]);
1014       }
1015       break;
1016     case UNKNOWN:
1017     default:
1018       NOTREACHED();
1019   }
1020 
1021   // Count anything generated from bundle_data dependencies.
1022   if (output_type_ == CREATE_BUNDLE) {
1023     if (!bundle_data().GetOutputFiles(settings(), this, &computed_outputs_,
1024                                       err))
1025       return false;
1026   }
1027 
1028   // Count all outputs from this tool as something generated by this target.
1029   if (check_tool_outputs) {
1030     SubstitutionWriter::ApplyListToLinkerAsOutputFile(
1031         this, tool, tool->outputs(), &computed_outputs_);
1032 
1033     // Output names aren't canonicalized in the same way that source files
1034     // are. For example, the tool outputs often use
1035     // {{some_var}}/{{output_name}} which expands to "./foo", but this won't
1036     // match "foo" which is what we'll compute when converting a SourceFile to
1037     // an OutputFile.
1038     for (auto& out : computed_outputs_)
1039       NormalizePath(&out.value());
1040   }
1041 
1042   // Also count anything the target has declared to be an output.
1043   if (action_values_.get()) {
1044     std::vector<SourceFile> outputs_as_sources;
1045     action_values_->GetOutputsAsSourceFiles(this, &outputs_as_sources);
1046     for (const SourceFile& out : outputs_as_sources)
1047       computed_outputs_.push_back(
1048           OutputFile(settings()->build_settings(), out));
1049   }
1050 
1051   return true;
1052 }
1053 
ResolvePrecompiledHeaders(Err * err)1054 bool Target::ResolvePrecompiledHeaders(Err* err) {
1055   // Precompiled headers are stored on a ConfigValues struct. This way, the
1056   // build can set all the precompiled header settings in a config and apply
1057   // it to many targets. Likewise, the precompiled header values may be
1058   // specified directly on a target.
1059   //
1060   // Unlike other values on configs which are lists that just get concatenated,
1061   // the precompiled header settings are unique values. We allow them to be
1062   // specified anywhere, but if they are specified in more than one place all
1063   // places must match.
1064 
1065   // Track where the current settings came from for issuing errors.
1066   bool has_precompiled_headers =
1067       config_values_.get() && config_values_->has_precompiled_headers();
1068   const Label* pch_header_settings_from = NULL;
1069   if (has_precompiled_headers)
1070     pch_header_settings_from = &label();
1071 
1072   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1073     if (!iter.GetCurrentConfig())
1074       continue;  // Skip the one on the target itself.
1075 
1076     const Config* config = iter.GetCurrentConfig();
1077     const ConfigValues& cur = config->resolved_values();
1078     if (!cur.has_precompiled_headers())
1079       continue;  // This one has no precompiled header info, skip.
1080 
1081     if (has_precompiled_headers) {
1082       // Already have a precompiled header values, the settings must match.
1083       if (config_values_->precompiled_header() != cur.precompiled_header() ||
1084           config_values_->precompiled_source() != cur.precompiled_source()) {
1085         *err = Err(
1086             defined_from(), "Precompiled header setting conflict.",
1087             "The target " + label().GetUserVisibleName(false) +
1088                 "\n"
1089                 "has conflicting precompiled header settings.\n"
1090                 "\n"
1091                 "From " +
1092                 pch_header_settings_from->GetUserVisibleName(false) +
1093                 "\n  header: " + config_values_->precompiled_header() +
1094                 "\n  source: " + config_values_->precompiled_source().value() +
1095                 "\n\n"
1096                 "From " +
1097                 config->label().GetUserVisibleName(false) +
1098                 "\n  header: " + cur.precompiled_header() +
1099                 "\n  source: " + cur.precompiled_source().value());
1100         return false;
1101       }
1102     } else {
1103       // Have settings from a config, apply them to ourselves.
1104       pch_header_settings_from = &config->label();
1105       config_values().set_precompiled_header(cur.precompiled_header());
1106       config_values().set_precompiled_source(cur.precompiled_source());
1107     }
1108   }
1109 
1110   return true;
1111 }
1112 
CheckVisibility(Err * err) const1113 bool Target::CheckVisibility(Err* err) const {
1114   for (const auto& pair : GetDeps(DEPS_ALL)) {
1115     if (!Visibility::CheckItemVisibility(this, pair.ptr, err))
1116       return false;
1117   }
1118   return true;
1119 }
1120 
CheckConfigVisibility(Err * err) const1121 bool Target::CheckConfigVisibility(Err* err) const {
1122   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1123     if (const Config* config = iter.GetCurrentConfig())
1124       if (!Visibility::CheckItemVisibility(this, config, err))
1125         return false;
1126   }
1127   return true;
1128 }
1129 
CheckSourceSetLanguages(Err * err) const1130 bool Target::CheckSourceSetLanguages(Err* err) const {
1131   if (output_type() == Target::SOURCE_SET &&
1132       source_types_used().RustSourceUsed()) {
1133     *err = Err(defined_from(), "source_set contained Rust code.",
1134                label().GetUserVisibleName(false) +
1135                    " has Rust code. Only C/C++ source_sets are supported.");
1136     return false;
1137   }
1138   return true;
1139 }
1140 
CheckTestonly(Err * err) const1141 bool Target::CheckTestonly(Err* err) const {
1142   // If the current target is marked testonly, it can include both testonly
1143   // and non-testonly targets, so there's nothing to check.
1144   if (testonly())
1145     return true;
1146 
1147   // Verify no deps have "testonly" set.
1148   for (const auto& pair : GetDeps(DEPS_ALL)) {
1149     if (pair.ptr->testonly()) {
1150       *err = MakeTestOnlyError(this, pair.ptr);
1151       return false;
1152     }
1153   }
1154 
1155   // Verify no configs have "testonly" set.
1156   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1157     if (const Config* config = iter.GetCurrentConfig()) {
1158       if (config->testonly()) {
1159         *err = MakeTestOnlyError(this, config);
1160         return false;
1161       }
1162     }
1163   }
1164 
1165   return true;
1166 }
1167 
CheckAssertNoDeps(Err * err) const1168 bool Target::CheckAssertNoDeps(Err* err) const {
1169   if (assert_no_deps_.empty())
1170     return true;
1171 
1172   TargetSet visited;
1173   std::string failure_path_str;
1174   const LabelPattern* failure_pattern = nullptr;
1175 
1176   if (!RecursiveCheckAssertNoDeps(this, false, assert_no_deps_, &visited,
1177                                   &failure_path_str, &failure_pattern)) {
1178     *err = Err(
1179         defined_from(), "assert_no_deps failed.",
1180         label().GetUserVisibleName(false) +
1181             " has an assert_no_deps entry:\n  " + failure_pattern->Describe() +
1182             "\nwhich fails for the dependency path:\n" + failure_path_str);
1183     return false;
1184   }
1185   return true;
1186 }
1187 
CheckSourcesGenerated() const1188 void Target::CheckSourcesGenerated() const {
1189   // Checks that any inputs or sources to this target that are in the build
1190   // directory are generated by a target that this one transitively depends on
1191   // in some way. We already guarantee that all generated files are written
1192   // to the build dir.
1193   //
1194   // See Scheduler::AddUnknownGeneratedInput's declaration for more.
1195   for (const SourceFile& file : sources_)
1196     CheckSourceGenerated(file);
1197   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
1198     for (const SourceFile& file : iter.cur().inputs())
1199       CheckSourceGenerated(file);
1200   }
1201   // TODO(agrieve): Check all_libs_ here as well (those that are source files).
1202   // http://crbug.com/571731
1203 }
1204 
CheckSourceGenerated(const SourceFile & source) const1205 void Target::CheckSourceGenerated(const SourceFile& source) const {
1206   if (!IsStringInOutputDir(settings()->build_settings()->build_dir(),
1207                            source.value()))
1208     return;  // Not in output dir, this is OK.
1209 
1210   // Tell the scheduler about unknown files. This will be noted for later so
1211   // the list of files written by the GN build itself (often response files)
1212   // can be filtered out of this list.
1213   OutputFile out_file(settings()->build_settings(), source);
1214   TargetSet seen_targets;
1215   bool check_data_deps = false;
1216   bool consider_object_files = false;
1217   if (!EnsureFileIsGeneratedByDependency(this, out_file, true,
1218                                          consider_object_files, check_data_deps,
1219                                          &seen_targets)) {
1220     seen_targets.clear();
1221     // Allow dependency to be through data_deps for files generated by gn.
1222     check_data_deps =
1223         g_scheduler->IsFileGeneratedByWriteRuntimeDeps(out_file) ||
1224         g_scheduler->IsFileGeneratedByTarget(source);
1225     // Check object files (much slower and very rare) only if the "normal"
1226     // output check failed.
1227     consider_object_files = !check_data_deps;
1228     if (!EnsureFileIsGeneratedByDependency(this, out_file, true,
1229                                            consider_object_files,
1230                                            check_data_deps, &seen_targets))
1231       g_scheduler->AddUnknownGeneratedInput(this, source);
1232   }
1233 }
1234 
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) const1235 bool Target::GetMetadata(const std::vector<std::string>& keys_to_extract,
1236                          const std::vector<std::string>& keys_to_walk,
1237                          const SourceDir& rebase_dir,
1238                          bool deps_only,
1239                          std::vector<Value>* result,
1240                          TargetSet* targets_walked,
1241                          Err* err) const {
1242   std::vector<Value> next_walk_keys;
1243   std::vector<Value> current_result;
1244   // If deps_only, this is the top-level target and thus we don't want to
1245   // collect its metadata, only that of its deps and data_deps.
1246   if (deps_only) {
1247     // Empty string will be converted below to mean all deps and data_deps.
1248     // Origin is null because this isn't declared anywhere, and should never
1249     // trigger any errors.
1250     next_walk_keys.push_back(Value(nullptr, ""));
1251   } else {
1252     // Otherwise, we walk this target and collect the appropriate data.
1253     // NOTE: Always call WalkStep() even when have_metadata() is false,
1254     // because WalkStep() will append to 'next_walk_keys' in this case.
1255     // See https://crbug.com/1273069.
1256     if (!metadata().WalkStep(settings()->build_settings(), keys_to_extract,
1257                              keys_to_walk, rebase_dir, &next_walk_keys,
1258                              &current_result, err))
1259       return false;
1260   }
1261 
1262   // Gather walk keys and find the appropriate target. Targets identified in
1263   // the walk key set must be deps or data_deps of the declaring target.
1264   const DepsIteratorRange& all_deps = GetDeps(Target::DEPS_ALL);
1265   const SourceDir& current_dir = label().dir();
1266   for (const auto& next : next_walk_keys) {
1267     DCHECK(next.type() == Value::STRING);
1268 
1269     // If we hit an empty string in this list, add all deps and data_deps. The
1270     // ordering in the resulting list of values as a result will be the data
1271     // from each explicitly listed dep prior to this, followed by all data in
1272     // walk order of the remaining deps.
1273     if (next.string_value().empty()) {
1274       for (const auto& dep : all_deps) {
1275         // If we haven't walked this dep yet, go down into it.
1276         if (targets_walked->add(dep.ptr)) {
1277           if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
1278                                     false, result, targets_walked, err))
1279             return false;
1280         }
1281       }
1282 
1283       // Any other walk keys are superfluous, as they can only be a subset of
1284       // all deps.
1285       break;
1286     }
1287 
1288     // Otherwise, look through the target's deps for the specified one.
1289     // Canonicalize the label if possible.
1290     Label next_label = Label::Resolve(
1291         current_dir, settings()->build_settings()->root_path_utf8(),
1292         settings()->toolchain_label(), next, err);
1293     if (next_label.is_null()) {
1294       *err = Err(next.origin(), std::string("Failed to canonicalize ") +
1295                                     next.string_value() + std::string("."));
1296     }
1297     std::string canonicalize_next_label = next_label.GetUserVisibleName(true);
1298 
1299     bool found_next = false;
1300     for (const auto& dep : all_deps) {
1301       // Match against the label with the toolchain.
1302       if (dep.label.GetUserVisibleName(true) == canonicalize_next_label) {
1303         // If we haven't walked this dep yet, go down into it.
1304         if (targets_walked->add(dep.ptr)) {
1305           if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
1306                                     false, result, targets_walked, err))
1307             return false;
1308         }
1309         // We found it, so we can exit this search now.
1310         found_next = true;
1311         break;
1312       }
1313     }
1314     // If we didn't find the specified dep in the target, that's an error.
1315     // Propagate it back to the user.
1316     if (!found_next) {
1317       *err = Err(next.origin(),
1318                  std::string("I was expecting ") + canonicalize_next_label +
1319                      std::string(" to be a dependency of ") +
1320                      label().GetUserVisibleName(true) +
1321                      ". Make sure it's included in the deps or data_deps, and "
1322                      "that you've specified the appropriate toolchain.");
1323       return false;
1324     }
1325   }
1326   result->insert(result->end(), std::make_move_iterator(current_result.begin()),
1327                  std::make_move_iterator(current_result.end()));
1328   return true;
1329 }
1330