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
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <algorithm>
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <limits>
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h"
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h"
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h"
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h"
12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h"
13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/settings.h"
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tools/gn/tool.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/toolchain.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "tools/gn/value_extractors.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "tools/gn/variables.h"
18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace functions {
20a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochnamespace {
22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// This is jsut a unique value to take the address of to use as the key for
24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// the toolchain property on a scope.
25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochconst int kToolchainPropertyKey = 0;
26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ReadBool(Scope* scope,
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              const char* var,
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              Tool* tool,
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              void (Tool::*set)(bool),
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)              Err* err) {
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Value* v = scope->GetValue(var, true);
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!v)
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;  // Not present is fine.
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!v->VerifyTypeIs(Value::BOOLEAN, err))
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  (tool->*set)(v->boolean_value());
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Reads the given string from the scope (if present) and puts the result into
43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// dest. If the value is not a string, sets the error and returns false.
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ReadString(Scope* scope,
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                const char* var,
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                Tool* tool,
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                void (Tool::*set)(const std::string&),
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                Err* err) {
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Value* v = scope->GetValue(var, true);
50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!v)
51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return true;  // Not present is fine.
52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!v->VerifyTypeIs(Value::STRING, err))
53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return false;
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  (tool->*set)(v->string_value());
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Calls the given validate function on each type in the list. On failure,
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// sets the error, blame the value, and return false.
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ValidateSubstitutionList(const std::vector<SubstitutionType>& list,
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              bool (*validate)(SubstitutionType),
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              const Value* origin,
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                              Err* err) {
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t i = 0; i < list.size(); i++) {
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    SubstitutionType cur_type = list[i];
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!validate(cur_type)) {
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *err = Err(*origin, "Pattern not valid here.",
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          "You used the pattern " + std::string(kSubstitutionNames[cur_type]) +
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          " which is not valid\nfor this variable.");
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return false;
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ReadPattern(Scope* scope,
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 const char* name,
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 bool (*validate)(SubstitutionType),
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 Tool* tool,
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 void (Tool::*set)(const SubstitutionPattern&),
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 Err* err) {
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Value* value = scope->GetValue(name, true);
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value)
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;  // Not present is fine.
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value->VerifyTypeIs(Value::STRING, err))
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SubstitutionPattern pattern;
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!pattern.Parse(*value, err))
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!ValidateSubstitutionList(pattern.required_types(), validate, value, err))
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  (tool->*set)(pattern);
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ReadOutputExtension(Scope* scope, Tool* tool, Err* err) {
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Value* value = scope->GetValue("default_output_extension", true);
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value)
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;  // Not present is fine.
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value->VerifyTypeIs(Value::STRING, err))
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (value->string_value().empty())
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;  // Accept empty string.
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (value->string_value()[0] != '.') {
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *err = Err(*value, "default_output_extension must begin with a '.'");
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  tool->set_default_output_extension(value->string_value());
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ReadDepsFormat(Scope* scope, Tool* tool, Err* err) {
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Value* value = scope->GetValue("depsformat", true);
12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value)
12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return true;  // Not present is fine.
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value->VerifyTypeIs(Value::STRING, err))
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (value->string_value() == "gcc") {
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    tool->set_depsformat(Tool::DEPS_GCC);
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else if (value->string_value() == "msvc") {
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    tool->set_depsformat(Tool::DEPS_MSVC);
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else {
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *err = Err(*value, "Deps format must be \"gcc\" or \"msvc\".");
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ReadOutputs(Scope* scope,
13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 const FunctionCallNode* tool_function,
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 bool (*validate)(SubstitutionType),
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 Tool* tool,
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 Err* err) {
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  const Value* value = scope->GetValue("outputs", true);
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!value) {
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *err = Err(tool_function, "\"outputs\" must be specified for this tool.");
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  SubstitutionList list;
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!list.Parse(*value, err))
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Validate the right kinds of patterns are used.
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!ValidateSubstitutionList(list.required_types(), validate, value, err))
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // There should always be at least one output.
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (list.list().empty()) {
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *err = Err(*value, "Outputs list is empty.", "I need some outputs.");
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return false;
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  tool->set_outputs(list);
162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return true;
163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool IsCompilerTool(Toolchain::ToolType type) {
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return type == Toolchain::TYPE_CC ||
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_CXX ||
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_OBJC ||
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_OBJCXX ||
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_RC ||
17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_ASM;
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool IsLinkerTool(Toolchain::ToolType type) {
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return type == Toolchain::TYPE_ALINK ||
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_SOLINK ||
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)         type == Toolchain::TYPE_LINK;
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool IsPatternInOutputList(const SubstitutionList& output_list,
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           const SubstitutionPattern& pattern) {
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (size_t output_i = 0; output_i < output_list.list().size(); output_i++) {
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const SubstitutionPattern& cur = output_list.list()[output_i];
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (pattern.ranges().size() == cur.ranges().size() &&
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        std::equal(pattern.ranges().begin(), pattern.ranges().end(),
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   cur.ranges().begin()))
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return true;
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return false;
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
192d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}  // namespace
193d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
194a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// toolchain -------------------------------------------------------------------
195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kToolchain[] = "toolchain";
197e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kToolchain_HelpShort[] =
198e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    "toolchain: Defines a toolchain.";
199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kToolchain_Help[] =
200d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "toolchain: Defines a toolchain.\n"
201d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
202d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  A toolchain is a set of commands and build flags used to compile the\n"
203d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  source code. You can have more than one toolchain in use at once in\n"
204d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  a build.\n"
205d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "Functions and variables\n"
207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "  tool()\n"
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    The tool() function call specifies the commands commands to run for\n"
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    a given step. See \"gn help tool\".\n"
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "  toolchain_args()\n"
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    List of arguments to pass to the toolchain when invoking this\n"
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    toolchain. This applies only to non-default toolchains. See\n"
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    \"gn help toolchain_args\" for more.\n"
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "  deps\n"
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    Dependencies of this toolchain. These dependencies will be resolved\n"
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    before any target in the toolchain is compiled. To avoid circular\n"
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    dependencies these must be targets defined in another toolchain.\n"
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    This is expressed as a list of targets, and generally these targets\n"
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    will always specify a toolchain:\n"
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "      deps = [ \"//foo/bar:baz(//build/toolchain:bootstrap)\" ]\n"
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    This concept is somewhat inefficient to express in Ninja (it\n"
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    requires a lot of duplicate of rules) so should only be used when\n"
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    absolutely necessary.\n"
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "  concurrent_links\n"
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    In integer expressing the number of links that Ninja will perform in\n"
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    parallel. GN will create a pool for shared library and executable\n"
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    link steps with this many processes. Since linking is memory- and\n"
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    I/O-intensive, projects with many large targets may want to limit\n"
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    the number of parallel steps to avoid overloading the computer.\n"
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    Since creating static libraries is generally not as intensive\n"
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    there is no limit to \"alink\" steps.\n"
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    Defaults to 0 which Ninja interprets as \"no limit\".\n"
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    The value used will be the one from the default toolchain of the\n"
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    current build.\n"
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    "\n"
244d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "Invoking targets in toolchains:\n"
245d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
246d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  By default, when a target depends on another, there is an implicit\n"
247d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  toolchain label that is inherited, so the dependee has the same one\n"
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    "  as the dependent.\n"
249d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
250d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  You can override this and refer to any other toolchain by explicitly\n"
251d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  labeling the toolchain to use. For example:\n"
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    data_deps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n"
253d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  The string \"//build/toolchains:plugin_toolchain\" is a label that\n"
254d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  identifies the toolchain declaration for compiling the sources.\n"
255d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
256d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  To load a file in an alternate toolchain, GN does the following:\n"
257d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
258d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "   1. Loads the file with the toolchain definition in it (as determined\n"
259d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      by the toolchain label).\n"
260d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "   2. Re-runs the master build configuration file, applying the\n"
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      arguments specified by the toolchain_args section of the toolchain\n"
262d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      definition (see \"gn help toolchain_args\").\n"
263d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "   3. Loads the destination build file in the context of the\n"
264d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      configuration file in the previous step.\n"
265d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
266d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "Example:\n"
267d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  toolchain(\"plugin_toolchain\") {\n"
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "    concurrent_links = 8\n"
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "\n"
270d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    tool(\"cc\") {\n"
271c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    "      command = \"gcc $in\"\n"
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    "      ...\n"
273d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    }\n"
274d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
275d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    toolchain_args() {\n"
276d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      is_plugin = true\n"
277d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      is_32bit = true\n"
278d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      is_64bit = false\n"
279d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    }\n"
280d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  }\n";
281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
282a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunToolchain(Scope* scope,
283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   const FunctionCallNode* function,
284a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   const std::vector<Value>& args,
285a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   BlockNode* block,
286a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                   Err* err) {
287d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!EnsureNotProcessingImport(function, scope, err) ||
288d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      !EnsureNotProcessingBuildConfig(function, scope, err))
289d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
290d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
291d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Note that we don't want to use MakeLabelForScope since that will include
292d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // the toolchain name in the label, and toolchain labels don't themselves
293d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // have toolchain names.
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const SourceDir& input_dir = scope->GetSourceDir();
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Label label(input_dir, args[0].string_value());
296d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (g_scheduler->verbose_logging())
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    g_scheduler->Log("Definining toolchain", label.GetUserVisibleName(false));
298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
299d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // This object will actually be copied into the one owned by the toolchain
300d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // manager, but that has to be done in the lock.
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<Toolchain> toolchain(new Toolchain(scope->settings(), label));
302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  toolchain->set_defined_from(function);
303e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  toolchain->visibility().SetPublic();
304d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
305d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Scope block_scope(scope);
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  block_scope.SetProperty(&kToolchainPropertyKey, toolchain.get());
307d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  block->ExecuteBlockInScope(&block_scope, err);
308d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  block_scope.SetProperty(&kToolchainPropertyKey, NULL);
309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (err->has_error())
310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Read deps (if any).
313116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const Value* deps_value = block_scope.GetValue(variables::kDeps, true);
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (deps_value) {
315116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ExtractListOfLabels(
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        *deps_value, block_scope.GetSourceDir(),
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ToolchainLabelForScope(&block_scope), &toolchain->deps(), err);
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (err->has_error())
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return Value();
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Read concurrent_links (if any).
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const Value* concurrent_links_value =
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      block_scope.GetValue("concurrent_links", true);
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (concurrent_links_value) {
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!concurrent_links_value->VerifyTypeIs(Value::INTEGER, err))
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return Value();
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (concurrent_links_value->int_value() < 0 ||
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        concurrent_links_value->int_value() > std::numeric_limits<int>::max()) {
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      *err = Err(*concurrent_links_value, "Value out of range.");
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return Value();
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    toolchain->set_concurrent_links(
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        static_cast<int>(concurrent_links_value->int_value()));
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
337d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!block_scope.CheckForUnusedVars(err))
338d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
339d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Save this toolchain.
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  toolchain->ToolchainSetupComplete();
342010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Scope::ItemVector* collector = scope->GetItemCollector();
343010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!collector) {
344010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    *err = Err(function, "Can't define a toolchain in this context.");
345010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return Value();
346010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
347010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  collector->push_back(new scoped_ptr<Item>(toolchain.PassAs<Item>()));
348d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return Value();
349d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
350d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// tool ------------------------------------------------------------------------
352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kTool[] = "tool";
354e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kTool_HelpShort[] =
355e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    "tool: Specify arguments to a toolchain tool.";
356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kTool_Help[] =
357d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "tool: Specify arguments to a toolchain tool.\n"
358d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Usage:\n"
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  tool(<tool type>) {\n"
36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    <tool variables...>\n"
36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  }\n"
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
36503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Tool types\n"
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
36703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    Compiler tools:\n"
36803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"cc\": C compiler\n"
36903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"cxx\": C++ compiler\n"
37003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"objc\": Objective C compiler\n"
37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"objcxx\": Objective C++ compiler\n"
37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"rc\": Resource compiler (Windows .rc files)\n"
37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"asm\": Assembler\n"
374d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    Linker tools:\n"
37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"alink\": Linker for static libraries (archives)\n"
37703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"solink\": Linker for shared libraries\n"
37803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"link\": Linker for executables\n"
379d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
38003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    Other tools:\n"
38103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"stamp\": Tool for creating stamp files\n"
38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      \"copy\": Tool to copy files.\n"
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "\n"
38403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Tool variables\n"
385116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    "\n"
38603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    command  [string with substitutions]\n"
38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: all tools (required)\n"
388d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The command to run.\n"
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    "\n"
39103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    default_output_extension  [string]\n"
39203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: linker tools\n"
39303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
39403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Extension for the main output of a linkable tool. It includes\n"
39503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        the leading dot. This will be the default value for the\n"
39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        {{output_extension}} expansion (discussed below) but will be\n"
39703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        overridden by by the \"output extension\" variable in a target,\n"
39803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        if one is specified. Empty string means no extension.\n"
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
40003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        GN doesn't actually do anything with this extension other than\n"
40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        pass it along, potentially with target-specific overrides. One\n"
40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        would typically use the {{output_extension}} value in the\n"
40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"outputs\" to read this value.\n"
4045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
40503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: default_output_extension = \".exe\"\n"
40603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
40703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    depfile  [string]\n"
40803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: compiler tools (optional)\n"
40903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
41003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        If the tool can write \".d\" files, this specifies the name of\n"
41103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        the resulting file. These files are used to list header file\n"
41203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        dependencies (or other implicit input dependencies) that are\n"
41303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        discovered at build time. See also \"depsformat\".\n"
41403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
41503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: depfile = \"{{output}}.d\"\n"
41603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
41703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    depsformat  [string]\n"
41803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: compiler tools (when depfile is specified)\n"
41903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
42003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Format for the deps outputs. This is either \"gcc\" or \"msvc\".\n"
42103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        See the ninja documentation for \"deps\" for more information.\n"
42203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
42303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: depsformat = \"gcc\"\n"
42403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
42503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    description  [string with substitutions, optional]\n"
42603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: all tools\n"
42703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
42803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        What to print when the command is run.\n"
42903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
43003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: description = \"Compiling {{source}}\"\n"
43103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
43203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    lib_switch  [string, optional, link tools only]\n"
43303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    lib_dir_switch  [string, optional, link tools only]\n"
43403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: Linker tools except \"alink\"\n"
4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
43603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        These strings will be prepended to the libraries and library\n"
43703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        search directories, respectively, because linkers differ on how\n"
43803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        specify them. If you specified:\n"
43903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          lib_switch = \"-l\"\n"
44003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          lib_dir_switch = \"-L\"\n"
44103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        then the \"{{libs}}\" expansion for [ \"freetype\", \"expat\"]\n"
44203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        would be \"-lfreetype -lexpat\".\n"
44303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
44403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    outputs  [list of strings with substitutions]\n"
44503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: Linker and compiler tools (required)\n"
44603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
44703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        An array of names for the output files the tool produces. These\n"
44803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        are relative to the build output directory. There must always be\n"
44903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        at least one output file. There can be more than one output (a\n"
45003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        linker might produce a library and an import library, for\n"
45103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        example).\n"
45203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
45303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        This array just declares to GN what files the tool will\n"
45403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        produce. It is your responsibility to specify the tool command\n"
45503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        that actually produces these files.\n"
45603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
45703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        If you specify more than one output for shared library links,\n"
45803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        you should consider setting link_output and depend_output.\n"
45903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Otherwise, the first entry in the outputs list should always be\n"
46003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        the main output which will be linked to.\n"
46103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
46203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example for a compiler tool that produces .obj files:\n"
46303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          outputs = [\n"
46403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "            \"{{source_out_dir}}/{{source_name_part}}.obj\"\n"
46503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          ]\n"
46603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
46703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example for a linker tool that produces a .dll and a .lib. The\n"
46803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        use of {{output_extension}} rather than hardcoding \".dll\"\n"
46903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        allows the extension of the library to be overridden on a\n"
47003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        target-by-target basis, but in this example, it always\n"
47103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        produces a \".lib\" import library:\n"
47203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          outputs = [\n"
47303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "            \"{{root_out_dir}}/{{target_output_name}}"
47403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     "{{output_extension}}\",\n"
47503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "            \"{{root_out_dir}}/{{target_output_name}}.lib\",\n"
47603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          ]\n"
47703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
47803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    link_output  [string with substitutions]\n"
47903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    depend_output  [string with substitutions]\n"
48003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: \"solink\" only (optional)\n"
48103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
48203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        These two files specify whch of the outputs from the solink\n"
48303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        tool should be used for linking and dependency tracking. These\n"
48403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        should match entries in the \"outputs\". If unspecified, the\n"
48503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        first item in the \"outputs\" array will be used for both. See\n"
48603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"Separate linking and dependencies for shared libraries\"\n"
48703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        below for more.\n"
48803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
48903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        On Windows, where the tools produce a .dll shared library and\n"
49003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        a .lib import library, you will want both of these to be the\n"
49103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        import library. On Linux, if you're not doing the separate\n"
49203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        linking/dependency optimization, both of these should be the\n"
49303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        .so output.\n"
49403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
49503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    output_prefix  [string]\n"
49603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: Linker tools (optional)\n"
49703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
49803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Prefix to use for the output name. Defaults to empty. This\n"
49903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        prefix will be prepended to the name of the target (or the\n"
50003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        output_name if one is manually specified for it) if the prefix\n"
50103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        is not already there. The result will show up in the\n"
50203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        {{output_name}} substitution pattern.\n"
50303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
50403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        This is typically used to prepend \"lib\" to libraries on\n"
50503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Posix systems:\n"
50603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          output_prefix = \"lib\"\n"
50703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
50803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    restat  [boolean]\n"
50903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: all tools (optional, defaults to false)\n"
51003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
51103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Requests that Ninja check the file timestamp after this tool has\n"
51203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        run to determine if anything changed. Set this if your tool has\n"
51303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        the ability to skip writing output if the output file has not\n"
51403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        changed.\n"
51503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
51603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Normally, Ninja will assume that when a tool runs the output\n"
51703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        be new and downstream dependents must be rebuild. When this is\n"
51803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        set to trye, Ninja can skip rebuilding downstream dependents for\n"
51903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        input changes that don't actually affect the output.\n"
52003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
52103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example:\n"
52203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          restat = true\n"
52303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
52403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    rspfile  [string with substitutions]\n"
52503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: all tools (optional)\n"
52603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
52703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Name of the response file. If empty, no response file will be\n"
52803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        used. See \"rspfile_content\".\n"
52903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
53003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    rspfile_content  [string with substitutions]\n"
53103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Valid for: all tools (required when \"rspfile\" is specified)\n"
53203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
53303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The contents to be written to the response file. This may\n"
53403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        include all or part of the command to send to the tool which\n"
53503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        allows you to get around OS command-line length limits.\n"
53603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
53703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        This example adds the inputs and libraries to a response file,\n"
53803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        but passes the linker flags directly on the command line:\n"
53903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          tool(\"link\") {\n"
54003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "            command = \"link -o {{output}} {{ldflags}} @{{output}}.rsp\"\n"
54103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "            rspfile = \"{{output}}.rsp\"\n"
54203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "            rspfile_content = \"{{inputs}} {{solibs}} {{libs}}\"\n"
54303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "          }\n"
54403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
54503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Expansions for tool variables"
54603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
54703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  All paths are relative to the root build directory, which is the\n"
54803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  current directory for running all tools. These expansions are\n"
54903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  available to all tools:\n"
55003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
55103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{label}}\n"
55203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The label of the current target. This is typically used in the\n"
55303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"description\" field for link tools. The toolchain will be\n"
55403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        omitted from the label for targets in the default toolchain, and\n"
55503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        will be included for targets in other toolchains.\n"
55603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
55703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{output}}\n"
55803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The relative path and name of the output)((s) of the current\n"
55903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        build step. If there is more than one output, this will expand\n"
56003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        to a list of all of them.\n"
56103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"out/base/my_file.o\"\n"
56203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
56303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{target_gen_dir}}\n"
56403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{target_out_dir}}\n"
56503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The directory of the generated file and output directories,\n"
56603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        respectively, for the current target. There is no trailing\n"
56703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        slash.\n"
56803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"out/base/test\"\n"
56903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
57003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{target_output_name}}\n"
57103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The short name of the current target with no path information,\n"
57203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        or the value of the \"output_name\" variable if one is specified\n"
57303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        in the target. This will include the \"output_prefix\" if any.\n"
57403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"libfoo\" for the target named \"foo\" and an\n"
57503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        output prefix for the linker tool of \"lib\".\n"
57603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
57703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  Compiler tools have the notion of a single input and a single output,\n"
57803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  along with a set of compiler-specific flags. The following expansions\n"
57903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  are available:\n"
58003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
58103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{cflags}}\n"
58203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{cflags_c}}\n"
58303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{cflags_cc}}\n"
58403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{cflags_objc}}\n"
58503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{cflags_objcc}}\n"
58603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{defines}}\n"
58703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{include_dirs}}\n"
58803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Strings correspond that to the processed flags/defines/include\n"
58903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        directories specified for the target.\n"
59003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"--enable-foo --enable-bar\"\n"
59103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
59203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Defines will be prefixed by \"-D\" and include directories will\n"
59303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        be prefixed by \"-I\" (these work with Posix tools as well as\n"
59403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Microsoft ones).\n"
59503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
59603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{source}}\n"
59703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The relative path and name of the current input file.\n"
59803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"../../base/my_file.cc\"\n"
59903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
60003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{source_file_part}}\n"
60103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The file part of the source including the extension (with no\n"
60203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        directory information).\n"
60303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"foo.cc\"\n"
60403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
60503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{source_name_part}}\n"
60603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The filename part of the source file with no directory or\n"
60703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        extension.\n"
60803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"foo\"\n"
60903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
61003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{source_gen_dir}}\n"
61103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{source_out_dir}}\n"
61203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The directory in the generated file and output directories,\n"
61303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        respectively, for the current input file. If the source file\n"
61403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        is in the same directory as the target is declared in, they will\n"
61503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        will be the same as the \"target\" versions above.\n"
61603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"gen/base/test\"\n"
61703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
61803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  Linker tools have multiple inputs and (potentially) multiple outputs\n"
61903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  The following expansions are available:\n"
62003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
62103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{inputs}}\n"
62203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{inputs_newline}}\n"
62303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Expands to the inputs to the link step. This will be a list of\n"
62403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        object files and static libraries.\n"
62503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"obj/foo.o obj/bar.o obj/somelibrary.a\"\n"
62603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
62703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The \"_newline\" version will separate the input files with\n"
62803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        newlines instead of spaces. This is useful in response files:\n"
62903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        some linkers can take a \"-filelist\" flag which expects newline\n"
63003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        separated files, and some Microsoft tools have a fixed-sized\n"
63103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        buffer for parsing each line of a response file.\n"
63203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
63303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{ldflags}}\n"
63403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Expands to the processed set of ldflags and library search paths\n"
63503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        specified for the target.\n"
63603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"-m64, -fPIC -pthread -L/usr/local/mylib\"\n"
63703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
63803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{libs}}\n"
63903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Expands to the list of system libraries to link to. Each will\n"
64003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        be prefixed by the \"lib_prefix\".\n"
64103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
64203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        As a special case to support Mac, libraries with names ending in\n"
64303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \".framework\" will be added to the {{libs}} with \"-framework\"\n"
64403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        preceeding it, and the lib prefix will be ignored.\n"
64503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
64603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"-lfoo -lbar\"\n"
64703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
64803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{output_extension}}\n"
64903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        The value of the \"output_extension\" variable in the target,\n"
65003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        or the value of the \"default_output_extension\" value in the\n"
65103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        tool if the target does not specify an output extension.\n"
65203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \".so\"\n"
65303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
65403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    {{solibs}}\n"
65503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Extra libraries from shared library dependencide not specified\n"
65603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        in the {{inputs}}. This is the list of link_output files from\n"
65703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        shared libraries (if the solink tool specifies a \"link_output\"\n"
65803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        variable separate from the \"depend_output\").\n"
65903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
66003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        These should generally be treated the same as libs by your tool.\n"
66103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        Example: \"libfoo.so libbar.so\"\n"
66203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
66303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  The copy tool allows the common compiler/linker substitutions, plus\n"
66403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  {{source}} which is the source of the copy. The stamp tool allows\n"
66503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  only the common tool substitutions.\n"
66603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
66703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "Separate linking and dependencies for shared libraries\n"
66803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
66903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  Shared libraries are special in that not all changes to them require\n"
67003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  that dependent targets be re-linked. If the shared library is changed\n"
67103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  but no imports or exports are different, dependent code needn't be\n"
67203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  relinked, which can speed up the build.\n"
67303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
67403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  If your link step can output a list of exports from a shared library\n"
67503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  and writes the file only if the new one is different, the timestamp of\n"
67603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  this file can be used for triggering re-links, while the actual shared\n"
67703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  library would be used for linking.\n"
67803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
67903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  You will need to specify\n"
68003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    restat = true\n"
68103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  in the linker tool to make this work, so Ninja will detect if the\n"
68203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  timestamp of the dependency file has changed after linking (otherwise\n"
68303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "  it will always assume that running a command updates the output):\n"
68403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "\n"
68503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    tool(\"solink\") {\n"
68603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      command = \"...\"\n"
68703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      outputs = [\n"
68803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n"
68903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"{{root_out_dir}}/{{target_output_name}}"
69003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 "{{output_extension}}.TOC\",\n"
69103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      ]\n"
69203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      link_output =\n"
69303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n"
69403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      depend_output =\n"
69503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "        \"{{root_out_dir}}/{{target_output_name}}"
69603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 "{{output_extension}}.TOC\",\n"
69703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      restat = true\n"
69803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "    }\n"
6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "Example\n"
7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    "\n"
702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  toolchain(\"my_toolchain\") {\n"
7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "    # Put these at the top to apply to all tools below.\n"
7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "    lib_prefix = \"-l\"\n"
7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "    lib_dir_prefix = \"-L\"\n"
7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    "\n"
707d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    tool(\"cc\") {\n"
708d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      command = \"gcc \\$in -o \\$out\"\n"
70903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      outputs = [ \"{{source_out_dir}}/{{source_name_part}}.o\"\n"
710d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      description = \"GCC \\$in\"\n"
711d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    }\n"
712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    tool(\"cxx\") {\n"
713d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      command = \"g++ \\$in -o \\$out\"\n"
71403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    "      outputs = [ \"{{source_out_dir}}/{{source_name_part}}.o\"\n"
715d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "      description = \"G++ \\$in\"\n"
716d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "    }\n"
717d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  }\n";
718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunTool(Scope* scope,
720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              const FunctionCallNode* function,
721a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              const std::vector<Value>& args,
722a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              BlockNode* block,
723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)              Err* err) {
724d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Find the toolchain definition we're executing inside of. The toolchain
725d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // function will set a property pointing to it that we'll pick up.
726d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Toolchain* toolchain = reinterpret_cast<Toolchain*>(
727d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      scope->GetProperty(&kToolchainPropertyKey, NULL));
728d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!toolchain) {
729d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    *err = Err(function->function(), "tool() called outside of toolchain().",
730d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "The tool() function can only be used inside a toolchain() "
731d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        "definition.");
732d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
733d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
734d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
735d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!EnsureSingleStringArg(function, args, err))
736d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
737d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const std::string& tool_name = args[0].string_value();
738d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Toolchain::ToolType tool_type = Toolchain::ToolNameToType(tool_name);
739d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (tool_type == Toolchain::TYPE_NONE) {
740d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    *err = Err(args[0], "Unknown tool type");
741d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
742d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
743d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
744d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Run the tool block.
745d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Scope block_scope(scope);
746d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  block->ExecuteBlockInScope(&block_scope, err);
747d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (err->has_error())
748d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
749d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
75003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Figure out which validator to use for the substitution pattern for this
75103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // tool type. There are different validators for the "outputs" than for the
75203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // rest of the strings.
75303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool (*subst_validator)(SubstitutionType) = NULL;
75403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool (*subst_output_validator)(SubstitutionType) = NULL;
75503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (IsCompilerTool(tool_type)) {
75603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_validator = &IsValidCompilerSubstitution;
75703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_output_validator = &IsValidCompilerOutputsSubstitution;
75803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else if (IsLinkerTool(tool_type)) {
75903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_validator = &IsValidLinkerSubstitution;
76003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_output_validator = &IsValidLinkerOutputsSubstitution;
76103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else if (tool_type == Toolchain::TYPE_COPY) {
76203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_validator = &IsValidCopySubstitution;
76303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_output_validator = &IsValidCopySubstitution;
76403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else {
76503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_validator = &IsValidToolSubstutition;
76603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    subst_output_validator = &IsValidToolSubstutition;
76703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
76803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
76903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<Tool> tool(new Tool);
77003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
77103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!ReadPattern(&block_scope, "command", subst_validator, tool.get(),
77203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_command, err) ||
77303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadOutputExtension(&block_scope, tool.get(), err) ||
77403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadPattern(&block_scope, "depfile", subst_validator, tool.get(),
77503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_depfile, err) ||
77603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadDepsFormat(&block_scope, tool.get(), err) ||
77703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadPattern(&block_scope, "description", subst_validator, tool.get(),
77803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_description, err) ||
77903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadString(&block_scope, "lib_switch", tool.get(),
78003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                  &Tool::set_lib_switch, err) ||
78103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadString(&block_scope, "lib_dir_switch", tool.get(),
78203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                  &Tool::set_lib_dir_switch, err) ||
78303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(),
78403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_link_output, err) ||
78503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(),
78603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_depend_output, err) ||
78703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadString(&block_scope, "output_prefix", tool.get(),
78803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                  &Tool::set_output_prefix, err) ||
78903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) ||
79003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(),
79103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_rspfile, err) ||
79203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(),
79303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                   &Tool::set_rspfile_content, err)) {
79403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return Value();
79503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
79603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
79703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) {
79803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // All tools except the copy and stamp tools should have outputs. The copy
79903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // and stamp tool's outputs are generated internally.
80003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!ReadOutputs(&block_scope, function, subst_output_validator,
80103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                     tool.get(), err))
80203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return Value();
80303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
80403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
80503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Validate that the link_output and depend_output refer to items in the
80603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // outputs and aren't defined for irrelevant tool types.
80703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!tool->link_output().empty()) {
80803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (tool_type != Toolchain::TYPE_SOLINK) {
80903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *err = Err(function, "This tool specifies a link_output.",
81003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          "This is only valid for solink tools.");
81103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return Value();
81203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
81303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!IsPatternInOutputList(tool->outputs(), tool->link_output())) {
81403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *err = Err(function, "This tool's link_output is bad.",
81503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 "It must match one of the outputs.");
81603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return Value();
81703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
81803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
81903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!tool->depend_output().empty()) {
82003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (tool_type != Toolchain::TYPE_SOLINK) {
82103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *err = Err(function, "This tool specifies a depend_output.",
82203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          "This is only valid for solink tools.");
82303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return Value();
82403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
82503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (!IsPatternInOutputList(tool->outputs(), tool->depend_output())) {
82603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      *err = Err(function, "This tool's depend_output is bad.",
82703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 "It must match one of the outputs.");
82803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return Value();
82903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
83003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
83103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if ((!tool->link_output().empty() && tool->depend_output().empty()) ||
83203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      (tool->link_output().empty() && !tool->depend_output().empty())) {
83303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    *err = Err(function, "Both link_output and depend_output should either "
83403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        "be specified or they should both be empty.");
835d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
83603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
837d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
838d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  // Make sure there weren't any vars set in this tool that were unused.
839d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (!block_scope.CheckForUnusedVars(err))
840d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return Value();
841d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
84203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  toolchain->SetTool(tool_type, tool.Pass());
843d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return Value();
844d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
845a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
8463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// toolchain_args --------------------------------------------------------------
8473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)extern const char kToolchainArgs[] = "toolchain_args";
849e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochextern const char kToolchainArgs_HelpShort[] =
850e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    "toolchain_args: Set build arguments for toolchain build setup.";
8513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)extern const char kToolchainArgs_Help[] =
8523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "toolchain_args: Set build arguments for toolchain build setup.\n"
8533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\n"
854d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  Used inside a toolchain definition to pass arguments to an alternate\n"
855d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  toolchain's invocation of the build.\n"
856d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "\n"
8573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  When you specify a target using an alternate toolchain, the master\n"
8583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  build configuration file is re-interpreted in the context of that\n"
859d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  toolchain (see \"gn help toolchain\"). The toolchain_args function\n"
860d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  allows you to control the arguments passed into this alternate\n"
861d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  invocation of the build.\n"
8623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\n"
8633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  Any default system arguments or arguments passed in on the command-\n"
8643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  line will also be passed to the alternate invocation unless explicitly\n"
865d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    "  overridden by toolchain_args.\n"
8663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\n"
8673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  The toolchain_args will be ignored when the toolchain being defined\n"
8683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  is the default. In this case, it's expected you want the default\n"
8693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  argument values.\n"
8703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\n"
8713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  See also \"gn help buildargs\" for an overview of these arguments.\n"
8723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\n"
8733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "Example:\n"
8743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  toolchain(\"my_weird_toolchain\") {\n"
8753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "    ...\n"
8763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "    toolchain_args() {\n"
8773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "      # Override the system values for a generic Posix system.\n"
8783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "      is_win = false\n"
8793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "      is_posix = true\n"
8803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "\n"
8813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "      # Pass this new value for specific setup for my toolchain.\n"
8823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "      is_my_weird_system = true\n"
8833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "    }\n"
8843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    "  }\n";
8853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Value RunToolchainArgs(Scope* scope,
8873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       const FunctionCallNode* function,
8883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       const std::vector<Value>& args,
8893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       BlockNode* block,
8903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                       Err* err) {
8913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Find the toolchain definition we're executing inside of. The toolchain
8923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // function will set a property pointing to it that we'll pick up.
8933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Toolchain* toolchain = reinterpret_cast<Toolchain*>(
8943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      scope->GetProperty(&kToolchainPropertyKey, NULL));
8953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!toolchain) {
8963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err = Err(function->function(),
8973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               "toolchain_args() called outside of toolchain().",
8983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               "The toolchain_args() function can only be used inside a "
8993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               "toolchain() definition.");
9003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return Value();
9013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
9023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!args.empty()) {
9043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err = Err(function->function(), "This function takes no arguments.");
9053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return Value();
9063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
9073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // This function makes a new scope with various variable sets on it, which
9093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // we then save on the toolchain to use when re-invoking the build.
9103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Scope block_scope(scope);
9113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block->ExecuteBlockInScope(&block_scope, err);
9123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (err->has_error())
9133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return Value();
9143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Scope::KeyValueMap values;
9163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block_scope.GetCurrentScopeValues(&values);
9173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  toolchain->args() = values;
9183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
9193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return Value();
9203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
9213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
922a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace functions
923