target_generator.cc revision 58537e28ecd584eab876aee8be7156509866d23a
1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file.
4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target_generator.h"
6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/binary_target_generator.h"
8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/build_settings.h"
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/copy_target_generator.h"
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h"
12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h"
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/group_target_generator.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/item_node.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h"
16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h"
17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/script_target_generator.h"
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target_manager.h"
20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h"
21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h"
22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value_extractors.h"
233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "tools/gn/variables.h"
24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
25d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTargetGenerator::TargetGenerator(Target* target,
26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 Scope* scope,
27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 const Token& function_token,
28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 Err* err)
29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    : target_(target),
30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      scope_(scope),
31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      function_token_(function_token),
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      err_(err) {
33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
35d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTargetGenerator::~TargetGenerator() {
36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::Run() {
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // All target types use these.
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillDependentConfigs();
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillData();
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillDependencies();
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // To type-specific generation.
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DoRun();
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Mark the target as complete.
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!err_->has_error()) {
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    target_->SetGenerated(&function_token_);
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    GetBuildSettings()->target_manager().TargetGenerationComplete(
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        target_->label(), err_);
52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static
56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::GenerateTarget(Scope* scope,
57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const Token& function_token,
58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const std::vector<Value>& args,
59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const std::string& output_type,
60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     Err* err) {
61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Name is the argument to the function.
62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (args.size() != 1u || args[0].type() != Value::STRING) {
63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    *err = Err(function_token,
64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "Target generator requires one string argument.",
65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "Otherwise I'm not sure what to call this target.");
66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // The location of the target is the directory name with no slash at the end.
70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // FIXME(brettw) validate name.
71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Label& toolchain_label = ToolchainLabelForScope(scope);
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Label label(scope->GetSourceDir(), args[0].string_value(),
73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch              toolchain_label.dir(), toolchain_label.name());
74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (g_scheduler->verbose_logging())
76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    g_scheduler->Log("Generating target", label.GetUserVisibleName(true));
77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Target* target =
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      scope->settings()->build_settings()->target_manager().GetTarget(
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          label, function_token.range(), NULL, err);
81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (err->has_error())
82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create and call out to the proper generator.
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (output_type == functions::kCopy) {
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CopyTargetGenerator generator(target, scope, function_token, err);
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kCustom) {
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ScriptTargetGenerator generator(target, scope, function_token, err);
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kExecutable) {
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BinaryTargetGenerator generator(target, scope, function_token,
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    Target::EXECUTABLE, err);
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kGroup) {
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    GroupTargetGenerator generator(target, scope, function_token, err);
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kSharedLibrary) {
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BinaryTargetGenerator generator(target, scope, function_token,
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    Target::SHARED_LIBRARY, err);
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kStaticLibrary) {
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    BinaryTargetGenerator generator(target, scope, function_token,
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    Target::STATIC_LIBRARY, err);
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err = Err(function_token, "Not a known output type",
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               "I am very confused.");
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const BuildSettings* TargetGenerator::GetBuildSettings() const {
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scope_->settings()->build_settings();
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::FillSources() {
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const Value* value = scope_->GetValue(variables::kSources, true);
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!value)
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Target::FileList dest_sources;
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  scope_->GetSourceDir(), &dest_sources, err_))
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  target_->swap_in_sources(&dest_sources);
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TargetGenerator::FillSourcePrereqs() {
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const Value* value = scope_->GetValue(variables::kSourcePrereqs, true);
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!value)
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Target::FileList dest_reqs;
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                  scope_->GetSourceDir(), &dest_reqs, err_))
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  target_->swap_in_source_prereqs(&dest_reqs);
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::FillConfigs() {
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillGenericConfigs(variables::kConfigs, &Target::swap_in_configs);
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::FillDependentConfigs() {
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillGenericConfigs(variables::kAllDependentConfigs,
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     &Target::swap_in_all_dependent_configs);
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillGenericConfigs(variables::kDirectDependentConfigs,
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                     &Target::swap_in_direct_dependent_configs);
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::FillData() {
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(brettW) hook this up to the constant when we have cleaned up
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // how data files are used.
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const Value* value = scope_->GetValue(variables::kData, true);
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!value)
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
1573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Target::FileList dest_data;
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  scope_->GetSourceDir(), &dest_data, err_))
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return;
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  target_->swap_in_data(&dest_data);
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::FillDependencies() {
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillGenericDeps(variables::kDeps, &Target::swap_in_deps);
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillGenericDeps(variables::kDatadeps, &Target::swap_in_datadeps);
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // This is a list of dependent targets to have their configs fowarded, so
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // it goes here rather than in FillConfigs.
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FillForwardDependentConfigs();
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  FillHardDep();
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TargetGenerator::FillHardDep() {
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const Value* hard_dep_value = scope_->GetValue(variables::kHardDep, true);
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!hard_dep_value)
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!hard_dep_value->VerifyTypeIs(Value::BOOLEAN, err_))
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return;
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  target_->set_hard_dep(hard_dep_value->boolean_value());
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TargetGenerator::FillExternal() {
186424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const Value* value = scope_->GetValue(variables::kExternal, true);
187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!value)
188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!value->VerifyTypeIs(Value::BOOLEAN, err_))
190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return;
191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  target_->set_external(value->boolean_value());
192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
193424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::SetToolchainDependency() {
1953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(brettw) currently we lock separately for each config, dep, and
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // toolchain we add which is bad! Do this in one lock.
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ItemTree* tree = &GetBuildSettings()->item_tree();
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::AutoLock lock(tree->lock());
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ItemNode* tc_node =
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      tree->GetExistingNodeLocked(ToolchainLabelForScope(scope_));
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  target_->item_node()->AddDependency(
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetBuildSettings(), function_token_.range(), tc_node, err_);
203d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillGenericConfigs(
206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const char* var_name,
207d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    void (Target::*setter)(std::vector<const Config*>*)) {
208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue(var_name, true);
209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::vector<Label> labels;
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfLabels(*value, scope_->GetSourceDir(),
214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                           ToolchainLabelForScope(scope_), &labels, err_))
215d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
217d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::vector<const Config*> dest_configs;
218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  dest_configs.resize(labels.size());
219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  for (size_t i = 0; i < labels.size(); i++) {
220d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    dest_configs[i] = Config::GetConfig(
221d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        scope_->settings(),
222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        value->list_value()[i].origin()->GetRange(),
223d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        labels[i], target_, err_);
224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (err_->has_error())
225d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return;
226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  (target_->*setter)(&dest_configs);
228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TargetGenerator::FillGenericDeps(
2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const char* var_name,
2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    void (Target::*setter)(std::vector<const Target*>*)) {
2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const Value* value = scope_->GetValue(var_name, true);
2343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (!value)
2353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
2363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::vector<Label> labels;
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfLabels(*value, scope_->GetSourceDir(),
2393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           ToolchainLabelForScope(scope_), &labels, err_))
2403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
2413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::vector<const Target*> dest_deps;
2433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  dest_deps.resize(labels.size());
2443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < labels.size(); i++) {
2453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    dest_deps[i] = GetBuildSettings()->target_manager().GetTarget(
2463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        labels[i], value->list_value()[i].origin()->GetRange(), target_, err_);
2473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (err_->has_error())
2483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return;
2493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2503240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  (target_->*setter)(&dest_deps);
2523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void TargetGenerator::FillForwardDependentConfigs() {
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const Value* value = scope_->GetValue(
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      variables::kForwardDependentConfigsFrom, true);
257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::vector<Label> labels;
2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfLabels(*value, scope_->GetSourceDir(),
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                           ToolchainLabelForScope(scope_), &labels, err_))
263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
264d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const std::vector<const Target*>& deps = target_->deps();
2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We currently assume that the list is very small and do a brute-force
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // search in the deps for the labeled target. This could be optimized.
2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::vector<const Target*> forward_from_list;
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t label_index = 0; label_index < labels.size(); label_index++) {
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const Target* forward_from = NULL;
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    for (size_t dep_index = 0; dep_index < deps.size(); dep_index++) {
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (deps[dep_index]->label() == labels[label_index]) {
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        forward_from = deps[dep_index];
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        break;
2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!forward_from) {
2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *err_ = Err(value->list_value()[label_index],
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          "Can't forward from this target.",
2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          "forward_dependent_configs_from must contain a list of labels that\n"
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          "must all appear in the deps of the same target.");
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return;
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    forward_from_list.push_back(forward_from);
287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  target_->swap_in_forward_dependent_configs(&forward_from_list);
290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
296