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
7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/files/file_path.h"
8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/logging.h"
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/build_settings.h"
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config.h"
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config_values_generator.h"
12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h"
13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/filesystem_utils.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/input_file.h"
16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/item_node.h"
17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/ninja_target_writer.h"
18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h"
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h"
20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h"
21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target_manager.h"
22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h"
23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h"
24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value_extractors.h"
253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "tools/gn/variables.h"
26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace {
28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool TypeHasConfigs(Target::OutputType type) {
30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return type == Target::EXECUTABLE ||
31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch         type == Target::SHARED_LIBRARY ||
32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch         type == Target::STATIC_LIBRARY ||
33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch         type == Target::LOADABLE_MODULE;
34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool TypeHasConfigValues(Target::OutputType type) {
37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return type == Target::EXECUTABLE ||
38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch         type == Target::SHARED_LIBRARY ||
39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch         type == Target::STATIC_LIBRARY ||
40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch         type == Target::LOADABLE_MODULE;
41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool TypeHasSources(Target::OutputType type) {
44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return type != Target::NONE;
45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool TypeHasData(Target::OutputType type) {
48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return type != Target::NONE;
49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool TypeHasDestDir(Target::OutputType type) {
52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return type == Target::COPY_FILES;
53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool TypeHasOutputs(Target::OutputType type) {
56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return type == Target::CUSTOM;
57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}  // namespace
60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
61d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTargetGenerator::TargetGenerator(Target* target,
62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 Scope* scope,
63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 const Token& function_token,
64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 const std::vector<Value>& args,
65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 const std::string& output_type,
66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 Err* err)
67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    : target_(target),
68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      scope_(scope),
69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      function_token_(function_token),
70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      args_(args),
71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      output_type_(output_type),
72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      err_(err),
73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      input_directory_(function_token.location().file()->dir()) {
74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
76d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTargetGenerator::~TargetGenerator() {
77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::Run() {
80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Output type.
81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Target::OutputType output_type = GetOutputType();
82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->set_output_type(output_type);
83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (err_->has_error())
84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (TypeHasConfigs(output_type)) {
87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillConfigs();
88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillAllDependentConfigs();
89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillDirectDependentConfigs();
90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
91d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (TypeHasSources(output_type))
92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillSources();
93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (TypeHasData(output_type))
94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillData();
95d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type == Target::CUSTOM) {
96d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillScript();
97d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillScriptArgs();
98d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
99d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (TypeHasOutputs(output_type))
100d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillOutputs();
101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  FillDependencies();  // All types have dependencies.
1023240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FillDataDependencies();  // All types have dependencies.
103d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (TypeHasConfigValues(output_type)) {
105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    ConfigValuesGenerator gen(&target_->config_values(), scope_,
106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                              function_token_, input_directory_, err_);
107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    gen.Run();
108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (err_->has_error())
109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return;
110d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (TypeHasDestDir(output_type))
113d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    FillDestDir();
114d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Set the toolchain as a dependency of the target.
116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // TODO(brettw) currently we lock separately for each config, dep, and
117d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // toolchain we add which is bad! Do this in one lock.
118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  {
119d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    ItemTree* tree = &GetBuildSettings()->item_tree();
120d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    base::AutoLock lock(tree->lock());
121d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    ItemNode* tc_node =
122d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        tree->GetExistingNodeLocked(ToolchainLabelForScope(scope_));
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (!tree->GetExistingNodeLocked(target_->label())->AddDependency(
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            GetBuildSettings(), function_token_.range(), tc_node, err_))
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return;
126d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
127d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
128d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->SetGenerated(&function_token_);
129d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  GetBuildSettings()->target_manager().TargetGenerationComplete(
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      target_->label(), err_);
131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
132d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
133d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static
134d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::GenerateTarget(Scope* scope,
135d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const Token& function_token,
136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const std::vector<Value>& args,
137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const std::string& output_type,
138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     Err* err) {
139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Name is the argument to the function.
140d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (args.size() != 1u || args[0].type() != Value::STRING) {
141d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    *err = Err(function_token,
142d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "Target generator requires one string argument.",
143d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "Otherwise I'm not sure what to call this target.");
144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
146d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
147d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // The location of the target is the directory name with no slash at the end.
148d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // FIXME(brettw) validate name.
149d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Label& toolchain_label = ToolchainLabelForScope(scope);
150d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Label label(function_token.location().file()->dir(),
151d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch              args[0].string_value(),
152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch              toolchain_label.dir(), toolchain_label.name());
153d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
154d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (g_scheduler->verbose_logging())
155d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    g_scheduler->Log("Generating target", label.GetUserVisibleName(true));
156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Target* t = scope->settings()->build_settings()->target_manager().GetTarget(
158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      label, function_token.range(), NULL, err);
159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (err->has_error())
160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  TargetGenerator gen(t, scope, function_token, args, output_type, err);
163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gen.Run();
164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
166d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTarget::OutputType TargetGenerator::GetOutputType() const {
167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type_ == functions::kGroup)
168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Target::NONE;
169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type_ == functions::kExecutable)
170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Target::EXECUTABLE;
171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type_ == functions::kSharedLibrary)
172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Target::SHARED_LIBRARY;
173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type_ == functions::kStaticLibrary)
174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Target::STATIC_LIBRARY;
175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // TODO(brettw) what does loadable module mean?
176d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  //if (output_type_ == ???)
177d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  //  return Target::LOADABLE_MODULE;
178d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type_ == functions::kCopy)
179d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Target::COPY_FILES;
180d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (output_type_ == functions::kCustom)
181d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Target::CUSTOM;
182d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  *err_ = Err(function_token_, "Not a known output type",
184d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch              "I am very confused.");
185d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return Target::NONE;
186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillGenericConfigs(
189d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const char* var_name,
190d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    void (Target::*setter)(std::vector<const Config*>*)) {
191d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue(var_name, true);
192d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
193d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
194d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
195d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::vector<Label> labels;
196d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!ExtractListOfLabels(*value, input_directory_,
197d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                           ToolchainLabelForScope(scope_), &labels, err_))
198d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
199d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
200d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::vector<const Config*> dest_configs;
201d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  dest_configs.resize(labels.size());
202d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  for (size_t i = 0; i < labels.size(); i++) {
203d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    dest_configs[i] = Config::GetConfig(
204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        scope_->settings(),
205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        value->list_value()[i].origin()->GetRange(),
206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        labels[i], target_, err_);
207d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (err_->has_error())
208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return;
209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  (target_->*setter)(&dest_configs);
211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TargetGenerator::FillGenericDeps(
2143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    const char* var_name,
2153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    void (Target::*setter)(std::vector<const Target*>*)) {
2163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const Value* value = scope_->GetValue(var_name, true);
2173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (!value)
2183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
2193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::vector<Label> labels;
2213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (!ExtractListOfLabels(*value, input_directory_,
2223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                           ToolchainLabelForScope(scope_), &labels, err_))
2233240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    return;
2243240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2253240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  std::vector<const Target*> dest_deps;
2263240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  dest_deps.resize(labels.size());
2273240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < labels.size(); i++) {
2283240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    dest_deps[i] = GetBuildSettings()->target_manager().GetTarget(
2293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        labels[i], value->list_value()[i].origin()->GetRange(), target_, err_);
2303240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (err_->has_error())
2313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      return;
2323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
2333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
2343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  (target_->*setter)(&dest_deps);
2353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
2363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
237d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillConfigs() {
2383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FillGenericConfigs(variables::kConfigs, &Target::swap_in_configs);
239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
240d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
241d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillAllDependentConfigs() {
2423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FillGenericConfigs(variables::kAllDependentConfigs,
243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                     &Target::swap_in_all_dependent_configs);
244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillDirectDependentConfigs() {
2473240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FillGenericConfigs(variables::kDirectDependentConfigs,
248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                     &Target::swap_in_direct_dependent_configs);
249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
251d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillSources() {
2523240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const Value* value = scope_->GetValue(variables::kSources, true);
253d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
254d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
255d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
256d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Target::FileList dest_sources;
257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!ExtractListOfRelativeFiles(*value, input_directory_, &dest_sources,
258d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                  err_))
259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
260d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->swap_in_sources(&dest_sources);
261d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
262d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
263d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillData() {
2643240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // TODO(brettW) hook this up to the constant when we have cleaned up
2653240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  // how data files are used.
266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue("data", true);
267d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
268d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
269d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
270d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Target::FileList dest_data;
271d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!ExtractListOfRelativeFiles(*value, input_directory_, &dest_data,
272d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                  err_))
273d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
274d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->swap_in_data(&dest_data);
275d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
277d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillDependencies() {
2783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FillGenericDeps(variables::kDeps, &Target::swap_in_deps);
2793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
280d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2813240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid TargetGenerator::FillDataDependencies() {
2823240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  FillGenericDeps(variables::kDatadeps, &Target::swap_in_datadeps);
283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
284d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillDestDir() {
286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Destdir is required for all targets that use it.
287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue("destdir", true);
288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value) {
289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    *err_ = Err(function_token_, "This target type requires a \"destdir\".");
290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value->VerifyTypeIs(Value::STRING, err_))
293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
294d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
295d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!EnsureStringIsInOutputDir(
296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          GetBuildSettings()->build_dir(),
297d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          value->string_value(), *value, err_))
298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->set_destdir(SourceDir(value->string_value()));
300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
301d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
302d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillScript() {
303d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // If this gets called, the target type requires a script, so error out
304d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // if it doesn't have one.
305d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue("script", true);
306d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value) {
307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    *err_ = Err(function_token_, "This target type requires a \"script\".");
308d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value->VerifyTypeIs(Value::STRING, err_))
311d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
312d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
313d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->set_script(
314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      input_directory_.ResolveRelativeFile(value->string_value()));
315d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
316d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
317d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillScriptArgs() {
318d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue("args", true);
319d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
320d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
321d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
322d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::vector<std::string> args;
323d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!ExtractListOfStringValues(*value, &args, err_))
324d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
325d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->swap_in_script_args(&args);
326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
327d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
328d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::FillOutputs() {
329d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue("outputs", true);
330d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!value)
331d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
332d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
333d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Target::FileList outputs;
334d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!ExtractListOfRelativeFiles(*value, input_directory_, &outputs, err_))
335d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
336d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
337d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Validate that outputs are in the output dir.
338d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  CHECK(outputs.size() == value->list_value().size());
339d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  for (size_t i = 0; i < outputs.size(); i++) {
340d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (!EnsureStringIsInOutputDir(
341d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch            GetBuildSettings()->build_dir(),
342d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch            outputs[i].value(), value->list_value()[i], err_))
343d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return;
344d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
345d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  target_->swap_in_outputs(&outputs);
346d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
347d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
348d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst BuildSettings* TargetGenerator::GetBuildSettings() const {
349d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return scope_->settings()->build_settings();
350d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
351