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
723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "tools/gn/action_target_generator.h"
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/binary_target_generator.h"
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/build_settings.h"
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/copy_target_generator.h"
12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "tools/gn/filesystem_utils.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h"
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "tools/gn/group_target_generator.h"
16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h"
17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h"
18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h"
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h"
20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h"
21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value_extractors.h"
223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "tools/gn/variables.h"
23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
24d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTargetGenerator::TargetGenerator(Target* target,
25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 Scope* scope,
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                 const FunctionCallNode* function_call,
27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                 Err* err)
28d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    : target_(target),
29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      scope_(scope),
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      function_call_(function_call),
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      err_(err) {
32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
34d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochTargetGenerator::~TargetGenerator() {
35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::Run() {
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // All target types use these.
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillDependentConfigs())
40e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
41e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillData())
43e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
44e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillDependencies())
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillTestonly())
49e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!Visibility::FillItemVisibility(target_, scope_, err_))
52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return;
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Do type-specific generation.
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DoRun();
56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static
59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid TargetGenerator::GenerateTarget(Scope* scope,
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     const FunctionCallNode* function_call,
61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const std::vector<Value>& args,
62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     const std::string& output_type,
63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                     Err* err) {
64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Name is the argument to the function.
65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (args.size() != 1u || args[0].type() != Value::STRING) {
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *err = Err(function_call,
67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "Target generator requires one string argument.",
68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "Otherwise I'm not sure what to call this target.");
69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return;
70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // The location of the target is the directory name with no slash at the end.
73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // FIXME(brettw) validate name.
74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Label& toolchain_label = ToolchainLabelForScope(scope);
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Label label(scope->GetSourceDir(), args[0].string_value(),
76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch              toolchain_label.dir(), toolchain_label.name());
77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (g_scheduler->verbose_logging())
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    g_scheduler->Log("Defining target", label.GetUserVisibleName(true));
80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Target> target(new Target(scope->settings(), label));
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  target->set_defined_from(function_call);
83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create and call out to the proper generator.
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (output_type == functions::kCopy) {
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CopyTargetGenerator generator(target.get(), scope, function_call, err);
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else if (output_type == functions::kAction) {
8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ActionTargetGenerator generator(target.get(), scope, function_call,
9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                    Target::ACTION, err);
9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    generator.Run();
9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else if (output_type == functions::kActionForEach) {
9323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ActionTargetGenerator generator(target.get(), scope, function_call,
9423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                    Target::ACTION_FOREACH, err);
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kExecutable) {
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    BinaryTargetGenerator generator(target.get(), scope, function_call,
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    Target::EXECUTABLE, err);
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kGroup) {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GroupTargetGenerator generator(target.get(), scope, function_call, err);
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kSharedLibrary) {
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    BinaryTargetGenerator generator(target.get(), scope, function_call,
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    Target::SHARED_LIBRARY, err);
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else if (output_type == functions::kSourceSet) {
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    BinaryTargetGenerator generator(target.get(), scope, function_call,
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                    Target::SOURCE_SET, err);
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    generator.Run();
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (output_type == functions::kStaticLibrary) {
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    BinaryTargetGenerator generator(target.get(), scope, function_call,
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    Target::STATIC_LIBRARY, err);
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    generator.Run();
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *err = Err(function_call, "Not a known output type",
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               "I am very confused.");
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (err->has_error())
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Save this target for the file.
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Scope::ItemVector* collector = scope->GetItemCollector();
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!collector) {
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *err = Err(function_call, "Can't define a target in this context.");
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return;
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  collector->push_back(new scoped_ptr<Item>(target.PassAs<Item>()));
130d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
131d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const BuildSettings* TargetGenerator::GetBuildSettings() const {
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scope_->settings()->build_settings();
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillSources() {
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const Value* value = scope_->GetValue(variables::kSources, true);
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!value)
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Target::FileList dest_sources;
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  scope_->GetSourceDir(), &dest_sources, err_))
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  target_->sources().swap(dest_sources);
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillPublic() {
150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const Value* value = scope_->GetValue(variables::kPublic, true);
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!value)
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // If the public headers are defined, don't default to public.
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  target_->set_all_headers_public(false);
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  Target::FileList dest_public;
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  scope_->GetSourceDir(), &dest_public, err_))
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  target_->public_headers().swap(dest_public);
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillInputs() {
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const Value* value = scope_->GetValue(variables::kInputs, true);
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!value) {
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // Older versions used "source_prereqs". Allow use of this variable until
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // all callers are updated.
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // TODO(brettw) remove this eventually.
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    value = scope_->GetValue("source_prereqs", true);
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (!value)
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return true;
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  Target::FileList dest_inputs;
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                  scope_->GetSourceDir(), &dest_inputs, err_))
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  target_->inputs().swap(dest_inputs);
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillConfigs() {
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return FillGenericConfigs(variables::kConfigs, &target_->configs());
1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillDependentConfigs() {
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillGenericConfigs(variables::kAllDependentConfigs,
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          &target_->all_dependent_configs()))
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillGenericConfigs(variables::kPublicConfigs,
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          &target_->public_configs()))
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // "public_configs" was previously named "direct_dependent_configs", fall
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // back to that if public_configs was undefined.
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!scope_->GetValue(variables::kPublicConfigs, false)) {
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!FillGenericConfigs("direct_dependent_configs",
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            &target_->public_configs()))
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillData() {
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const Value* value = scope_->GetValue(variables::kData, true);
2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!value)
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Target::FileList dest_data;
2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  scope_->GetSourceDir(), &dest_data, err_))
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  target_->data().swap(dest_data);
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillDependencies() {
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillGenericDeps(variables::kDeps, &target_->private_deps()))
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillGenericDeps(variables::kPublicDeps, &target_->public_deps()))
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillGenericDeps(variables::kDataDeps, &target_->data_deps()))
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // "data_deps" was previously named "datadeps". For backwards-compat, read
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the old one if no "data_deps" were specified.
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!scope_->GetValue(variables::kDataDeps, false)) {
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!FillGenericDeps("datadeps", &target_->data_deps()))
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // This is a list of dependent targets to have their configs fowarded, so
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // it goes here rather than in FillConfigs.
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!FillForwardDependentConfigs())
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillTestonly() {
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Value* value = scope_->GetValue(variables::kTestonly, true);
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (value) {
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!value->VerifyTypeIs(Value::BOOLEAN, err_))
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    target_->set_testonly(value->boolean_value());
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillOutputs(bool allow_substitutions) {
252d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const Value* value = scope_->GetValue(variables::kOutputs, true);
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  if (!value)
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return true;
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SubstitutionList& outputs = target_->action_values().outputs();
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!outputs.Parse(*value, err_))
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!allow_substitutions) {
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Verify no substitutions were actually used.
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!outputs.required_types().empty()) {
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *err_ = Err(*value, "Source expansions not allowed here.",
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "The outputs of this target used source {{expansions}} but this "
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "targe type\ndoesn't support them. Just express the outputs "
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "literally.");
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Check the substitutions used are valid for this purpose.
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!EnsureValidSourcesSubstitutions(outputs.required_types(),
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       value->origin(), err_))
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return false;
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Validate that outputs are in the output dir.
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK(outputs.list().size() == value->list_value().size());
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (size_t i = 0; i < outputs.list().size(); i++) {
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!EnsureSubstitutionIsInOutputDir(outputs.list()[i],
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                         value->list_value()[i]))
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return false;
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return true;
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool TargetGenerator::EnsureSubstitutionIsInOutputDir(
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const SubstitutionPattern& pattern,
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const Value& original_value) {
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pattern.ranges().empty()) {
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Pattern is empty, error out (this prevents weirdness below).
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    *err_ = Err(original_value, "This has an empty value in it.");
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return false;
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (pattern.ranges()[0].type == SUBSTITUTION_LITERAL) {
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If the first thing is a literal, it must start with the output dir.
297d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    if (!EnsureStringIsInOutputDir(
298d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            GetBuildSettings()->build_dir(),
29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            pattern.ranges()[0].literal, original_value.origin(), err_))
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Otherwise, the first subrange must be a pattern that expands to
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // something in the output directory.
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!SubstitutionIsInOutputDir(pattern.ranges()[0].type)) {
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      *err_ = Err(original_value,
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "File is not inside output directory.",
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "The given file should be in the output directory. Normally you\n"
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "would specify\n\"$target_out_dir/foo\" or "
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          "\"{{source_gen_dir}}/foo\".");
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return false;
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
312d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
315d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
316d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillGenericConfigs(const char* var_name,
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                         UniqueVector<LabelConfigPair>* dest) {
319d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Value* value = scope_->GetValue(var_name, true);
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (value) {
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(),
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              ToolchainLabelForScope(scope_), dest, err_);
323d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return !err_->has_error();
325d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
326d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillGenericDeps(const char* var_name,
3280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                      LabelTargetVector* dest) {
3293240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const Value* value = scope_->GetValue(var_name, true);
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (value) {
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ExtractListOfLabels(*value, scope_->GetSourceDir(),
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                        ToolchainLabelForScope(scope_), dest, err_);
3333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  }
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return !err_->has_error();
3353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch}
3363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool TargetGenerator::FillForwardDependentConfigs() {
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const Value* value = scope_->GetValue(
3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      variables::kForwardDependentConfigsFrom, true);
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (value) {
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(),
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              ToolchainLabelForScope(scope_),
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              &target_->forward_dependent_configs(), err_);
344d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return !err_->has_error();
346d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
347