Home | History | Annotate | Download | only in gn
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <algorithm>
      6 #include <limits>
      7 
      8 #include "tools/gn/err.h"
      9 #include "tools/gn/functions.h"
     10 #include "tools/gn/parse_tree.h"
     11 #include "tools/gn/scheduler.h"
     12 #include "tools/gn/scope.h"
     13 #include "tools/gn/settings.h"
     14 #include "tools/gn/tool.h"
     15 #include "tools/gn/toolchain.h"
     16 #include "tools/gn/value_extractors.h"
     17 #include "tools/gn/variables.h"
     18 
     19 namespace functions {
     20 
     21 namespace {
     22 
     23 // This is jsut a unique value to take the address of to use as the key for
     24 // the toolchain property on a scope.
     25 const int kToolchainPropertyKey = 0;
     26 
     27 bool ReadBool(Scope* scope,
     28               const char* var,
     29               Tool* tool,
     30               void (Tool::*set)(bool),
     31               Err* err) {
     32   const Value* v = scope->GetValue(var, true);
     33   if (!v)
     34     return true;  // Not present is fine.
     35   if (!v->VerifyTypeIs(Value::BOOLEAN, err))
     36     return false;
     37 
     38   (tool->*set)(v->boolean_value());
     39   return true;
     40 }
     41 
     42 // Reads the given string from the scope (if present) and puts the result into
     43 // dest. If the value is not a string, sets the error and returns false.
     44 bool ReadString(Scope* scope,
     45                 const char* var,
     46                 Tool* tool,
     47                 void (Tool::*set)(const std::string&),
     48                 Err* err) {
     49   const Value* v = scope->GetValue(var, true);
     50   if (!v)
     51     return true;  // Not present is fine.
     52   if (!v->VerifyTypeIs(Value::STRING, err))
     53     return false;
     54 
     55   (tool->*set)(v->string_value());
     56   return true;
     57 }
     58 
     59 // Calls the given validate function on each type in the list. On failure,
     60 // sets the error, blame the value, and return false.
     61 bool ValidateSubstitutionList(const std::vector<SubstitutionType>& list,
     62                               bool (*validate)(SubstitutionType),
     63                               const Value* origin,
     64                               Err* err) {
     65   for (size_t i = 0; i < list.size(); i++) {
     66     SubstitutionType cur_type = list[i];
     67     if (!validate(cur_type)) {
     68       *err = Err(*origin, "Pattern not valid here.",
     69           "You used the pattern " + std::string(kSubstitutionNames[cur_type]) +
     70           " which is not valid\nfor this variable.");
     71       return false;
     72     }
     73   }
     74   return true;
     75 }
     76 
     77 bool ReadPattern(Scope* scope,
     78                  const char* name,
     79                  bool (*validate)(SubstitutionType),
     80                  Tool* tool,
     81                  void (Tool::*set)(const SubstitutionPattern&),
     82                  Err* err) {
     83   const Value* value = scope->GetValue(name, true);
     84   if (!value)
     85     return true;  // Not present is fine.
     86   if (!value->VerifyTypeIs(Value::STRING, err))
     87     return false;
     88 
     89   SubstitutionPattern pattern;
     90   if (!pattern.Parse(*value, err))
     91     return false;
     92   if (!ValidateSubstitutionList(pattern.required_types(), validate, value, err))
     93     return false;
     94 
     95   (tool->*set)(pattern);
     96   return true;
     97 }
     98 
     99 bool ReadOutputExtension(Scope* scope, Tool* tool, Err* err) {
    100   const Value* value = scope->GetValue("default_output_extension", true);
    101   if (!value)
    102     return true;  // Not present is fine.
    103   if (!value->VerifyTypeIs(Value::STRING, err))
    104     return false;
    105 
    106   if (value->string_value().empty())
    107     return true;  // Accept empty string.
    108 
    109   if (value->string_value()[0] != '.') {
    110     *err = Err(*value, "default_output_extension must begin with a '.'");
    111     return false;
    112   }
    113 
    114   tool->set_default_output_extension(value->string_value());
    115   return true;
    116 }
    117 
    118 bool ReadDepsFormat(Scope* scope, Tool* tool, Err* err) {
    119   const Value* value = scope->GetValue("depsformat", true);
    120   if (!value)
    121     return true;  // Not present is fine.
    122   if (!value->VerifyTypeIs(Value::STRING, err))
    123     return false;
    124 
    125   if (value->string_value() == "gcc") {
    126     tool->set_depsformat(Tool::DEPS_GCC);
    127   } else if (value->string_value() == "msvc") {
    128     tool->set_depsformat(Tool::DEPS_MSVC);
    129   } else {
    130     *err = Err(*value, "Deps format must be \"gcc\" or \"msvc\".");
    131     return false;
    132   }
    133   return true;
    134 }
    135 
    136 bool ReadOutputs(Scope* scope,
    137                  const FunctionCallNode* tool_function,
    138                  bool (*validate)(SubstitutionType),
    139                  Tool* tool,
    140                  Err* err) {
    141   const Value* value = scope->GetValue("outputs", true);
    142   if (!value) {
    143     *err = Err(tool_function, "\"outputs\" must be specified for this tool.");
    144     return false;
    145   }
    146 
    147   SubstitutionList list;
    148   if (!list.Parse(*value, err))
    149     return false;
    150 
    151   // Validate the right kinds of patterns are used.
    152   if (!ValidateSubstitutionList(list.required_types(), validate, value, err))
    153     return false;
    154 
    155   // There should always be at least one output.
    156   if (list.list().empty()) {
    157     *err = Err(*value, "Outputs list is empty.", "I need some outputs.");
    158     return false;
    159   }
    160 
    161   tool->set_outputs(list);
    162   return true;
    163 }
    164 
    165 bool IsCompilerTool(Toolchain::ToolType type) {
    166   return type == Toolchain::TYPE_CC ||
    167          type == Toolchain::TYPE_CXX ||
    168          type == Toolchain::TYPE_OBJC ||
    169          type == Toolchain::TYPE_OBJCXX ||
    170          type == Toolchain::TYPE_RC ||
    171          type == Toolchain::TYPE_ASM;
    172 }
    173 
    174 bool IsLinkerTool(Toolchain::ToolType type) {
    175   return type == Toolchain::TYPE_ALINK ||
    176          type == Toolchain::TYPE_SOLINK ||
    177          type == Toolchain::TYPE_LINK;
    178 }
    179 
    180 bool IsPatternInOutputList(const SubstitutionList& output_list,
    181                            const SubstitutionPattern& pattern) {
    182   for (size_t output_i = 0; output_i < output_list.list().size(); output_i++) {
    183     const SubstitutionPattern& cur = output_list.list()[output_i];
    184     if (pattern.ranges().size() == cur.ranges().size() &&
    185         std::equal(pattern.ranges().begin(), pattern.ranges().end(),
    186                    cur.ranges().begin()))
    187       return true;
    188   }
    189   return false;
    190 }
    191 
    192 }  // namespace
    193 
    194 // toolchain -------------------------------------------------------------------
    195 
    196 const char kToolchain[] = "toolchain";
    197 const char kToolchain_HelpShort[] =
    198     "toolchain: Defines a toolchain.";
    199 const char kToolchain_Help[] =
    200     "toolchain: Defines a toolchain.\n"
    201     "\n"
    202     "  A toolchain is a set of commands and build flags used to compile the\n"
    203     "  source code. You can have more than one toolchain in use at once in\n"
    204     "  a build.\n"
    205     "\n"
    206     "Functions and variables\n"
    207     "\n"
    208     "  tool()\n"
    209     "    The tool() function call specifies the commands commands to run for\n"
    210     "    a given step. See \"gn help tool\".\n"
    211     "\n"
    212     "  toolchain_args()\n"
    213     "    List of arguments to pass to the toolchain when invoking this\n"
    214     "    toolchain. This applies only to non-default toolchains. See\n"
    215     "    \"gn help toolchain_args\" for more.\n"
    216     "\n"
    217     "  deps\n"
    218     "    Dependencies of this toolchain. These dependencies will be resolved\n"
    219     "    before any target in the toolchain is compiled. To avoid circular\n"
    220     "    dependencies these must be targets defined in another toolchain.\n"
    221     "\n"
    222     "    This is expressed as a list of targets, and generally these targets\n"
    223     "    will always specify a toolchain:\n"
    224     "      deps = [ \"//foo/bar:baz(//build/toolchain:bootstrap)\" ]\n"
    225     "\n"
    226     "    This concept is somewhat inefficient to express in Ninja (it\n"
    227     "    requires a lot of duplicate of rules) so should only be used when\n"
    228     "    absolutely necessary.\n"
    229     "\n"
    230     "  concurrent_links\n"
    231     "    In integer expressing the number of links that Ninja will perform in\n"
    232     "    parallel. GN will create a pool for shared library and executable\n"
    233     "    link steps with this many processes. Since linking is memory- and\n"
    234     "    I/O-intensive, projects with many large targets may want to limit\n"
    235     "    the number of parallel steps to avoid overloading the computer.\n"
    236     "    Since creating static libraries is generally not as intensive\n"
    237     "    there is no limit to \"alink\" steps.\n"
    238     "\n"
    239     "    Defaults to 0 which Ninja interprets as \"no limit\".\n"
    240     "\n"
    241     "    The value used will be the one from the default toolchain of the\n"
    242     "    current build.\n"
    243     "\n"
    244     "Invoking targets in toolchains:\n"
    245     "\n"
    246     "  By default, when a target depends on another, there is an implicit\n"
    247     "  toolchain label that is inherited, so the dependee has the same one\n"
    248     "  as the dependent.\n"
    249     "\n"
    250     "  You can override this and refer to any other toolchain by explicitly\n"
    251     "  labeling the toolchain to use. For example:\n"
    252     "    data_deps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n"
    253     "  The string \"//build/toolchains:plugin_toolchain\" is a label that\n"
    254     "  identifies the toolchain declaration for compiling the sources.\n"
    255     "\n"
    256     "  To load a file in an alternate toolchain, GN does the following:\n"
    257     "\n"
    258     "   1. Loads the file with the toolchain definition in it (as determined\n"
    259     "      by the toolchain label).\n"
    260     "   2. Re-runs the master build configuration file, applying the\n"
    261     "      arguments specified by the toolchain_args section of the toolchain\n"
    262     "      definition (see \"gn help toolchain_args\").\n"
    263     "   3. Loads the destination build file in the context of the\n"
    264     "      configuration file in the previous step.\n"
    265     "\n"
    266     "Example:\n"
    267     "  toolchain(\"plugin_toolchain\") {\n"
    268     "    concurrent_links = 8\n"
    269     "\n"
    270     "    tool(\"cc\") {\n"
    271     "      command = \"gcc $in\"\n"
    272     "      ...\n"
    273     "    }\n"
    274     "\n"
    275     "    toolchain_args() {\n"
    276     "      is_plugin = true\n"
    277     "      is_32bit = true\n"
    278     "      is_64bit = false\n"
    279     "    }\n"
    280     "  }\n";
    281 
    282 Value RunToolchain(Scope* scope,
    283                    const FunctionCallNode* function,
    284                    const std::vector<Value>& args,
    285                    BlockNode* block,
    286                    Err* err) {
    287   if (!EnsureNotProcessingImport(function, scope, err) ||
    288       !EnsureNotProcessingBuildConfig(function, scope, err))
    289     return Value();
    290 
    291   // Note that we don't want to use MakeLabelForScope since that will include
    292   // the toolchain name in the label, and toolchain labels don't themselves
    293   // have toolchain names.
    294   const SourceDir& input_dir = scope->GetSourceDir();
    295   Label label(input_dir, args[0].string_value());
    296   if (g_scheduler->verbose_logging())
    297     g_scheduler->Log("Definining toolchain", label.GetUserVisibleName(false));
    298 
    299   // This object will actually be copied into the one owned by the toolchain
    300   // manager, but that has to be done in the lock.
    301   scoped_ptr<Toolchain> toolchain(new Toolchain(scope->settings(), label));
    302   toolchain->set_defined_from(function);
    303   toolchain->visibility().SetPublic();
    304 
    305   Scope block_scope(scope);
    306   block_scope.SetProperty(&kToolchainPropertyKey, toolchain.get());
    307   block->ExecuteBlockInScope(&block_scope, err);
    308   block_scope.SetProperty(&kToolchainPropertyKey, NULL);
    309   if (err->has_error())
    310     return Value();
    311 
    312   // Read deps (if any).
    313   const Value* deps_value = block_scope.GetValue(variables::kDeps, true);
    314   if (deps_value) {
    315     ExtractListOfLabels(
    316         *deps_value, block_scope.GetSourceDir(),
    317         ToolchainLabelForScope(&block_scope), &toolchain->deps(), err);
    318     if (err->has_error())
    319       return Value();
    320   }
    321 
    322   // Read concurrent_links (if any).
    323   const Value* concurrent_links_value =
    324       block_scope.GetValue("concurrent_links", true);
    325   if (concurrent_links_value) {
    326     if (!concurrent_links_value->VerifyTypeIs(Value::INTEGER, err))
    327       return Value();
    328     if (concurrent_links_value->int_value() < 0 ||
    329         concurrent_links_value->int_value() > std::numeric_limits<int>::max()) {
    330       *err = Err(*concurrent_links_value, "Value out of range.");
    331       return Value();
    332     }
    333     toolchain->set_concurrent_links(
    334         static_cast<int>(concurrent_links_value->int_value()));
    335   }
    336 
    337   if (!block_scope.CheckForUnusedVars(err))
    338     return Value();
    339 
    340   // Save this toolchain.
    341   toolchain->ToolchainSetupComplete();
    342   Scope::ItemVector* collector = scope->GetItemCollector();
    343   if (!collector) {
    344     *err = Err(function, "Can't define a toolchain in this context.");
    345     return Value();
    346   }
    347   collector->push_back(new scoped_ptr<Item>(toolchain.PassAs<Item>()));
    348   return Value();
    349 }
    350 
    351 // tool ------------------------------------------------------------------------
    352 
    353 const char kTool[] = "tool";
    354 const char kTool_HelpShort[] =
    355     "tool: Specify arguments to a toolchain tool.";
    356 const char kTool_Help[] =
    357     "tool: Specify arguments to a toolchain tool.\n"
    358     "\n"
    359     "Usage:\n"
    360     "\n"
    361     "  tool(<tool type>) {\n"
    362     "    <tool variables...>\n"
    363     "  }\n"
    364     "\n"
    365     "Tool types\n"
    366     "\n"
    367     "    Compiler tools:\n"
    368     "      \"cc\": C compiler\n"
    369     "      \"cxx\": C++ compiler\n"
    370     "      \"objc\": Objective C compiler\n"
    371     "      \"objcxx\": Objective C++ compiler\n"
    372     "      \"rc\": Resource compiler (Windows .rc files)\n"
    373     "      \"asm\": Assembler\n"
    374     "\n"
    375     "    Linker tools:\n"
    376     "      \"alink\": Linker for static libraries (archives)\n"
    377     "      \"solink\": Linker for shared libraries\n"
    378     "      \"link\": Linker for executables\n"
    379     "\n"
    380     "    Other tools:\n"
    381     "      \"stamp\": Tool for creating stamp files\n"
    382     "      \"copy\": Tool to copy files.\n"
    383     "\n"
    384     "Tool variables\n"
    385     "\n"
    386     "    command  [string with substitutions]\n"
    387     "        Valid for: all tools (required)\n"
    388     "\n"
    389     "        The command to run.\n"
    390     "\n"
    391     "    default_output_extension  [string]\n"
    392     "        Valid for: linker tools\n"
    393     "\n"
    394     "        Extension for the main output of a linkable tool. It includes\n"
    395     "        the leading dot. This will be the default value for the\n"
    396     "        {{output_extension}} expansion (discussed below) but will be\n"
    397     "        overridden by by the \"output extension\" variable in a target,\n"
    398     "        if one is specified. Empty string means no extension.\n"
    399     "\n"
    400     "        GN doesn't actually do anything with this extension other than\n"
    401     "        pass it along, potentially with target-specific overrides. One\n"
    402     "        would typically use the {{output_extension}} value in the\n"
    403     "        \"outputs\" to read this value.\n"
    404     "\n"
    405     "        Example: default_output_extension = \".exe\"\n"
    406     "\n"
    407     "    depfile  [string]\n"
    408     "        Valid for: compiler tools (optional)\n"
    409     "\n"
    410     "        If the tool can write \".d\" files, this specifies the name of\n"
    411     "        the resulting file. These files are used to list header file\n"
    412     "        dependencies (or other implicit input dependencies) that are\n"
    413     "        discovered at build time. See also \"depsformat\".\n"
    414     "\n"
    415     "        Example: depfile = \"{{output}}.d\"\n"
    416     "\n"
    417     "    depsformat  [string]\n"
    418     "        Valid for: compiler tools (when depfile is specified)\n"
    419     "\n"
    420     "        Format for the deps outputs. This is either \"gcc\" or \"msvc\".\n"
    421     "        See the ninja documentation for \"deps\" for more information.\n"
    422     "\n"
    423     "        Example: depsformat = \"gcc\"\n"
    424     "\n"
    425     "    description  [string with substitutions, optional]\n"
    426     "        Valid for: all tools\n"
    427     "\n"
    428     "        What to print when the command is run.\n"
    429     "\n"
    430     "        Example: description = \"Compiling {{source}}\"\n"
    431     "\n"
    432     "    lib_switch  [string, optional, link tools only]\n"
    433     "    lib_dir_switch  [string, optional, link tools only]\n"
    434     "        Valid for: Linker tools except \"alink\"\n"
    435     "\n"
    436     "        These strings will be prepended to the libraries and library\n"
    437     "        search directories, respectively, because linkers differ on how\n"
    438     "        specify them. If you specified:\n"
    439     "          lib_switch = \"-l\"\n"
    440     "          lib_dir_switch = \"-L\"\n"
    441     "        then the \"{{libs}}\" expansion for [ \"freetype\", \"expat\"]\n"
    442     "        would be \"-lfreetype -lexpat\".\n"
    443     "\n"
    444     "    outputs  [list of strings with substitutions]\n"
    445     "        Valid for: Linker and compiler tools (required)\n"
    446     "\n"
    447     "        An array of names for the output files the tool produces. These\n"
    448     "        are relative to the build output directory. There must always be\n"
    449     "        at least one output file. There can be more than one output (a\n"
    450     "        linker might produce a library and an import library, for\n"
    451     "        example).\n"
    452     "\n"
    453     "        This array just declares to GN what files the tool will\n"
    454     "        produce. It is your responsibility to specify the tool command\n"
    455     "        that actually produces these files.\n"
    456     "\n"
    457     "        If you specify more than one output for shared library links,\n"
    458     "        you should consider setting link_output and depend_output.\n"
    459     "        Otherwise, the first entry in the outputs list should always be\n"
    460     "        the main output which will be linked to.\n"
    461     "\n"
    462     "        Example for a compiler tool that produces .obj files:\n"
    463     "          outputs = [\n"
    464     "            \"{{source_out_dir}}/{{source_name_part}}.obj\"\n"
    465     "          ]\n"
    466     "\n"
    467     "        Example for a linker tool that produces a .dll and a .lib. The\n"
    468     "        use of {{output_extension}} rather than hardcoding \".dll\"\n"
    469     "        allows the extension of the library to be overridden on a\n"
    470     "        target-by-target basis, but in this example, it always\n"
    471     "        produces a \".lib\" import library:\n"
    472     "          outputs = [\n"
    473     "            \"{{root_out_dir}}/{{target_output_name}}"
    474                      "{{output_extension}}\",\n"
    475     "            \"{{root_out_dir}}/{{target_output_name}}.lib\",\n"
    476     "          ]\n"
    477     "\n"
    478     "    link_output  [string with substitutions]\n"
    479     "    depend_output  [string with substitutions]\n"
    480     "        Valid for: \"solink\" only (optional)\n"
    481     "\n"
    482     "        These two files specify whch of the outputs from the solink\n"
    483     "        tool should be used for linking and dependency tracking. These\n"
    484     "        should match entries in the \"outputs\". If unspecified, the\n"
    485     "        first item in the \"outputs\" array will be used for both. See\n"
    486     "        \"Separate linking and dependencies for shared libraries\"\n"
    487     "        below for more.\n"
    488     "\n"
    489     "        On Windows, where the tools produce a .dll shared library and\n"
    490     "        a .lib import library, you will want both of these to be the\n"
    491     "        import library. On Linux, if you're not doing the separate\n"
    492     "        linking/dependency optimization, both of these should be the\n"
    493     "        .so output.\n"
    494     "\n"
    495     "    output_prefix  [string]\n"
    496     "        Valid for: Linker tools (optional)\n"
    497     "\n"
    498     "        Prefix to use for the output name. Defaults to empty. This\n"
    499     "        prefix will be prepended to the name of the target (or the\n"
    500     "        output_name if one is manually specified for it) if the prefix\n"
    501     "        is not already there. The result will show up in the\n"
    502     "        {{output_name}} substitution pattern.\n"
    503     "\n"
    504     "        This is typically used to prepend \"lib\" to libraries on\n"
    505     "        Posix systems:\n"
    506     "          output_prefix = \"lib\"\n"
    507     "\n"
    508     "    restat  [boolean]\n"
    509     "        Valid for: all tools (optional, defaults to false)\n"
    510     "\n"
    511     "        Requests that Ninja check the file timestamp after this tool has\n"
    512     "        run to determine if anything changed. Set this if your tool has\n"
    513     "        the ability to skip writing output if the output file has not\n"
    514     "        changed.\n"
    515     "\n"
    516     "        Normally, Ninja will assume that when a tool runs the output\n"
    517     "        be new and downstream dependents must be rebuild. When this is\n"
    518     "        set to trye, Ninja can skip rebuilding downstream dependents for\n"
    519     "        input changes that don't actually affect the output.\n"
    520     "\n"
    521     "        Example:\n"
    522     "          restat = true\n"
    523     "\n"
    524     "    rspfile  [string with substitutions]\n"
    525     "        Valid for: all tools (optional)\n"
    526     "\n"
    527     "        Name of the response file. If empty, no response file will be\n"
    528     "        used. See \"rspfile_content\".\n"
    529     "\n"
    530     "    rspfile_content  [string with substitutions]\n"
    531     "        Valid for: all tools (required when \"rspfile\" is specified)\n"
    532     "\n"
    533     "        The contents to be written to the response file. This may\n"
    534     "        include all or part of the command to send to the tool which\n"
    535     "        allows you to get around OS command-line length limits.\n"
    536     "\n"
    537     "        This example adds the inputs and libraries to a response file,\n"
    538     "        but passes the linker flags directly on the command line:\n"
    539     "          tool(\"link\") {\n"
    540     "            command = \"link -o {{output}} {{ldflags}} @{{output}}.rsp\"\n"
    541     "            rspfile = \"{{output}}.rsp\"\n"
    542     "            rspfile_content = \"{{inputs}} {{solibs}} {{libs}}\"\n"
    543     "          }\n"
    544     "\n"
    545     "Expansions for tool variables"
    546     "\n"
    547     "  All paths are relative to the root build directory, which is the\n"
    548     "  current directory for running all tools. These expansions are\n"
    549     "  available to all tools:\n"
    550     "\n"
    551     "    {{label}}\n"
    552     "        The label of the current target. This is typically used in the\n"
    553     "        \"description\" field for link tools. The toolchain will be\n"
    554     "        omitted from the label for targets in the default toolchain, and\n"
    555     "        will be included for targets in other toolchains.\n"
    556     "\n"
    557     "    {{output}}\n"
    558     "        The relative path and name of the output)((s) of the current\n"
    559     "        build step. If there is more than one output, this will expand\n"
    560     "        to a list of all of them.\n"
    561     "        Example: \"out/base/my_file.o\"\n"
    562     "\n"
    563     "    {{target_gen_dir}}\n"
    564     "    {{target_out_dir}}\n"
    565     "        The directory of the generated file and output directories,\n"
    566     "        respectively, for the current target. There is no trailing\n"
    567     "        slash.\n"
    568     "        Example: \"out/base/test\"\n"
    569     "\n"
    570     "    {{target_output_name}}\n"
    571     "        The short name of the current target with no path information,\n"
    572     "        or the value of the \"output_name\" variable if one is specified\n"
    573     "        in the target. This will include the \"output_prefix\" if any.\n"
    574     "        Example: \"libfoo\" for the target named \"foo\" and an\n"
    575     "        output prefix for the linker tool of \"lib\".\n"
    576     "\n"
    577     "  Compiler tools have the notion of a single input and a single output,\n"
    578     "  along with a set of compiler-specific flags. The following expansions\n"
    579     "  are available:\n"
    580     "\n"
    581     "    {{cflags}}\n"
    582     "    {{cflags_c}}\n"
    583     "    {{cflags_cc}}\n"
    584     "    {{cflags_objc}}\n"
    585     "    {{cflags_objcc}}\n"
    586     "    {{defines}}\n"
    587     "    {{include_dirs}}\n"
    588     "        Strings correspond that to the processed flags/defines/include\n"
    589     "        directories specified for the target.\n"
    590     "        Example: \"--enable-foo --enable-bar\"\n"
    591     "\n"
    592     "        Defines will be prefixed by \"-D\" and include directories will\n"
    593     "        be prefixed by \"-I\" (these work with Posix tools as well as\n"
    594     "        Microsoft ones).\n"
    595     "\n"
    596     "    {{source}}\n"
    597     "        The relative path and name of the current input file.\n"
    598     "        Example: \"../../base/my_file.cc\"\n"
    599     "\n"
    600     "    {{source_file_part}}\n"
    601     "        The file part of the source including the extension (with no\n"
    602     "        directory information).\n"
    603     "        Example: \"foo.cc\"\n"
    604     "\n"
    605     "    {{source_name_part}}\n"
    606     "        The filename part of the source file with no directory or\n"
    607     "        extension.\n"
    608     "        Example: \"foo\"\n"
    609     "\n"
    610     "    {{source_gen_dir}}\n"
    611     "    {{source_out_dir}}\n"
    612     "        The directory in the generated file and output directories,\n"
    613     "        respectively, for the current input file. If the source file\n"
    614     "        is in the same directory as the target is declared in, they will\n"
    615     "        will be the same as the \"target\" versions above.\n"
    616     "        Example: \"gen/base/test\"\n"
    617     "\n"
    618     "  Linker tools have multiple inputs and (potentially) multiple outputs\n"
    619     "  The following expansions are available:\n"
    620     "\n"
    621     "    {{inputs}}\n"
    622     "    {{inputs_newline}}\n"
    623     "        Expands to the inputs to the link step. This will be a list of\n"
    624     "        object files and static libraries.\n"
    625     "        Example: \"obj/foo.o obj/bar.o obj/somelibrary.a\"\n"
    626     "\n"
    627     "        The \"_newline\" version will separate the input files with\n"
    628     "        newlines instead of spaces. This is useful in response files:\n"
    629     "        some linkers can take a \"-filelist\" flag which expects newline\n"
    630     "        separated files, and some Microsoft tools have a fixed-sized\n"
    631     "        buffer for parsing each line of a response file.\n"
    632     "\n"
    633     "    {{ldflags}}\n"
    634     "        Expands to the processed set of ldflags and library search paths\n"
    635     "        specified for the target.\n"
    636     "        Example: \"-m64, -fPIC -pthread -L/usr/local/mylib\"\n"
    637     "\n"
    638     "    {{libs}}\n"
    639     "        Expands to the list of system libraries to link to. Each will\n"
    640     "        be prefixed by the \"lib_prefix\".\n"
    641     "\n"
    642     "        As a special case to support Mac, libraries with names ending in\n"
    643     "        \".framework\" will be added to the {{libs}} with \"-framework\"\n"
    644     "        preceeding it, and the lib prefix will be ignored.\n"
    645     "\n"
    646     "        Example: \"-lfoo -lbar\"\n"
    647     "\n"
    648     "    {{output_extension}}\n"
    649     "        The value of the \"output_extension\" variable in the target,\n"
    650     "        or the value of the \"default_output_extension\" value in the\n"
    651     "        tool if the target does not specify an output extension.\n"
    652     "        Example: \".so\"\n"
    653     "\n"
    654     "    {{solibs}}\n"
    655     "        Extra libraries from shared library dependencide not specified\n"
    656     "        in the {{inputs}}. This is the list of link_output files from\n"
    657     "        shared libraries (if the solink tool specifies a \"link_output\"\n"
    658     "        variable separate from the \"depend_output\").\n"
    659     "\n"
    660     "        These should generally be treated the same as libs by your tool.\n"
    661     "        Example: \"libfoo.so libbar.so\"\n"
    662     "\n"
    663     "  The copy tool allows the common compiler/linker substitutions, plus\n"
    664     "  {{source}} which is the source of the copy. The stamp tool allows\n"
    665     "  only the common tool substitutions.\n"
    666     "\n"
    667     "Separate linking and dependencies for shared libraries\n"
    668     "\n"
    669     "  Shared libraries are special in that not all changes to them require\n"
    670     "  that dependent targets be re-linked. If the shared library is changed\n"
    671     "  but no imports or exports are different, dependent code needn't be\n"
    672     "  relinked, which can speed up the build.\n"
    673     "\n"
    674     "  If your link step can output a list of exports from a shared library\n"
    675     "  and writes the file only if the new one is different, the timestamp of\n"
    676     "  this file can be used for triggering re-links, while the actual shared\n"
    677     "  library would be used for linking.\n"
    678     "\n"
    679     "  You will need to specify\n"
    680     "    restat = true\n"
    681     "  in the linker tool to make this work, so Ninja will detect if the\n"
    682     "  timestamp of the dependency file has changed after linking (otherwise\n"
    683     "  it will always assume that running a command updates the output):\n"
    684     "\n"
    685     "    tool(\"solink\") {\n"
    686     "      command = \"...\"\n"
    687     "      outputs = [\n"
    688     "        \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n"
    689     "        \"{{root_out_dir}}/{{target_output_name}}"
    690                  "{{output_extension}}.TOC\",\n"
    691     "      ]\n"
    692     "      link_output =\n"
    693     "        \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n"
    694     "      depend_output =\n"
    695     "        \"{{root_out_dir}}/{{target_output_name}}"
    696                  "{{output_extension}}.TOC\",\n"
    697     "      restat = true\n"
    698     "    }\n"
    699     "\n"
    700     "Example\n"
    701     "\n"
    702     "  toolchain(\"my_toolchain\") {\n"
    703     "    # Put these at the top to apply to all tools below.\n"
    704     "    lib_prefix = \"-l\"\n"
    705     "    lib_dir_prefix = \"-L\"\n"
    706     "\n"
    707     "    tool(\"cc\") {\n"
    708     "      command = \"gcc \\$in -o \\$out\"\n"
    709     "      outputs = [ \"{{source_out_dir}}/{{source_name_part}}.o\"\n"
    710     "      description = \"GCC \\$in\"\n"
    711     "    }\n"
    712     "    tool(\"cxx\") {\n"
    713     "      command = \"g++ \\$in -o \\$out\"\n"
    714     "      outputs = [ \"{{source_out_dir}}/{{source_name_part}}.o\"\n"
    715     "      description = \"G++ \\$in\"\n"
    716     "    }\n"
    717     "  }\n";
    718 
    719 Value RunTool(Scope* scope,
    720               const FunctionCallNode* function,
    721               const std::vector<Value>& args,
    722               BlockNode* block,
    723               Err* err) {
    724   // Find the toolchain definition we're executing inside of. The toolchain
    725   // function will set a property pointing to it that we'll pick up.
    726   Toolchain* toolchain = reinterpret_cast<Toolchain*>(
    727       scope->GetProperty(&kToolchainPropertyKey, NULL));
    728   if (!toolchain) {
    729     *err = Err(function->function(), "tool() called outside of toolchain().",
    730         "The tool() function can only be used inside a toolchain() "
    731         "definition.");
    732     return Value();
    733   }
    734 
    735   if (!EnsureSingleStringArg(function, args, err))
    736     return Value();
    737   const std::string& tool_name = args[0].string_value();
    738   Toolchain::ToolType tool_type = Toolchain::ToolNameToType(tool_name);
    739   if (tool_type == Toolchain::TYPE_NONE) {
    740     *err = Err(args[0], "Unknown tool type");
    741     return Value();
    742   }
    743 
    744   // Run the tool block.
    745   Scope block_scope(scope);
    746   block->ExecuteBlockInScope(&block_scope, err);
    747   if (err->has_error())
    748     return Value();
    749 
    750   // Figure out which validator to use for the substitution pattern for this
    751   // tool type. There are different validators for the "outputs" than for the
    752   // rest of the strings.
    753   bool (*subst_validator)(SubstitutionType) = NULL;
    754   bool (*subst_output_validator)(SubstitutionType) = NULL;
    755   if (IsCompilerTool(tool_type)) {
    756     subst_validator = &IsValidCompilerSubstitution;
    757     subst_output_validator = &IsValidCompilerOutputsSubstitution;
    758   } else if (IsLinkerTool(tool_type)) {
    759     subst_validator = &IsValidLinkerSubstitution;
    760     subst_output_validator = &IsValidLinkerOutputsSubstitution;
    761   } else if (tool_type == Toolchain::TYPE_COPY) {
    762     subst_validator = &IsValidCopySubstitution;
    763     subst_output_validator = &IsValidCopySubstitution;
    764   } else {
    765     subst_validator = &IsValidToolSubstutition;
    766     subst_output_validator = &IsValidToolSubstutition;
    767   }
    768 
    769   scoped_ptr<Tool> tool(new Tool);
    770 
    771   if (!ReadPattern(&block_scope, "command", subst_validator, tool.get(),
    772                    &Tool::set_command, err) ||
    773       !ReadOutputExtension(&block_scope, tool.get(), err) ||
    774       !ReadPattern(&block_scope, "depfile", subst_validator, tool.get(),
    775                    &Tool::set_depfile, err) ||
    776       !ReadDepsFormat(&block_scope, tool.get(), err) ||
    777       !ReadPattern(&block_scope, "description", subst_validator, tool.get(),
    778                    &Tool::set_description, err) ||
    779       !ReadString(&block_scope, "lib_switch", tool.get(),
    780                   &Tool::set_lib_switch, err) ||
    781       !ReadString(&block_scope, "lib_dir_switch", tool.get(),
    782                   &Tool::set_lib_dir_switch, err) ||
    783       !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(),
    784                    &Tool::set_link_output, err) ||
    785       !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(),
    786                    &Tool::set_depend_output, err) ||
    787       !ReadString(&block_scope, "output_prefix", tool.get(),
    788                   &Tool::set_output_prefix, err) ||
    789       !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) ||
    790       !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(),
    791                    &Tool::set_rspfile, err) ||
    792       !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(),
    793                    &Tool::set_rspfile_content, err)) {
    794     return Value();
    795   }
    796 
    797   if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) {
    798     // All tools except the copy and stamp tools should have outputs. The copy
    799     // and stamp tool's outputs are generated internally.
    800     if (!ReadOutputs(&block_scope, function, subst_output_validator,
    801                      tool.get(), err))
    802       return Value();
    803   }
    804 
    805   // Validate that the link_output and depend_output refer to items in the
    806   // outputs and aren't defined for irrelevant tool types.
    807   if (!tool->link_output().empty()) {
    808     if (tool_type != Toolchain::TYPE_SOLINK) {
    809       *err = Err(function, "This tool specifies a link_output.",
    810           "This is only valid for solink tools.");
    811       return Value();
    812     }
    813     if (!IsPatternInOutputList(tool->outputs(), tool->link_output())) {
    814       *err = Err(function, "This tool's link_output is bad.",
    815                  "It must match one of the outputs.");
    816       return Value();
    817     }
    818   }
    819   if (!tool->depend_output().empty()) {
    820     if (tool_type != Toolchain::TYPE_SOLINK) {
    821       *err = Err(function, "This tool specifies a depend_output.",
    822           "This is only valid for solink tools.");
    823       return Value();
    824     }
    825     if (!IsPatternInOutputList(tool->outputs(), tool->depend_output())) {
    826       *err = Err(function, "This tool's depend_output is bad.",
    827                  "It must match one of the outputs.");
    828       return Value();
    829     }
    830   }
    831   if ((!tool->link_output().empty() && tool->depend_output().empty()) ||
    832       (tool->link_output().empty() && !tool->depend_output().empty())) {
    833     *err = Err(function, "Both link_output and depend_output should either "
    834         "be specified or they should both be empty.");
    835     return Value();
    836   }
    837 
    838   // Make sure there weren't any vars set in this tool that were unused.
    839   if (!block_scope.CheckForUnusedVars(err))
    840     return Value();
    841 
    842   toolchain->SetTool(tool_type, tool.Pass());
    843   return Value();
    844 }
    845 
    846 // toolchain_args --------------------------------------------------------------
    847 
    848 extern const char kToolchainArgs[] = "toolchain_args";
    849 extern const char kToolchainArgs_HelpShort[] =
    850     "toolchain_args: Set build arguments for toolchain build setup.";
    851 extern const char kToolchainArgs_Help[] =
    852     "toolchain_args: Set build arguments for toolchain build setup.\n"
    853     "\n"
    854     "  Used inside a toolchain definition to pass arguments to an alternate\n"
    855     "  toolchain's invocation of the build.\n"
    856     "\n"
    857     "  When you specify a target using an alternate toolchain, the master\n"
    858     "  build configuration file is re-interpreted in the context of that\n"
    859     "  toolchain (see \"gn help toolchain\"). The toolchain_args function\n"
    860     "  allows you to control the arguments passed into this alternate\n"
    861     "  invocation of the build.\n"
    862     "\n"
    863     "  Any default system arguments or arguments passed in on the command-\n"
    864     "  line will also be passed to the alternate invocation unless explicitly\n"
    865     "  overridden by toolchain_args.\n"
    866     "\n"
    867     "  The toolchain_args will be ignored when the toolchain being defined\n"
    868     "  is the default. In this case, it's expected you want the default\n"
    869     "  argument values.\n"
    870     "\n"
    871     "  See also \"gn help buildargs\" for an overview of these arguments.\n"
    872     "\n"
    873     "Example:\n"
    874     "  toolchain(\"my_weird_toolchain\") {\n"
    875     "    ...\n"
    876     "    toolchain_args() {\n"
    877     "      # Override the system values for a generic Posix system.\n"
    878     "      is_win = false\n"
    879     "      is_posix = true\n"
    880     "\n"
    881     "      # Pass this new value for specific setup for my toolchain.\n"
    882     "      is_my_weird_system = true\n"
    883     "    }\n"
    884     "  }\n";
    885 
    886 Value RunToolchainArgs(Scope* scope,
    887                        const FunctionCallNode* function,
    888                        const std::vector<Value>& args,
    889                        BlockNode* block,
    890                        Err* err) {
    891   // Find the toolchain definition we're executing inside of. The toolchain
    892   // function will set a property pointing to it that we'll pick up.
    893   Toolchain* toolchain = reinterpret_cast<Toolchain*>(
    894       scope->GetProperty(&kToolchainPropertyKey, NULL));
    895   if (!toolchain) {
    896     *err = Err(function->function(),
    897                "toolchain_args() called outside of toolchain().",
    898                "The toolchain_args() function can only be used inside a "
    899                "toolchain() definition.");
    900     return Value();
    901   }
    902 
    903   if (!args.empty()) {
    904     *err = Err(function->function(), "This function takes no arguments.");
    905     return Value();
    906   }
    907 
    908   // This function makes a new scope with various variable sets on it, which
    909   // we then save on the toolchain to use when re-invoking the build.
    910   Scope block_scope(scope);
    911   block->ExecuteBlockInScope(&block_scope, err);
    912   if (err->has_error())
    913     return Value();
    914 
    915   Scope::KeyValueMap values;
    916   block_scope.GetCurrentScopeValues(&values);
    917   toolchain->args() = values;
    918 
    919   return Value();
    920 }
    921 
    922 }  // namespace functions
    923