• 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 Target * from,const Target * to)46 Err MakeTestOnlyError(const Target* from, const Target* 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,std::set<const Target * > * 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                                        std::set<const Target*>* seen_targets) {
77   if (seen_targets->find(target) != seen_targets->end())
78     return false;  // Already checked this one and it's not found.
79   seen_targets->insert(target);
80 
81   // Assume that we have relatively few generated inputs so brute-force
82   // searching here is OK. If this becomes a bottleneck, consider storing
83   // computed_outputs as a hash set.
84   for (const OutputFile& cur : target->computed_outputs()) {
85     if (file == cur)
86       return true;
87   }
88 
89   if (file == target->write_runtime_deps_output())
90     return true;
91 
92   // Check binary target intermediate files if requested.
93   if (consider_object_files && target->IsBinary()) {
94     std::vector<OutputFile> source_outputs;
95     for (const SourceFile& source : target->sources()) {
96       const char* tool_name;
97       if (!target->GetOutputFilesForSource(source, &tool_name, &source_outputs))
98         continue;
99       if (base::ContainsValue(source_outputs, file))
100         return true;
101     }
102   }
103 
104   if (check_data_deps) {
105     check_data_deps = false;  // Consider only direct data_deps.
106     for (const auto& pair : target->data_deps()) {
107       if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
108                                             consider_object_files,
109                                             check_data_deps, seen_targets))
110         return true;  // Found a path.
111     }
112   }
113 
114   // Check all public dependencies (don't do data ones since those are
115   // runtime-only).
116   for (const auto& pair : target->public_deps()) {
117     if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
118                                           consider_object_files,
119                                           check_data_deps, seen_targets))
120       return true;  // Found a path.
121   }
122 
123   // Only check private deps if requested.
124   if (check_private_deps) {
125     for (const auto& pair : target->private_deps()) {
126       if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
127                                             consider_object_files,
128                                             check_data_deps, seen_targets))
129         return true;  // Found a path.
130     }
131     if (target->output_type() == Target::CREATE_BUNDLE) {
132       for (auto* dep : target->bundle_data().bundle_deps()) {
133         if (EnsureFileIsGeneratedByDependency(dep, file, false,
134                                               consider_object_files,
135                                               check_data_deps, seen_targets))
136           return true;  // Found a path.
137       }
138     }
139   }
140   return false;
141 }
142 
143 // check_this indicates if the given target should be matched against the
144 // patterns. It should be set to false for the first call since assert_no_deps
145 // shouldn't match the target itself.
146 //
147 // visited should point to an empty set, this will be used to prevent
148 // multiple visits.
149 //
150 // *failure_path_str will be filled with a string describing the path of the
151 // dependency failure, and failure_pattern will indicate the pattern in
152 // assert_no that matched the target.
153 //
154 // Returns true if everything is OK. failure_path_str and failure_pattern_index
155 // will be unchanged in this case.
RecursiveCheckAssertNoDeps(const Target * target,bool check_this,const std::vector<LabelPattern> & assert_no,std::set<const Target * > * visited,std::string * failure_path_str,const LabelPattern ** failure_pattern)156 bool RecursiveCheckAssertNoDeps(const Target* target,
157                                 bool check_this,
158                                 const std::vector<LabelPattern>& assert_no,
159                                 std::set<const Target*>* visited,
160                                 std::string* failure_path_str,
161                                 const LabelPattern** failure_pattern) {
162   static const char kIndentPath[] = "  ";
163 
164   if (visited->find(target) != visited->end())
165     return true;  // Already checked this target.
166   visited->insert(target);
167 
168   if (check_this) {
169     // Check this target against the given list of patterns.
170     for (const LabelPattern& pattern : assert_no) {
171       if (pattern.Matches(target->label())) {
172         // Found a match.
173         *failure_pattern = &pattern;
174         *failure_path_str =
175             kIndentPath + target->label().GetUserVisibleName(false);
176         return false;
177       }
178     }
179   }
180 
181   // Recursively check dependencies.
182   for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) {
183     if (pair.ptr->output_type() == Target::EXECUTABLE)
184       continue;
185     if (!RecursiveCheckAssertNoDeps(pair.ptr, true, assert_no, visited,
186                                     failure_path_str, failure_pattern)) {
187       // To reconstruct the path, prepend the current target to the error.
188       std::string prepend_path =
189           kIndentPath + target->label().GetUserVisibleName(false) + " ->\n";
190       failure_path_str->insert(0, prepend_path);
191       return false;
192     }
193   }
194 
195   return true;
196 }
197 
198 }  // namespace
199 
200 const char kExecution_Help[] =
201     R"(Build graph and execution overview
202 
203 Overall build flow
204 
205   1. Look for ".gn" file (see "gn help dotfile") in the current directory and
206      walk up the directory tree until one is found. Set this directory to be
207      the "source root" and interpret this file to find the name of the build
208      config file.
209 
210   2. Execute the build config file identified by .gn to set up the global
211      variables and default toolchain name. Any arguments, variables, defaults,
212      etc. set up in this file will be visible to all files in the build.
213 
214   3. Load the //BUILD.gn (in the source root directory).
215 
216   4. Recursively evaluate rules and load BUILD.gn in other directories as
217      necessary to resolve dependencies. If a BUILD file isn't found in the
218      specified location, GN will look in the corresponding location inside
219      the secondary_source defined in the dotfile (see "gn help dotfile").
220 
221   5. When a target's dependencies are resolved, write out the `.ninja`
222      file to disk.
223 
224   6. When all targets are resolved, write out the root build.ninja file.
225 
226 Executing target definitions and templates
227 
228   Build files are loaded in parallel. This means it is impossible to
229   interrogate a target from GN code for any information not derivable from its
230   label (see "gn help label"). The exception is the get_target_outputs()
231   function which requires the target being interrogated to have been defined
232   previously in the same file.
233 
234   Targets are declared by their type and given a name:
235 
236     static_library("my_static_library") {
237       ... target parameter definitions ...
238     }
239 
240   There is also a generic "target" function for programmatically defined types
241   (see "gn help target"). You can define new types using templates (see "gn
242   help template"). A template defines some custom code that expands to one or
243   more other targets.
244 
245   Before executing the code inside the target's { }, the target defaults are
246   applied (see "gn help set_defaults"). It will inject implicit variable
247   definitions that can be overridden by the target code as necessary. Typically
248   this mechanism is used to inject a default set of configs that define the
249   global compiler and linker flags.
250 
251 Which targets are built
252 
253   All targets encountered in the default toolchain (see "gn help toolchain")
254   will have build rules generated for them, even if no other targets reference
255   them. Their dependencies must resolve and they will be added to the implicit
256   "all" rule (see "gn help ninja_rules").
257 
258   Targets in non-default toolchains will only be generated when they are
259   required (directly or transitively) to build a target in the default
260   toolchain.
261 
262   See also "gn help ninja_rules".
263 
264 Dependencies
265 
266   The only difference between "public_deps" and "deps" except for pushing
267   configs around the build tree and allowing includes for the purposes of "gn
268   check".
269 
270   A target's "data_deps" are guaranteed to be built whenever the target is
271   built, but the ordering is not defined. The meaning of this is dependencies
272   required at runtime. Currently data deps will be complete before the target
273   is linked, but this is not semantically guaranteed and this is undesirable
274   from a build performance perspective. Since we hope to change this in the
275   future, do not rely on this behavior.
276 )";
277 
Target(const Settings * settings,const Label & label,const SourceFileSet & build_dependency_files)278 Target::Target(const Settings* settings,
279                const Label& label,
280                const SourceFileSet& build_dependency_files)
281     : Item(settings, label, build_dependency_files) {}
282 
283 Target::~Target() = default;
284 
285 // static
GetStringForOutputType(OutputType type)286 const char* Target::GetStringForOutputType(OutputType type) {
287   switch (type) {
288     case UNKNOWN:
289       return "unknown";
290     case GROUP:
291       return functions::kGroup;
292     case EXECUTABLE:
293       return functions::kExecutable;
294     case LOADABLE_MODULE:
295       return functions::kLoadableModule;
296     case SHARED_LIBRARY:
297       return functions::kSharedLibrary;
298     case STATIC_LIBRARY:
299       return functions::kStaticLibrary;
300     case SOURCE_SET:
301       return functions::kSourceSet;
302     case COPY_FILES:
303       return functions::kCopy;
304     case ACTION:
305       return functions::kAction;
306     case ACTION_FOREACH:
307       return functions::kActionForEach;
308     case BUNDLE_DATA:
309       return functions::kBundleData;
310     case CREATE_BUNDLE:
311       return functions::kCreateBundle;
312     case GENERATED_FILE:
313       return functions::kGeneratedFile;
314     case RUST_LIBRARY:
315       return functions::kRustLibrary;
316     case RUST_PROC_MACRO:
317       return functions::kRustProcMacro;
318     default:
319       return "";
320   }
321 }
322 
AsTarget()323 Target* Target::AsTarget() {
324   return this;
325 }
326 
AsTarget() const327 const Target* Target::AsTarget() const {
328   return this;
329 }
330 
OnResolved(Err * err)331 bool Target::OnResolved(Err* err) {
332   DCHECK(output_type_ != UNKNOWN);
333   DCHECK(toolchain_) << "Toolchain should have been set before resolving.";
334 
335   ScopedTrace trace(TraceItem::TRACE_ON_RESOLVED, label());
336   trace.SetToolchain(settings()->toolchain_label());
337 
338   // Copy this target's own dependent and public configs to the list of configs
339   // applying to it.
340   configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end());
341   MergePublicConfigsFrom(this, &configs_);
342 
343   // Copy public configs from all dependencies into the list of configs
344   // applying to this target (configs_).
345   PullDependentTargetConfigs();
346 
347   // Copies public dependencies' public configs to this target's public
348   // configs. These configs have already been applied to this target by
349   // PullDependentTargetConfigs above, along with the public configs from
350   // private deps. This step re-exports them as public configs for targets that
351   // depend on this one.
352   for (const auto& dep : public_deps_) {
353     if (dep.ptr->toolchain() == toolchain() ||
354         dep.ptr->toolchain()->propagates_configs())
355       public_configs_.Append(dep.ptr->public_configs().begin(),
356                              dep.ptr->public_configs().end());
357   }
358 
359   // Copy our own libs and lib_dirs to the final set. This will be from our
360   // target and all of our configs. We do this specially since these must be
361   // inherited through the dependency tree (other flags don't work this way).
362   //
363   // This needs to happen after we pull dependent target configs for the
364   // public config's libs to be included here. And it needs to happen
365   // before pulling the dependent target libs so the libs are in the correct
366   // order (local ones first, then the dependency's).
367   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
368     const ConfigValues& cur = iter.cur();
369     all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end());
370     all_libs_.append(cur.libs().begin(), cur.libs().end());
371 
372     all_framework_dirs_.append(cur.framework_dirs().begin(),
373                                cur.framework_dirs().end());
374     all_frameworks_.append(cur.frameworks().begin(), cur.frameworks().end());
375   }
376 
377   PullRecursiveBundleData();
378   PullDependentTargetLibs();
379   PullRecursiveHardDeps();
380   if (!ResolvePrecompiledHeaders(err))
381     return false;
382 
383   if (!FillOutputFiles(err))
384     return false;
385 
386   if (!CheckVisibility(err))
387     return false;
388   if (!CheckTestonly(err))
389     return false;
390   if (!CheckAssertNoDeps(err))
391     return false;
392   CheckSourcesGenerated();
393 
394   if (!write_runtime_deps_output_.value().empty())
395     g_scheduler->AddWriteRuntimeDepsTarget(this);
396 
397   if (output_type_ == GENERATED_FILE) {
398     DCHECK(!computed_outputs_.empty());
399     g_scheduler->AddGeneratedFile(
400         computed_outputs_[0].AsSourceFile(settings()->build_settings()));
401   }
402 
403   return true;
404 }
405 
IsBinary() const406 bool Target::IsBinary() const {
407   return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
408          output_type_ == LOADABLE_MODULE || output_type_ == STATIC_LIBRARY ||
409          output_type_ == SOURCE_SET || output_type_ == RUST_LIBRARY ||
410          output_type_ == RUST_PROC_MACRO;
411 }
412 
IsLinkable() const413 bool Target::IsLinkable() const {
414   return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY ||
415          output_type_ == RUST_LIBRARY || output_type_ == RUST_PROC_MACRO;
416 }
417 
IsFinal() const418 bool Target::IsFinal() const {
419   return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
420          output_type_ == LOADABLE_MODULE || output_type_ == ACTION ||
421          output_type_ == ACTION_FOREACH || output_type_ == COPY_FILES ||
422          output_type_ == CREATE_BUNDLE || output_type_ == RUST_PROC_MACRO ||
423          (output_type_ == STATIC_LIBRARY &&
424           (complete_static_lib_ ||
425            // Rust static libraries may be used from C/C++ code and therefore
426            // require all dependencies to be linked in as we cannot link their
427            // (Rust) dependencies directly as we would for C/C++.
428            source_types_used_.RustSourceUsed()));
429 }
430 
GetDeps(DepsIterationType type) const431 DepsIteratorRange Target::GetDeps(DepsIterationType type) const {
432   if (type == DEPS_LINKED) {
433     return DepsIteratorRange(
434         DepsIterator(&public_deps_, &private_deps_, nullptr));
435   }
436   // All deps.
437   return DepsIteratorRange(
438       DepsIterator(&public_deps_, &private_deps_, &data_deps_));
439 }
440 
GetComputedOutputName() const441 std::string Target::GetComputedOutputName() const {
442   DCHECK(toolchain_)
443       << "Toolchain must be specified before getting the computed output name.";
444 
445   const std::string& name =
446       output_name_.empty() ? label().name() : output_name_;
447 
448   std::string result;
449   const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
450   if (tool) {
451     // Only add the prefix if the name doesn't already have it and it's not
452     // being overridden.
453     if (!output_prefix_override_ &&
454         !base::StartsWith(name, tool->output_prefix(),
455                           base::CompareCase::SENSITIVE))
456       result = tool->output_prefix();
457   }
458   result.append(name);
459   return result;
460 }
461 
SetToolchain(const Toolchain * toolchain,Err * err)462 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
463   DCHECK(!toolchain_);
464   DCHECK_NE(UNKNOWN, output_type_);
465   toolchain_ = toolchain;
466 
467   const Tool* tool = toolchain->GetToolForTargetFinalOutput(this);
468   if (tool)
469     return true;
470 
471   // Tool not specified for this target type.
472   if (err) {
473     *err =
474         Err(defined_from(), "This target uses an undefined tool.",
475             base::StringPrintf(
476                 "The target %s\n"
477                 "of type \"%s\"\n"
478                 "uses toolchain %s\n"
479                 "which doesn't have the tool \"%s\" defined.\n\n"
480                 "Alas, I can not continue.",
481                 label().GetUserVisibleName(false).c_str(),
482                 GetStringForOutputType(output_type_),
483                 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
484                 Tool::GetToolTypeForTargetFinalOutput(this)));
485   }
486   return false;
487 }
488 
GetOutputFilesForSource(const SourceFile & source,const char ** computed_tool_type,std::vector<OutputFile> * outputs) const489 bool Target::GetOutputFilesForSource(const SourceFile& source,
490                                      const char** computed_tool_type,
491                                      std::vector<OutputFile>* outputs) const {
492   outputs->clear();
493   *computed_tool_type = Tool::kToolNone;
494 
495   SourceFile::Type file_type = source.type();
496   if (file_type == SourceFile::SOURCE_UNKNOWN)
497     return false;
498   if (file_type == SourceFile::SOURCE_O) {
499     // Object files just get passed to the output and not compiled.
500     outputs->push_back(OutputFile(settings()->build_settings(), source));
501     return true;
502   }
503 
504   // Rust generates on a module level, not source.
505   if (file_type == SourceFile::SOURCE_RS) {
506     return false;
507   }
508 
509   *computed_tool_type = Tool::GetToolTypeForSourceType(file_type);
510   if (*computed_tool_type == Tool::kToolNone)
511     return false;  // No tool for this file (it's a header file or something).
512   const Tool* tool = toolchain_->GetTool(*computed_tool_type);
513   if (!tool)
514     return false;  // Tool does not apply for this toolchain.file.
515 
516   // Figure out what output(s) this compiler produces.
517   SubstitutionWriter::ApplyListToCompilerAsOutputFile(this, source,
518                                                       tool->outputs(), outputs);
519   return !outputs->empty();
520 }
521 
PullDependentTargetConfigs()522 void Target::PullDependentTargetConfigs() {
523   for (const auto& pair : GetDeps(DEPS_LINKED)) {
524     if (pair.ptr->toolchain() == toolchain() ||
525         pair.ptr->toolchain()->propagates_configs())
526       MergeAllDependentConfigsFrom(pair.ptr, &configs_,
527                                    &all_dependent_configs_);
528   }
529   for (const auto& pair : GetDeps(DEPS_LINKED)) {
530     if (pair.ptr->toolchain() == toolchain() ||
531         pair.ptr->toolchain()->propagates_configs())
532       MergePublicConfigsFrom(pair.ptr, &configs_);
533   }
534 }
535 
PullDependentTargetLibsFrom(const Target * dep,bool is_public)536 void Target::PullDependentTargetLibsFrom(const Target* dep, bool is_public) {
537   // Direct dependent libraries.
538   if (dep->output_type() == STATIC_LIBRARY ||
539       dep->output_type() == SHARED_LIBRARY ||
540       dep->output_type() == SOURCE_SET || dep->output_type() == RUST_LIBRARY ||
541       dep->output_type() == RUST_PROC_MACRO)
542     inherited_libraries_.Append(dep, is_public);
543 
544   if (dep->output_type() == CREATE_BUNDLE &&
545       dep->bundle_data().is_framework()) {
546     inherited_libraries_.Append(dep, is_public);
547   }
548 
549   if (dep->output_type() == SHARED_LIBRARY) {
550     // Shared library dependendencies are inherited across public shared
551     // library boundaries.
552     //
553     // In this case:
554     //   EXE -> INTERMEDIATE_SHLIB --[public]--> FINAL_SHLIB
555     // The EXE will also link to to FINAL_SHLIB. The public dependeny means
556     // that the EXE can use the headers in FINAL_SHLIB so the FINAL_SHLIB
557     // will need to appear on EXE's link line.
558     //
559     // However, if the dependency is private:
560     //   EXE -> INTERMEDIATE_SHLIB --[private]--> FINAL_SHLIB
561     // the dependency will not be propagated because INTERMEDIATE_SHLIB is
562     // not granting permission to call functiosn from FINAL_SHLIB. If EXE
563     // wants to use functions (and link to) FINAL_SHLIB, it will need to do
564     // so explicitly.
565     //
566     // Static libraries and source sets aren't inherited across shared
567     // library boundaries because they will be linked into the shared
568     // library.
569     inherited_libraries_.AppendPublicSharedLibraries(dep->inherited_libraries(),
570                                                      is_public);
571   } else if (!dep->IsFinal()) {
572     // The current target isn't linked, so propogate linked deps and
573     // libraries up the dependency tree.
574     inherited_libraries_.AppendInherited(dep->inherited_libraries(), is_public);
575   } else if (dep->complete_static_lib()) {
576     // Inherit only final targets through _complete_ static libraries.
577     //
578     // Inherited final libraries aren't linked into complete static libraries.
579     // They are forwarded here so that targets that depend on complete
580     // static libraries can link them in. Conversely, since complete static
581     // libraries link in non-final targets they shouldn't be inherited.
582     for (const auto& inherited :
583          dep->inherited_libraries().GetOrderedAndPublicFlag()) {
584       if (inherited.first->IsFinal()) {
585         inherited_libraries_.Append(inherited.first,
586                                     is_public && inherited.second);
587       }
588     }
589   }
590 
591   // Library settings are always inherited across static library boundaries.
592   if (!dep->IsFinal() || dep->output_type() == STATIC_LIBRARY) {
593     all_lib_dirs_.append(dep->all_lib_dirs());
594     all_libs_.append(dep->all_libs());
595 
596     all_framework_dirs_.append(dep->all_framework_dirs());
597     all_frameworks_.append(dep->all_frameworks());
598   }
599 }
600 
PullDependentTargetLibs()601 void Target::PullDependentTargetLibs() {
602   for (const auto& dep : public_deps_)
603     PullDependentTargetLibsFrom(dep.ptr, true);
604   for (const auto& dep : private_deps_)
605     PullDependentTargetLibsFrom(dep.ptr, false);
606 }
607 
PullRecursiveHardDeps()608 void Target::PullRecursiveHardDeps() {
609   for (const auto& pair : GetDeps(DEPS_LINKED)) {
610     // Direct hard dependencies.
611     if (hard_dep() || pair.ptr->hard_dep()) {
612       recursive_hard_deps_.insert(pair.ptr);
613       continue;
614     }
615 
616     // If |pair.ptr| is binary target and |pair.ptr| has no public header,
617     // |this| target does not need to have |pair.ptr|'s hard_deps as its
618     // hard_deps to start compiles earlier.
619     if (pair.ptr->IsBinary() && !pair.ptr->all_headers_public() &&
620         pair.ptr->public_headers().empty()) {
621       continue;
622     }
623 
624     // Recursive hard dependencies of all dependencies.
625     recursive_hard_deps_.insert(pair.ptr->recursive_hard_deps().begin(),
626                                 pair.ptr->recursive_hard_deps().end());
627   }
628 }
629 
PullRecursiveBundleData()630 void Target::PullRecursiveBundleData() {
631   for (const auto& pair : GetDeps(DEPS_LINKED)) {
632     // Don't propagate bundle_data once they are added to a bundle.
633     if (pair.ptr->output_type() == CREATE_BUNDLE)
634       continue;
635 
636     // Don't propagate across toolchain.
637     if (pair.ptr->toolchain() != toolchain())
638       continue;
639 
640     // Direct dependency on a bundle_data target.
641     if (pair.ptr->output_type() == BUNDLE_DATA)
642       bundle_data_.AddBundleData(pair.ptr);
643 
644     // Recursive bundle_data informations from all dependencies.
645     for (auto* target : pair.ptr->bundle_data().bundle_deps())
646       bundle_data_.AddBundleData(target);
647   }
648 
649   bundle_data_.OnTargetResolved(this);
650 }
651 
FillOutputFiles(Err * err)652 bool Target::FillOutputFiles(Err* err) {
653   const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
654   bool check_tool_outputs = false;
655   switch (output_type_) {
656     case GROUP:
657     case BUNDLE_DATA:
658     case CREATE_BUNDLE:
659     case SOURCE_SET:
660     case COPY_FILES:
661     case ACTION:
662     case ACTION_FOREACH:
663     case GENERATED_FILE: {
664       // These don't get linked to and use stamps which should be the first
665       // entry in the outputs. These stamps are named
666       // "<target_out_dir>/<targetname>.stamp".
667       dependency_output_file_ =
668           GetBuildDirForTargetAsOutputFile(this, BuildDirType::OBJ);
669       dependency_output_file_.value().append(GetComputedOutputName());
670       dependency_output_file_.value().append(".stamp");
671       break;
672     }
673     case EXECUTABLE:
674     case LOADABLE_MODULE:
675       // Executables and loadable modules don't get linked to, but the first
676       // output is used for dependency management.
677       CHECK_GE(tool->outputs().list().size(), 1u);
678       check_tool_outputs = true;
679       dependency_output_file_ =
680           SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
681               this, tool, tool->outputs().list()[0]);
682 
683       if (tool->runtime_outputs().list().empty()) {
684         // Default to the first output for the runtime output.
685         runtime_outputs_.push_back(dependency_output_file_);
686       } else {
687         SubstitutionWriter::ApplyListToLinkerAsOutputFile(
688             this, tool, tool->runtime_outputs(), &runtime_outputs_);
689       }
690       break;
691     case RUST_LIBRARY:
692     case STATIC_LIBRARY:
693       // Static libraries both have dependencies and linking going off of the
694       // first output.
695       CHECK(tool->outputs().list().size() >= 1);
696       check_tool_outputs = true;
697       link_output_file_ = dependency_output_file_ =
698           SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
699               this, tool, tool->outputs().list()[0]);
700       break;
701     case RUST_PROC_MACRO:
702     case SHARED_LIBRARY:
703       CHECK(tool->outputs().list().size() >= 1);
704       check_tool_outputs = true;
705       if (const CTool* ctool = tool->AsC()) {
706         if (ctool->link_output().empty() && ctool->depend_output().empty()) {
707           // Default behavior, use the first output file for both.
708           link_output_file_ = dependency_output_file_ =
709               SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
710                   this, tool, tool->outputs().list()[0]);
711         } else {
712           // Use the tool-specified ones.
713           if (!ctool->link_output().empty()) {
714             link_output_file_ =
715                 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
716                     this, tool, ctool->link_output());
717           }
718           if (!ctool->depend_output().empty()) {
719             dependency_output_file_ =
720                 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
721                     this, tool, ctool->depend_output());
722           }
723         }
724         if (tool->runtime_outputs().list().empty()) {
725           // Default to the link output for the runtime output.
726           runtime_outputs_.push_back(link_output_file_);
727         } else {
728           SubstitutionWriter::ApplyListToLinkerAsOutputFile(
729               this, tool, tool->runtime_outputs(), &runtime_outputs_);
730         }
731       } else if (const RustTool* rstool = tool->AsRust()) {
732         // Default behavior, use the first output file for both.
733         link_output_file_ = dependency_output_file_ =
734             SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
735                 this, tool, tool->outputs().list()[0]);
736       }
737       break;
738     case UNKNOWN:
739     default:
740       NOTREACHED();
741   }
742 
743   // Count anything generated from bundle_data dependencies.
744   if (output_type_ == CREATE_BUNDLE) {
745     if (!bundle_data_.GetOutputFiles(settings(), this, &computed_outputs_, err))
746       return false;
747   }
748 
749   // Count all outputs from this tool as something generated by this target.
750   if (check_tool_outputs) {
751     SubstitutionWriter::ApplyListToLinkerAsOutputFile(
752         this, tool, tool->outputs(), &computed_outputs_);
753 
754     // Output names aren't canonicalized in the same way that source files
755     // are. For example, the tool outputs often use
756     // {{some_var}}/{{output_name}} which expands to "./foo", but this won't
757     // match "foo" which is what we'll compute when converting a SourceFile to
758     // an OutputFile.
759     for (auto& out : computed_outputs_)
760       NormalizePath(&out.value());
761   }
762 
763   // Also count anything the target has declared to be an output.
764   std::vector<SourceFile> outputs_as_sources;
765   action_values_.GetOutputsAsSourceFiles(this, &outputs_as_sources);
766   for (const SourceFile& out : outputs_as_sources)
767     computed_outputs_.push_back(OutputFile(settings()->build_settings(), out));
768 
769   return true;
770 }
771 
ResolvePrecompiledHeaders(Err * err)772 bool Target::ResolvePrecompiledHeaders(Err* err) {
773   // Precompiled headers are stored on a ConfigValues struct. This way, the
774   // build can set all the precompiled header settings in a config and apply
775   // it to many targets. Likewise, the precompiled header values may be
776   // specified directly on a target.
777   //
778   // Unlike other values on configs which are lists that just get concatenated,
779   // the precompiled header settings are unique values. We allow them to be
780   // specified anywhere, but if they are specified in more than one place all
781   // places must match.
782 
783   // Track where the current settings came from for issuing errors.
784   const Label* pch_header_settings_from = NULL;
785   if (config_values_.has_precompiled_headers())
786     pch_header_settings_from = &label();
787 
788   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
789     if (!iter.GetCurrentConfig())
790       continue;  // Skip the one on the target itself.
791 
792     const Config* config = iter.GetCurrentConfig();
793     const ConfigValues& cur = config->resolved_values();
794     if (!cur.has_precompiled_headers())
795       continue;  // This one has no precompiled header info, skip.
796 
797     if (config_values_.has_precompiled_headers()) {
798       // Already have a precompiled header values, the settings must match.
799       if (config_values_.precompiled_header() != cur.precompiled_header() ||
800           config_values_.precompiled_source() != cur.precompiled_source()) {
801         *err = Err(
802             defined_from(), "Precompiled header setting conflict.",
803             "The target " + label().GetUserVisibleName(false) +
804                 "\n"
805                 "has conflicting precompiled header settings.\n"
806                 "\n"
807                 "From " +
808                 pch_header_settings_from->GetUserVisibleName(false) +
809                 "\n  header: " + config_values_.precompiled_header() +
810                 "\n  source: " + config_values_.precompiled_source().value() +
811                 "\n\n"
812                 "From " +
813                 config->label().GetUserVisibleName(false) +
814                 "\n  header: " + cur.precompiled_header() +
815                 "\n  source: " + cur.precompiled_source().value());
816         return false;
817       }
818     } else {
819       // Have settings from a config, apply them to ourselves.
820       pch_header_settings_from = &config->label();
821       config_values_.set_precompiled_header(cur.precompiled_header());
822       config_values_.set_precompiled_source(cur.precompiled_source());
823     }
824   }
825 
826   return true;
827 }
828 
CheckVisibility(Err * err) const829 bool Target::CheckVisibility(Err* err) const {
830   for (const auto& pair : GetDeps(DEPS_ALL)) {
831     if (!Visibility::CheckItemVisibility(this, pair.ptr, err))
832       return false;
833   }
834   return true;
835 }
836 
CheckTestonly(Err * err) const837 bool Target::CheckTestonly(Err* err) const {
838   // If the current target is marked testonly, it can include both testonly
839   // and non-testonly targets, so there's nothing to check.
840   if (testonly())
841     return true;
842 
843   // Verify no deps have "testonly" set.
844   for (const auto& pair : GetDeps(DEPS_ALL)) {
845     if (pair.ptr->testonly()) {
846       *err = MakeTestOnlyError(this, pair.ptr);
847       return false;
848     }
849   }
850 
851   return true;
852 }
853 
CheckAssertNoDeps(Err * err) const854 bool Target::CheckAssertNoDeps(Err* err) const {
855   if (assert_no_deps_.empty())
856     return true;
857 
858   std::set<const Target*> visited;
859   std::string failure_path_str;
860   const LabelPattern* failure_pattern = nullptr;
861 
862   if (!RecursiveCheckAssertNoDeps(this, false, assert_no_deps_, &visited,
863                                   &failure_path_str, &failure_pattern)) {
864     *err = Err(
865         defined_from(), "assert_no_deps failed.",
866         label().GetUserVisibleName(false) +
867             " has an assert_no_deps entry:\n  " + failure_pattern->Describe() +
868             "\nwhich fails for the dependency path:\n" + failure_path_str);
869     return false;
870   }
871   return true;
872 }
873 
CheckSourcesGenerated() const874 void Target::CheckSourcesGenerated() const {
875   // Checks that any inputs or sources to this target that are in the build
876   // directory are generated by a target that this one transitively depends on
877   // in some way. We already guarantee that all generated files are written
878   // to the build dir.
879   //
880   // See Scheduler::AddUnknownGeneratedInput's declaration for more.
881   for (const SourceFile& file : sources_)
882     CheckSourceGenerated(file);
883   for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
884     for (const SourceFile& file : iter.cur().inputs())
885       CheckSourceGenerated(file);
886   }
887   // TODO(agrieve): Check all_libs_ here as well (those that are source files).
888   // http://crbug.com/571731
889 }
890 
CheckSourceGenerated(const SourceFile & source) const891 void Target::CheckSourceGenerated(const SourceFile& source) const {
892   if (!IsStringInOutputDir(settings()->build_settings()->build_dir(),
893                            source.value()))
894     return;  // Not in output dir, this is OK.
895 
896   // Tell the scheduler about unknown files. This will be noted for later so
897   // the list of files written by the GN build itself (often response files)
898   // can be filtered out of this list.
899   OutputFile out_file(settings()->build_settings(), source);
900   std::set<const Target*> seen_targets;
901   bool check_data_deps = false;
902   bool consider_object_files = false;
903   if (!EnsureFileIsGeneratedByDependency(this, out_file, true,
904                                          consider_object_files, check_data_deps,
905                                          &seen_targets)) {
906     seen_targets.clear();
907     // Allow dependency to be through data_deps for files generated by gn.
908     check_data_deps =
909         g_scheduler->IsFileGeneratedByWriteRuntimeDeps(out_file) ||
910         g_scheduler->IsFileGeneratedByTarget(source);
911     // Check object files (much slower and very rare) only if the "normal"
912     // output check failed.
913     consider_object_files = !check_data_deps;
914     if (!EnsureFileIsGeneratedByDependency(this, out_file, true,
915                                            consider_object_files,
916                                            check_data_deps, &seen_targets))
917       g_scheduler->AddUnknownGeneratedInput(this, source);
918   }
919 }
920 
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,std::set<const Target * > * targets_walked,Err * err) const921 bool Target::GetMetadata(const std::vector<std::string>& keys_to_extract,
922                          const std::vector<std::string>& keys_to_walk,
923                          const SourceDir& rebase_dir,
924                          bool deps_only,
925                          std::vector<Value>* result,
926                          std::set<const Target*>* targets_walked,
927                          Err* err) const {
928   std::vector<Value> next_walk_keys;
929   std::vector<Value> current_result;
930   // If deps_only, this is the top-level target and thus we don't want to
931   // collect its metadata, only that of its deps and data_deps.
932   if (deps_only) {
933     // Empty string will be converted below to mean all deps and data_deps.
934     // Origin is null because this isn't declared anywhere, and should never
935     // trigger any errors.
936     next_walk_keys.push_back(Value(nullptr, ""));
937   } else {
938     // Otherwise, we walk this target and collect the appropriate data.
939     if (!metadata_.WalkStep(settings()->build_settings(), keys_to_extract,
940                             keys_to_walk, rebase_dir, &next_walk_keys,
941                             &current_result, err))
942       return false;
943   }
944 
945   // Gather walk keys and find the appropriate target. Targets identified in
946   // the walk key set must be deps or data_deps of the declaring target.
947   const DepsIteratorRange& all_deps = GetDeps(Target::DEPS_ALL);
948   const SourceDir& current_dir = label().dir();
949   for (const auto& next : next_walk_keys) {
950     DCHECK(next.type() == Value::STRING);
951 
952     // If we hit an empty string in this list, add all deps and data_deps. The
953     // ordering in the resulting list of values as a result will be the data
954     // from each explicitly listed dep prior to this, followed by all data in
955     // walk order of the remaining deps.
956     if (next.string_value().empty()) {
957       for (const auto& dep : all_deps) {
958         // If we haven't walked this dep yet, go down into it.
959         auto pair = targets_walked->insert(dep.ptr);
960         if (pair.second) {
961           if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
962                                     false, result, targets_walked, err))
963             return false;
964         }
965       }
966 
967       // Any other walk keys are superfluous, as they can only be a subset of
968       // all deps.
969       break;
970     }
971 
972     // Otherwise, look through the target's deps for the specified one.
973     // Canonicalize the label if possible.
974     Label next_label = Label::Resolve(
975         current_dir, settings()->build_settings()->root_path_utf8(),
976         settings()->toolchain_label(), next, err);
977     if (next_label.is_null()) {
978       *err = Err(next.origin(), std::string("Failed to canonicalize ") +
979                                     next.string_value() + std::string("."));
980     }
981     std::string canonicalize_next_label = next_label.GetUserVisibleName(true);
982 
983     bool found_next = false;
984     for (const auto& dep : all_deps) {
985       // Match against the label with the toolchain.
986       if (dep.label.GetUserVisibleName(true) == canonicalize_next_label) {
987         // If we haven't walked this dep yet, go down into it.
988         auto pair = targets_walked->insert(dep.ptr);
989         if (pair.second) {
990           if (!dep.ptr->GetMetadata(keys_to_extract, keys_to_walk, rebase_dir,
991                                     false, result, targets_walked, err))
992             return false;
993         }
994         // We found it, so we can exit this search now.
995         found_next = true;
996         break;
997       }
998     }
999     // If we didn't find the specified dep in the target, that's an error.
1000     // Propagate it back to the user.
1001     if (!found_next) {
1002       *err = Err(next.origin(),
1003                  std::string("I was expecting ") + canonicalize_next_label +
1004                      std::string(" to be a dependency of ") +
1005                      label().GetUserVisibleName(true) +
1006                      ". Make sure it's included in the deps or data_deps, and "
1007                      "that you've specified the appropriate toolchain.");
1008       return false;
1009     }
1010   }
1011   result->insert(result->end(), std::make_move_iterator(current_result.begin()),
1012                  std::make_move_iterator(current_result.end()));
1013   return true;
1014 }
1015