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