Try to work around that clang/win bug in another file.
[chromium-blink-merge.git] / tools / gn / target.cc
bloba7a3d07d2063e1b49aca0505d4a419c911889fb9
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.
5 #include "tools/gn/target.h"
7 #include "base/bind.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "tools/gn/config_values_extractors.h"
11 #include "tools/gn/deps_iterator.h"
12 #include "tools/gn/filesystem_utils.h"
13 #include "tools/gn/scheduler.h"
14 #include "tools/gn/substitution_writer.h"
16 namespace {
18 typedef std::set<const Config*> ConfigSet;
20 // Merges the public configs from the given target to the given config list.
21 void MergePublicConfigsFrom(const Target* from_target,
22 UniqueVector<LabelConfigPair>* dest) {
23 const UniqueVector<LabelConfigPair>& pub = from_target->public_configs();
24 dest->Append(pub.begin(), pub.end());
27 // Like MergePublicConfigsFrom above except does the "all dependent" ones. This
28 // additionally adds all configs to the all_dependent_configs_ of the dest
29 // target given in *all_dest.
30 void MergeAllDependentConfigsFrom(const Target* from_target,
31 UniqueVector<LabelConfigPair>* dest,
32 UniqueVector<LabelConfigPair>* all_dest) {
33 for (const auto& pair : from_target->all_dependent_configs()) {
34 all_dest->push_back(pair);
35 dest->push_back(pair);
39 Err MakeTestOnlyError(const Target* from, const Target* to) {
40 return Err(from->defined_from(), "Test-only dependency not allowed.",
41 from->label().GetUserVisibleName(false) + "\n"
42 "which is NOT marked testonly can't depend on\n" +
43 to->label().GetUserVisibleName(false) + "\n"
44 "which is marked testonly. Only targets with \"testonly = true\"\n"
45 "can depend on other test-only targets.\n"
46 "\n"
47 "Either mark it test-only or don't do this dependency.");
50 Err MakeStaticLibDepsError(const Target* from, const Target* to) {
51 return Err(from->defined_from(),
52 "Complete static libraries can't depend on static libraries.",
53 from->label().GetUserVisibleName(false) +
54 "\n"
55 "which is a complete static library can't depend on\n" +
56 to->label().GetUserVisibleName(false) +
57 "\n"
58 "which is a static library.\n"
59 "\n"
60 "Use source sets for intermediate targets instead.");
63 // Set check_private_deps to true for the first invocation since a target
64 // can see all of its dependencies. For recursive invocations this will be set
65 // to false to follow only public dependency paths.
67 // Pass a pointer to an empty set for the first invocation. This will be used
68 // to avoid duplicate checking.
69 bool EnsureFileIsGeneratedByDependency(const Target* target,
70 const OutputFile& file,
71 bool check_private_deps,
72 std::set<const Target*>* seen_targets) {
73 if (seen_targets->find(target) != seen_targets->end())
74 return false; // Already checked this one and it's not found.
75 seen_targets->insert(target);
77 // Assume that we have relatively few generated inputs so brute-force
78 // searching here is OK. If this becomes a bottleneck, consider storing
79 // computed_outputs as a hash set.
80 for (const OutputFile& cur : target->computed_outputs()) {
81 if (file == cur)
82 return true;
85 // Check all public dependencies (don't do data ones since those are
86 // runtime-only).
87 for (const auto& pair : target->public_deps()) {
88 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
89 seen_targets))
90 return true; // Found a path.
93 // Only check private deps if requested.
94 if (check_private_deps) {
95 for (const auto& pair : target->private_deps()) {
96 if (EnsureFileIsGeneratedByDependency(pair.ptr, file, false,
97 seen_targets))
98 return true; // Found a path.
101 return false;
104 } // namespace
106 Target::Target(const Settings* settings, const Label& label)
107 : Item(settings, label),
108 output_type_(UNKNOWN),
109 all_headers_public_(true),
110 check_includes_(true),
111 complete_static_lib_(false),
112 testonly_(false),
113 toolchain_(nullptr) {
116 Target::~Target() {
119 // static
120 const char* Target::GetStringForOutputType(OutputType type) {
121 switch (type) {
122 case UNKNOWN:
123 return "Unknown";
124 case GROUP:
125 return "Group";
126 case EXECUTABLE:
127 return "Executable";
128 case SHARED_LIBRARY:
129 return "Shared library";
130 case STATIC_LIBRARY:
131 return "Static library";
132 case SOURCE_SET:
133 return "Source set";
134 case COPY_FILES:
135 return "Copy";
136 case ACTION:
137 return "Action";
138 case ACTION_FOREACH:
139 return "ActionForEach";
140 default:
141 return "";
145 Target* Target::AsTarget() {
146 return this;
149 const Target* Target::AsTarget() const {
150 return this;
153 bool Target::OnResolved(Err* err) {
154 DCHECK(output_type_ != UNKNOWN);
155 DCHECK(toolchain_) << "Toolchain should have been set before resolving.";
157 // Copy our own dependent configs to the list of configs applying to us.
158 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end());
159 MergePublicConfigsFrom(this, &configs_);
161 // Copy our own libs and lib_dirs to the final set. This will be from our
162 // target and all of our configs. We do this specially since these must be
163 // inherited through the dependency tree (other flags don't work this way).
164 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
165 const ConfigValues& cur = iter.cur();
166 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end());
167 all_libs_.append(cur.libs().begin(), cur.libs().end());
170 PullDependentTargets();
171 PullForwardedDependentConfigs();
172 PullRecursiveHardDeps();
173 if (!ResolvePrecompiledHeaders(err))
174 return false;
176 FillOutputFiles();
178 if (settings()->build_settings()->check_for_bad_items()) {
179 if (!CheckVisibility(err))
180 return false;
181 if (!CheckTestonly(err))
182 return false;
183 if (!CheckNoNestedStaticLibs(err))
184 return false;
185 CheckSourcesGenerated();
188 return true;
191 bool Target::IsLinkable() const {
192 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY;
195 bool Target::IsFinal() const {
196 return output_type_ == EXECUTABLE || output_type_ == SHARED_LIBRARY ||
197 (output_type_ == STATIC_LIBRARY && complete_static_lib_);
200 DepsIteratorRange Target::GetDeps(DepsIterationType type) const {
201 if (type == DEPS_LINKED) {
202 return DepsIteratorRange(DepsIterator(
203 &public_deps_, &private_deps_, nullptr));
205 // All deps.
206 return DepsIteratorRange(DepsIterator(
207 &public_deps_, &private_deps_, &data_deps_));
210 std::string Target::GetComputedOutputName(bool include_prefix) const {
211 DCHECK(toolchain_)
212 << "Toolchain must be specified before getting the computed output name.";
214 const std::string& name = output_name_.empty() ? label().name()
215 : output_name_;
217 std::string result;
218 if (include_prefix) {
219 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
220 if (tool) {
221 // Only add the prefix if the name doesn't already have it.
222 if (!base::StartsWithASCII(name, tool->output_prefix(), true))
223 result = tool->output_prefix();
226 result.append(name);
227 return result;
230 bool Target::SetToolchain(const Toolchain* toolchain, Err* err) {
231 DCHECK(!toolchain_);
232 DCHECK_NE(UNKNOWN, output_type_);
233 toolchain_ = toolchain;
235 const Tool* tool = toolchain->GetToolForTargetFinalOutput(this);
236 if (tool)
237 return true;
239 // Tool not specified for this target type.
240 if (err) {
241 *err = Err(defined_from(), "This target uses an undefined tool.",
242 base::StringPrintf(
243 "The target %s\n"
244 "of type \"%s\"\n"
245 "uses toolchain %s\n"
246 "which doesn't have the tool \"%s\" defined.\n\n"
247 "Alas, I can not continue.",
248 label().GetUserVisibleName(false).c_str(),
249 GetStringForOutputType(output_type_),
250 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
251 Toolchain::ToolTypeToName(
252 toolchain->GetToolTypeForTargetFinalOutput(this)).c_str()));
254 return false;
257 void Target::PullDependentTarget(const Target* dep, bool is_public) {
258 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_);
259 MergePublicConfigsFrom(dep, &configs_);
261 // Direct dependent libraries.
262 if (dep->output_type() == STATIC_LIBRARY ||
263 dep->output_type() == SHARED_LIBRARY ||
264 dep->output_type() == SOURCE_SET)
265 inherited_libraries_.Append(dep, is_public);
267 if (dep->output_type() == SHARED_LIBRARY) {
268 // Shared library dependendencies are inherited across public shared
269 // library boundaries.
271 // In this case:
272 // EXE -> INTERMEDIATE_SHLIB --[public]--> FINAL_SHLIB
273 // The EXE will also link to to FINAL_SHLIB. The public dependeny means
274 // that the EXE can use the headers in FINAL_SHLIB so the FINAL_SHLIB
275 // will need to appear on EXE's link line.
277 // However, if the dependency is private:
278 // EXE -> INTERMEDIATE_SHLIB --[private]--> FINAL_SHLIB
279 // the dependency will not be propogated because INTERMEDIATE_SHLIB is
280 // not granting permission to call functiosn from FINAL_SHLIB. If EXE
281 // wants to use functions (and link to) FINAL_SHLIB, it will need to do
282 // so explicitly.
284 // Static libraries and source sets aren't inherited across shared
285 // library boundaries because they will be linked into the shared
286 // library.
287 inherited_libraries_.AppendPublicSharedLibraries(
288 dep->inherited_libraries(), is_public);
289 } else if (!dep->IsFinal()) {
290 // The current target isn't linked, so propogate linked deps and
291 // libraries up the dependency tree.
292 inherited_libraries_.AppendInherited(dep->inherited_libraries(), is_public);
294 // Inherited library settings.
295 all_lib_dirs_.append(dep->all_lib_dirs());
296 all_libs_.append(dep->all_libs());
300 void Target::PullDependentTargets() {
301 for (const auto& dep : public_deps_)
302 PullDependentTarget(dep.ptr, true);
303 for (const auto& dep : private_deps_)
304 PullDependentTarget(dep.ptr, false);
307 void Target::PullForwardedDependentConfigs() {
308 // Pull public configs from each of our dependency's public deps.
309 for (const auto& dep : public_deps_)
310 PullForwardedDependentConfigsFrom(dep.ptr);
312 // Forward public configs if explicitly requested.
313 for (const auto& dep : forward_dependent_configs_) {
314 const Target* from_target = dep.ptr;
316 // The forward_dependent_configs_ must be in the deps (public or private)
317 // already, so we don't need to bother copying to our configs, only
318 // forwarding.
319 DCHECK(std::find_if(private_deps_.begin(), private_deps_.end(),
320 LabelPtrPtrEquals<Target>(from_target)) !=
321 private_deps_.end() ||
322 std::find_if(public_deps_.begin(), public_deps_.end(),
323 LabelPtrPtrEquals<Target>(from_target)) !=
324 public_deps_.end());
326 PullForwardedDependentConfigsFrom(from_target);
330 void Target::PullForwardedDependentConfigsFrom(const Target* from) {
331 public_configs_.Append(from->public_configs().begin(),
332 from->public_configs().end());
335 void Target::PullRecursiveHardDeps() {
336 for (const auto& pair : GetDeps(DEPS_LINKED)) {
337 if (pair.ptr->hard_dep())
338 recursive_hard_deps_.insert(pair.ptr);
340 // Android STL doesn't like insert(begin, end) so do it manually.
341 // TODO(brettw) this can be changed to
342 // insert(iter.target()->begin(), iter.target()->end())
343 // when Android uses a better STL.
344 for (std::set<const Target*>::const_iterator cur =
345 pair.ptr->recursive_hard_deps().begin();
346 cur != pair.ptr->recursive_hard_deps().end(); ++cur)
347 recursive_hard_deps_.insert(*cur);
351 void Target::FillOutputFiles() {
352 const Tool* tool = toolchain_->GetToolForTargetFinalOutput(this);
353 bool check_tool_outputs = false;
354 switch (output_type_) {
355 case GROUP:
356 case SOURCE_SET:
357 case COPY_FILES:
358 case ACTION:
359 case ACTION_FOREACH: {
360 // These don't get linked to and use stamps which should be the first
361 // entry in the outputs. These stamps are named
362 // "<target_out_dir>/<targetname>.stamp".
363 dependency_output_file_ = GetTargetOutputDirAsOutputFile(this);
364 dependency_output_file_.value().append(GetComputedOutputName(true));
365 dependency_output_file_.value().append(".stamp");
366 break;
368 case EXECUTABLE:
369 // Executables don't get linked to, but the first output is used for
370 // dependency management.
371 CHECK_GE(tool->outputs().list().size(), 1u);
372 check_tool_outputs = true;
373 dependency_output_file_ =
374 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
375 this, tool, tool->outputs().list()[0]);
376 break;
377 case STATIC_LIBRARY:
378 // Static libraries both have dependencies and linking going off of the
379 // first output.
380 CHECK(tool->outputs().list().size() >= 1);
381 check_tool_outputs = true;
382 link_output_file_ = dependency_output_file_ =
383 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
384 this, tool, tool->outputs().list()[0]);
385 break;
386 case SHARED_LIBRARY:
387 CHECK(tool->outputs().list().size() >= 1);
388 check_tool_outputs = true;
389 if (tool->link_output().empty() && tool->depend_output().empty()) {
390 // Default behavior, use the first output file for both.
391 link_output_file_ = dependency_output_file_ =
392 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
393 this, tool, tool->outputs().list()[0]);
394 } else {
395 // Use the tool-specified ones.
396 if (!tool->link_output().empty()) {
397 link_output_file_ =
398 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
399 this, tool, tool->link_output());
401 if (!tool->depend_output().empty()) {
402 dependency_output_file_ =
403 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
404 this, tool, tool->depend_output());
407 break;
408 case UNKNOWN:
409 default:
410 NOTREACHED();
413 // Count all outputs from this tool as something generated by this target.
414 if (check_tool_outputs) {
415 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
416 this, tool, tool->outputs(), &computed_outputs_);
418 // Output names aren't canonicalized in the same way that source files
419 // are. For example, the tool outputs often use
420 // {{some_var}}/{{output_name}} which expands to "./foo", but this won't
421 // match "foo" which is what we'll compute when converting a SourceFile to
422 // an OutputFile.
423 for (auto& out : computed_outputs_)
424 NormalizePath(&out.value());
427 // Also count anything the target has declared to be an output.
428 std::vector<SourceFile> outputs_as_sources;
429 action_values_.GetOutputsAsSourceFiles(this, &outputs_as_sources);
430 for (const SourceFile& out : outputs_as_sources)
431 computed_outputs_.push_back(OutputFile(settings()->build_settings(), out));
434 bool Target::ResolvePrecompiledHeaders(Err* err) {
435 // Precompiled headers are stored on a ConfigValues struct. This way, the
436 // build can set all the precompiled header settings in a config and apply
437 // it to many targets. Likewise, the precompiled header values may be
438 // specified directly on a target.
440 // Unlike other values on configs which are lists that just get concatenated,
441 // the precompiled header settings are unique values. We allow them to be
442 // specified anywhere, but if they are specified in more than one place all
443 // places must match.
445 // Track where the current settings came from for issuing errors.
446 const Label* pch_header_settings_from = NULL;
447 if (config_values_.has_precompiled_headers())
448 pch_header_settings_from = &label();
450 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) {
451 if (!iter.GetCurrentConfig())
452 continue; // Skip the one on the target itself.
454 const Config* config = iter.GetCurrentConfig();
455 const ConfigValues& cur = config->config_values();
456 if (!cur.has_precompiled_headers())
457 continue; // This one has no precompiled header info, skip.
459 if (config_values_.has_precompiled_headers()) {
460 // Already have a precompiled header values, the settings must match.
461 if (config_values_.precompiled_header() != cur.precompiled_header() ||
462 config_values_.precompiled_source() != cur.precompiled_source()) {
463 *err = Err(defined_from(),
464 "Precompiled header setting conflict.",
465 "The target " + label().GetUserVisibleName(false) + "\n"
466 "has conflicting precompiled header settings.\n"
467 "\n"
468 "From " + pch_header_settings_from->GetUserVisibleName(false) +
469 "\n header: " + config_values_.precompiled_header() +
470 "\n source: " + config_values_.precompiled_source().value() +
471 "\n\n"
472 "From " + config->label().GetUserVisibleName(false) +
473 "\n header: " + cur.precompiled_header() +
474 "\n source: " + cur.precompiled_source().value());
475 return false;
477 } else {
478 // Have settings from a config, apply them to ourselves.
479 pch_header_settings_from = &config->label();
480 config_values_.set_precompiled_header(cur.precompiled_header());
481 config_values_.set_precompiled_source(cur.precompiled_source());
485 return true;
488 bool Target::CheckVisibility(Err* err) const {
489 for (const auto& pair : GetDeps(DEPS_ALL)) {
490 if (!Visibility::CheckItemVisibility(this, pair.ptr, err))
491 return false;
493 return true;
496 bool Target::CheckTestonly(Err* err) const {
497 // If the current target is marked testonly, it can include both testonly
498 // and non-testonly targets, so there's nothing to check.
499 if (testonly())
500 return true;
502 // Verify no deps have "testonly" set.
503 for (const auto& pair : GetDeps(DEPS_ALL)) {
504 if (pair.ptr->testonly()) {
505 *err = MakeTestOnlyError(this, pair.ptr);
506 return false;
510 return true;
513 bool Target::CheckNoNestedStaticLibs(Err* err) const {
514 // If the current target is not a complete static library, it can depend on
515 // static library targets with no problem.
516 if (!(output_type() == Target::STATIC_LIBRARY && complete_static_lib()))
517 return true;
519 // Verify no deps are static libraries.
520 for (const auto& pair : GetDeps(DEPS_ALL)) {
521 if (pair.ptr->output_type() == Target::STATIC_LIBRARY) {
522 *err = MakeStaticLibDepsError(this, pair.ptr);
523 return false;
527 // Verify no inherited libraries are static libraries.
528 for (const auto& lib : inherited_libraries().GetOrdered()) {
529 if (lib->output_type() == Target::STATIC_LIBRARY) {
530 *err = MakeStaticLibDepsError(this, lib);
531 return false;
534 return true;
537 void Target::CheckSourcesGenerated() const {
538 // Checks that any inputs or sources to this target that are in the build
539 // directory are generated by a target that this one transitively depends on
540 // in some way. We already guarantee that all generated files are written
541 // to the build dir.
543 // See Scheduler::AddUnknownGeneratedInput's declaration for more.
544 for (const SourceFile& file : sources_)
545 CheckSourceGenerated(file);
546 for (const SourceFile& file : inputs_)
547 CheckSourceGenerated(file);
550 void Target::CheckSourceGenerated(const SourceFile& source) const {
551 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(),
552 source.value()))
553 return; // Not in output dir, this is OK.
555 // Tell the scheduler about unknown files. This will be noted for later so
556 // the list of files written by the GN build itself (often response files)
557 // can be filtered out of this list.
558 OutputFile out_file(settings()->build_settings(), source);
559 std::set<const Target*> seen_targets;
560 if (!EnsureFileIsGeneratedByDependency(this, out_file, true, &seen_targets))
561 g_scheduler->AddUnknownGeneratedInput(this, source);