• 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   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                              &current_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