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"
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"
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"
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) +
55 "which is a complete static library can't depend on\n" +
56 to
->label().GetUserVisibleName(false) +
58 "which is a static library.\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()) {
85 // Check all public dependencies (don't do data ones since those are
87 for (const auto& pair
: target
->public_deps()) {
88 if (EnsureFileIsGeneratedByDependency(pair
.ptr
, file
, false,
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,
98 return true; // Found a path.
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),
113 toolchain_(nullptr) {
120 const char* Target::GetStringForOutputType(OutputType type
) {
129 return "Shared library";
131 return "Static library";
139 return "ActionForEach";
145 Target
* Target::AsTarget() {
149 const Target
* Target::AsTarget() const {
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
))
178 if (settings()->build_settings()->check_for_bad_items()) {
179 if (!CheckVisibility(err
))
181 if (!CheckTestonly(err
))
183 if (!CheckNoNestedStaticLibs(err
))
185 CheckSourcesGenerated();
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));
206 return DepsIteratorRange(DepsIterator(
207 &public_deps_
, &private_deps_
, &data_deps_
));
210 std::string
Target::GetComputedOutputName(bool include_prefix
) const {
212 << "Toolchain must be specified before getting the computed output name.";
214 const std::string
& name
= output_name_
.empty() ? label().name()
218 if (include_prefix
) {
219 const Tool
* tool
= toolchain_
->GetToolForTargetFinalOutput(this);
221 // Only add the prefix if the name doesn't already have it.
222 if (!base::StartsWith(name
, tool
->output_prefix(),
223 base::CompareCase::SENSITIVE
))
224 result
= tool
->output_prefix();
231 bool Target::SetToolchain(const Toolchain
* toolchain
, Err
* err
) {
233 DCHECK_NE(UNKNOWN
, output_type_
);
234 toolchain_
= toolchain
;
236 const Tool
* tool
= toolchain
->GetToolForTargetFinalOutput(this);
240 // Tool not specified for this target type.
242 *err
= Err(defined_from(), "This target uses an undefined tool.",
246 "uses toolchain %s\n"
247 "which doesn't have the tool \"%s\" defined.\n\n"
248 "Alas, I can not continue.",
249 label().GetUserVisibleName(false).c_str(),
250 GetStringForOutputType(output_type_
),
251 label().GetToolchainLabel().GetUserVisibleName(false).c_str(),
252 Toolchain::ToolTypeToName(
253 toolchain
->GetToolTypeForTargetFinalOutput(this)).c_str()));
258 void Target::PullDependentTarget(const Target
* dep
, bool is_public
) {
259 MergeAllDependentConfigsFrom(dep
, &configs_
, &all_dependent_configs_
);
260 MergePublicConfigsFrom(dep
, &configs_
);
262 // Direct dependent libraries.
263 if (dep
->output_type() == STATIC_LIBRARY
||
264 dep
->output_type() == SHARED_LIBRARY
||
265 dep
->output_type() == SOURCE_SET
)
266 inherited_libraries_
.Append(dep
, is_public
);
268 if (dep
->output_type() == SHARED_LIBRARY
) {
269 // Shared library dependendencies are inherited across public shared
270 // library boundaries.
273 // EXE -> INTERMEDIATE_SHLIB --[public]--> FINAL_SHLIB
274 // The EXE will also link to to FINAL_SHLIB. The public dependeny means
275 // that the EXE can use the headers in FINAL_SHLIB so the FINAL_SHLIB
276 // will need to appear on EXE's link line.
278 // However, if the dependency is private:
279 // EXE -> INTERMEDIATE_SHLIB --[private]--> FINAL_SHLIB
280 // the dependency will not be propogated because INTERMEDIATE_SHLIB is
281 // not granting permission to call functiosn from FINAL_SHLIB. If EXE
282 // wants to use functions (and link to) FINAL_SHLIB, it will need to do
285 // Static libraries and source sets aren't inherited across shared
286 // library boundaries because they will be linked into the shared
288 inherited_libraries_
.AppendPublicSharedLibraries(
289 dep
->inherited_libraries(), is_public
);
290 } else if (!dep
->IsFinal()) {
291 // The current target isn't linked, so propogate linked deps and
292 // libraries up the dependency tree.
293 inherited_libraries_
.AppendInherited(dep
->inherited_libraries(), is_public
);
295 // Inherited library settings.
296 all_lib_dirs_
.append(dep
->all_lib_dirs());
297 all_libs_
.append(dep
->all_libs());
301 void Target::PullDependentTargets() {
302 for (const auto& dep
: public_deps_
)
303 PullDependentTarget(dep
.ptr
, true);
304 for (const auto& dep
: private_deps_
)
305 PullDependentTarget(dep
.ptr
, false);
308 void Target::PullForwardedDependentConfigs() {
309 // Pull public configs from each of our dependency's public deps.
310 for (const auto& dep
: public_deps_
)
311 PullForwardedDependentConfigsFrom(dep
.ptr
);
313 // Forward public configs if explicitly requested.
314 for (const auto& dep
: forward_dependent_configs_
) {
315 const Target
* from_target
= dep
.ptr
;
317 // The forward_dependent_configs_ must be in the deps (public or private)
318 // already, so we don't need to bother copying to our configs, only
320 DCHECK(std::find_if(private_deps_
.begin(), private_deps_
.end(),
321 LabelPtrPtrEquals
<Target
>(from_target
)) !=
322 private_deps_
.end() ||
323 std::find_if(public_deps_
.begin(), public_deps_
.end(),
324 LabelPtrPtrEquals
<Target
>(from_target
)) !=
327 PullForwardedDependentConfigsFrom(from_target
);
331 void Target::PullForwardedDependentConfigsFrom(const Target
* from
) {
332 public_configs_
.Append(from
->public_configs().begin(),
333 from
->public_configs().end());
336 void Target::PullRecursiveHardDeps() {
337 for (const auto& pair
: GetDeps(DEPS_LINKED
)) {
338 if (pair
.ptr
->hard_dep())
339 recursive_hard_deps_
.insert(pair
.ptr
);
341 // Android STL doesn't like insert(begin, end) so do it manually.
342 // TODO(brettw) this can be changed to
343 // insert(iter.target()->begin(), iter.target()->end())
344 // when Android uses a better STL.
345 for (std::set
<const Target
*>::const_iterator cur
=
346 pair
.ptr
->recursive_hard_deps().begin();
347 cur
!= pair
.ptr
->recursive_hard_deps().end(); ++cur
)
348 recursive_hard_deps_
.insert(*cur
);
352 void Target::FillOutputFiles() {
353 const Tool
* tool
= toolchain_
->GetToolForTargetFinalOutput(this);
354 bool check_tool_outputs
= false;
355 switch (output_type_
) {
360 case ACTION_FOREACH
: {
361 // These don't get linked to and use stamps which should be the first
362 // entry in the outputs. These stamps are named
363 // "<target_out_dir>/<targetname>.stamp".
364 dependency_output_file_
= GetTargetOutputDirAsOutputFile(this);
365 dependency_output_file_
.value().append(GetComputedOutputName(true));
366 dependency_output_file_
.value().append(".stamp");
370 // Executables don't get linked to, but the first output is used for
371 // dependency management.
372 CHECK_GE(tool
->outputs().list().size(), 1u);
373 check_tool_outputs
= true;
374 dependency_output_file_
=
375 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
376 this, tool
, tool
->outputs().list()[0]);
379 // Static libraries both have dependencies and linking going off of the
381 CHECK(tool
->outputs().list().size() >= 1);
382 check_tool_outputs
= true;
383 link_output_file_
= dependency_output_file_
=
384 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
385 this, tool
, tool
->outputs().list()[0]);
388 CHECK(tool
->outputs().list().size() >= 1);
389 check_tool_outputs
= true;
390 if (tool
->link_output().empty() && tool
->depend_output().empty()) {
391 // Default behavior, use the first output file for both.
392 link_output_file_
= dependency_output_file_
=
393 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
394 this, tool
, tool
->outputs().list()[0]);
396 // Use the tool-specified ones.
397 if (!tool
->link_output().empty()) {
399 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
400 this, tool
, tool
->link_output());
402 if (!tool
->depend_output().empty()) {
403 dependency_output_file_
=
404 SubstitutionWriter::ApplyPatternToLinkerAsOutputFile(
405 this, tool
, tool
->depend_output());
414 // Count all outputs from this tool as something generated by this target.
415 if (check_tool_outputs
) {
416 SubstitutionWriter::ApplyListToLinkerAsOutputFile(
417 this, tool
, tool
->outputs(), &computed_outputs_
);
419 // Output names aren't canonicalized in the same way that source files
420 // are. For example, the tool outputs often use
421 // {{some_var}}/{{output_name}} which expands to "./foo", but this won't
422 // match "foo" which is what we'll compute when converting a SourceFile to
424 for (auto& out
: computed_outputs_
)
425 NormalizePath(&out
.value());
428 // Also count anything the target has declared to be an output.
429 std::vector
<SourceFile
> outputs_as_sources
;
430 action_values_
.GetOutputsAsSourceFiles(this, &outputs_as_sources
);
431 for (const SourceFile
& out
: outputs_as_sources
)
432 computed_outputs_
.push_back(OutputFile(settings()->build_settings(), out
));
435 bool Target::ResolvePrecompiledHeaders(Err
* err
) {
436 // Precompiled headers are stored on a ConfigValues struct. This way, the
437 // build can set all the precompiled header settings in a config and apply
438 // it to many targets. Likewise, the precompiled header values may be
439 // specified directly on a target.
441 // Unlike other values on configs which are lists that just get concatenated,
442 // the precompiled header settings are unique values. We allow them to be
443 // specified anywhere, but if they are specified in more than one place all
444 // places must match.
446 // Track where the current settings came from for issuing errors.
447 const Label
* pch_header_settings_from
= NULL
;
448 if (config_values_
.has_precompiled_headers())
449 pch_header_settings_from
= &label();
451 for (ConfigValuesIterator
iter(this); !iter
.done(); iter
.Next()) {
452 if (!iter
.GetCurrentConfig())
453 continue; // Skip the one on the target itself.
455 const Config
* config
= iter
.GetCurrentConfig();
456 const ConfigValues
& cur
= config
->config_values();
457 if (!cur
.has_precompiled_headers())
458 continue; // This one has no precompiled header info, skip.
460 if (config_values_
.has_precompiled_headers()) {
461 // Already have a precompiled header values, the settings must match.
462 if (config_values_
.precompiled_header() != cur
.precompiled_header() ||
463 config_values_
.precompiled_source() != cur
.precompiled_source()) {
464 *err
= Err(defined_from(),
465 "Precompiled header setting conflict.",
466 "The target " + label().GetUserVisibleName(false) + "\n"
467 "has conflicting precompiled header settings.\n"
469 "From " + pch_header_settings_from
->GetUserVisibleName(false) +
470 "\n header: " + config_values_
.precompiled_header() +
471 "\n source: " + config_values_
.precompiled_source().value() +
473 "From " + config
->label().GetUserVisibleName(false) +
474 "\n header: " + cur
.precompiled_header() +
475 "\n source: " + cur
.precompiled_source().value());
479 // Have settings from a config, apply them to ourselves.
480 pch_header_settings_from
= &config
->label();
481 config_values_
.set_precompiled_header(cur
.precompiled_header());
482 config_values_
.set_precompiled_source(cur
.precompiled_source());
489 bool Target::CheckVisibility(Err
* err
) const {
490 for (const auto& pair
: GetDeps(DEPS_ALL
)) {
491 if (!Visibility::CheckItemVisibility(this, pair
.ptr
, err
))
497 bool Target::CheckTestonly(Err
* err
) const {
498 // If the current target is marked testonly, it can include both testonly
499 // and non-testonly targets, so there's nothing to check.
503 // Verify no deps have "testonly" set.
504 for (const auto& pair
: GetDeps(DEPS_ALL
)) {
505 if (pair
.ptr
->testonly()) {
506 *err
= MakeTestOnlyError(this, pair
.ptr
);
514 bool Target::CheckNoNestedStaticLibs(Err
* err
) const {
515 // If the current target is not a complete static library, it can depend on
516 // static library targets with no problem.
517 if (!(output_type() == Target::STATIC_LIBRARY
&& complete_static_lib()))
520 // Verify no deps are static libraries.
521 for (const auto& pair
: GetDeps(DEPS_ALL
)) {
522 if (pair
.ptr
->output_type() == Target::STATIC_LIBRARY
) {
523 *err
= MakeStaticLibDepsError(this, pair
.ptr
);
528 // Verify no inherited libraries are static libraries.
529 for (const auto& lib
: inherited_libraries().GetOrdered()) {
530 if (lib
->output_type() == Target::STATIC_LIBRARY
) {
531 *err
= MakeStaticLibDepsError(this, lib
);
538 void Target::CheckSourcesGenerated() const {
539 // Checks that any inputs or sources to this target that are in the build
540 // directory are generated by a target that this one transitively depends on
541 // in some way. We already guarantee that all generated files are written
544 // See Scheduler::AddUnknownGeneratedInput's declaration for more.
545 for (const SourceFile
& file
: sources_
)
546 CheckSourceGenerated(file
);
547 for (const SourceFile
& file
: inputs_
)
548 CheckSourceGenerated(file
);
551 void Target::CheckSourceGenerated(const SourceFile
& source
) const {
552 if (!IsStringInOutputDir(settings()->build_settings()->build_dir(),
554 return; // Not in output dir, this is OK.
556 // Tell the scheduler about unknown files. This will be noted for later so
557 // the list of files written by the GN build itself (often response files)
558 // can be filtered out of this list.
559 OutputFile
out_file(settings()->build_settings(), source
);
560 std::set
<const Target
*> seen_targets
;
561 if (!EnsureFileIsGeneratedByDependency(this, out_file
, true, &seen_targets
))
562 g_scheduler
->AddUnknownGeneratedInput(this, source
);