functions.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file. 4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h" 6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <iostream> 8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/environment.h" 10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/string_util.h" 11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config.h" 12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/config_values_generator.h" 13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/err.h" 14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/input_file.h" 15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parse_tree.h" 16d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scheduler.h" 17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/scope.h" 18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/settings.h" 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "tools/gn/template.h" 20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h" 21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/value.h" 22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool EnsureNotProcessingImport(const ParseNode* node, 24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Scope* scope, 25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (scope->IsProcessingImport()) { 27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(node, "Not valid from an import.", 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "Imports are for defining defaults, variables, and rules. The\n" 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "appropriate place for this kind of thing is really in a normal\n" 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "BUILD file."); 31a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 32a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 35a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 36a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool EnsureNotProcessingBuildConfig(const ParseNode* node, 37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Scope* scope, 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (scope->IsProcessingBuildConfig()) { 40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(node, "Not valid from the build config.", 41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "You can't do this kind of thing from the build config script, " 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "silly!\nPut it in a regular BUILD file."); 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 46a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 48a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool FillTargetBlockScope(const Scope* scope, 49a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& target_type, 51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const BlockNode* block, 52a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 53a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Scope* block_scope, 54a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!block) { 56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FillNeedsBlockError(function, err); 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Copy the target defaults, if any, into the scope we're going to execute 61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // the block in. 62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Scope* default_scope = scope->GetTargetDefaults(target_type); 63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (default_scope) { 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!default_scope->NonRecursiveMergeTo(block_scope, false, function, 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "target defaults", err)) 66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The name is the single argument to the target function. 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!EnsureSingleStringArg(function, args, err)) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Set the target name variable to the current target, and mark it used 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // because we don't want to issue an error if the script ignores it. 75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::StringPiece target_name("target_name"); 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) block_scope->SetValue(target_name, Value(function, args[0].string_value()), 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) function); 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) block_scope->MarkUsed(target_name); 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return true; 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void FillNeedsBlockError(const FunctionCallNode* function, Err* err) { 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "This function call requires a block.", 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "The block's \"{\" must be on the same line as the function " 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "call's \")\"."); 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool EnsureSingleStringArg(const FunctionCallNode* function, 89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 90a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (args.size() != 1) { 92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(function->function(), "Incorrect arguments.", 93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "This function requires a single string argument."); 94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return false; 95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return args[0].VerifyTypeIs(Value::STRING, err); 97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const Label& ToolchainLabelForScope(const Scope* scope) { 1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return scope->settings()->toolchain_label(); 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Label MakeLabelForScope(const Scope* scope, 104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& name) { 106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const Label& toolchain_label = ToolchainLabelForScope(scope); 1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Label(scope->GetSourceDir(), name, toolchain_label.dir(), 1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) toolchain_label.name()); 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)namespace functions { 112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// assert ---------------------------------------------------------------------- 114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kAssert[] = "assert"; 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kAssert_HelpShort[] = 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "assert: Assert an expression is true at generation time."; 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kAssert_Help[] = 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "assert: Assert an expression is true at generation time.\n" 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " assert(<condition> [, <error string>])\n" 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " If the condition is false, the build will fail with an error. If the\n" 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " optional second argument is provided, that string will be printed\n" 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " with the error message.\n" 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Examples:\n" 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " assert(is_win)\n" 1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " assert(defined(sources), \"Sources must be defined\")\n"; 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunAssert(Scope* scope, 132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (args.size() != 1 && args.size() != 2) { 136d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function->function(), "Wrong number of arguments.", 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "assert() takes one or two argument, " 138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "were you expecting somethig else?"); 1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (args[0].type() != Value::BOOLEAN) { 1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion value not a bool."); 1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else if (!args[0].boolean_value()) { 1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (args.size() == 2) { 1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Optional string message. 1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (args[1].type() != Value::STRING) { 1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion failed.", 1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "<<<ERROR MESSAGE IS NOT A STRING>>>"); 1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion failed.", 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args[1].string_value()); 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *err = Err(function->function(), "Assertion failed."); 1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 155d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args[0].origin()) { 156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // If you do "assert(foo)" we'd ideally like to show you where foo was 157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // set, and in this case the origin of the args will tell us that. 158d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // However, if you do "assert(foo && bar)" the source of the value will 159d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // be the assert like, which isn't so helpful. 160d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // 161d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // So we try to see if the args are from the same line or not. This will 162d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // break if you do "assert(\nfoo && bar)" and we may show the second line 163d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // as the source, oh well. The way around this is to check to see if the 164d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // origin node is inside our function call block. 165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Location origin_location = args[0].origin()->GetRange().begin(); 166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (origin_location.file() != function->function().location().file() || 167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch origin_location.line_number() != 168d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch function->function().location().line_number()) { 169d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch err->AppendSubErr(Err(args[0].origin()->GetRange(), "", 170d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch "This is where it was set.")); 171d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 172d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 173d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 176d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// config ---------------------------------------------------------------------- 178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kConfig[] = "config"; 180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kConfig_HelpShort[] = 181e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "config: Defines a configuration object."; 182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kConfig_Help[] = 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "config: Defines a configuration object.\n" 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " Configuration objects can be applied to targets and specify sets of\n" 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " compiler flags, includes, defines, etc. They provide a way to\n" 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " conveniently group sets of this configuration information.\n" 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " A config is referenced by its label just like a target.\n" 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " The values in a config are additive only. If you want to remove a flag\n" 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " you need to remove the corresponding config that sets it. The final\n" 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " set of flags, defines, etc. for a target is generated in this order:\n" 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 1. The values specified directly on the target (rather than using a\n" 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " config.\n" 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 2. The configs specified in the target's \"configs\" list, in order.\n" 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 3. Direct dependent configs from a breadth-first traversal of the\n" 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " dependency tree in the order that the targets appear in \"deps\".\n" 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " 4. All dependent configs from a breadth-first traversal of the\n" 20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " dependency tree in the order that the targets appear in \"deps\".\n" 20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Variables valid in a config definition:\n" 20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CONFIG_VALUES_VARS_HELP 20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Variables on a target used to apply configs:\n" 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " all_dependent_configs, configs, direct_dependent_configs,\n" 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " forward_dependent_configs_from\n" 20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Example:\n" 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " config(\"myconfig\") {\n" 21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " includes = [ \"include/common\" ]\n" 21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " defines = [ \"ENABLE_DOOM_MELON\" ]\n" 21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " }\n" 21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " executable(\"mything\") {\n" 21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " configs = [ \":myconfig\" ]\n" 21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " }\n"; 219a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 220a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunConfig(const FunctionCallNode* function, 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Scope* scope, 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!EnsureSingleStringArg(function, args, err) || 225d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch !EnsureNotProcessingImport(function, scope, err)) 226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 228d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Label label(MakeLabelForScope(scope, function, args[0].string_value())); 229d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 230d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (g_scheduler->verbose_logging()) 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) g_scheduler->Log("Defining config", label.GetUserVisibleName(true)); 232d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Create the new config. 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<Config> config(new Config(scope->settings(), label)); 235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) config->set_defined_from(function); 236e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (!Visibility::FillItemVisibility(config.get(), scope, err)) 237e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return Value(); 238d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Fill it. 2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const SourceDir& input_dir = scope->GetSourceDir(); 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ConfigValuesGenerator gen(&config->config_values(), scope, input_dir, err); 242d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch gen.Run(); 243d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 244d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 245d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 246d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Mark as complete. 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scope->settings()->build_settings()->ItemDefined(config.PassAs<Item>()); 248d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 250d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// declare_args ---------------------------------------------------------------- 252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kDeclareArgs[] = "declare_args"; 254e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kDeclareArgs_HelpShort[] = 255e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "declare_args: Declare build arguments."; 256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kDeclareArgs_Help[] = 257e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "declare_args: Declare build arguments.\n" 2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " Introduces the given arguments into the current scope. If they are\n" 2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " not specified on the command line or in a toolchain's arguments,\n" 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " the default values given in the declare_args block will be used.\n" 2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " However, these defaults will not override command-line values.\n" 2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " See also \"gn help buildargs\" for an overview.\n" 2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Example:\n" 2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " declare_args() {\n" 2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " enable_teleporter = true\n" 2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " enable_doom_melon = false\n" 2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " }\n" 2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " If you want to override the (default disabled) Doom Melon:\n" 2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n" 2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " This also sets the teleporter, but it's already defaulted to on so\n" 2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " it will have no effect.\n"; 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Value RunDeclareArgs(Scope* scope, 2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FunctionCallNode* function, 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) BlockNode* block, 281a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Scope block_scope(scope); 2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) block->ExecuteBlockInScope(&block_scope, err); 2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err->has_error()) 285d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 286d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Pass the values from our scope into the Args object for adding to the 2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // scope with the proper values (taking into account the defaults given in 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the block_scope, and arguments passed into the build). 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Scope::KeyValueMap values; 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) block_scope.GetCurrentScopeValues(&values); 2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scope->settings()->build_settings()->build_args().DeclareArgs( 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) values, scope, err); 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// defined --------------------------------------------------------------------- 298d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kDefined[] = "defined"; 300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kDefined_HelpShort[] = 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch "defined: Returns whether an identifier is defined."; 3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kDefined_Help[] = 3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "defined: Returns whether an identifier is defined.\n" 3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " Returns true if the given argument is defined. This is most useful in\n" 3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " templates to assert that the caller set things up properly.\n" 3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 308effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " You can pass an identifier:\n" 309effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " defined(foo)\n" 310effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " which will return true or false depending on whether foo is defined in\n" 311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " the current scope.\n" 312effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "\n" 313effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " You can also check a named scope:\n" 314effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " defined(foo.bar)\n" 315effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " which returns true if both foo is defined and bar is defined on the\n" 316effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " named scope foo. It will throw an error if foo is defined but is not\n" 317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " a scope.\n" 318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "\n" 3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "Example:\n" 3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " template(\"mytemplate\") {\n" 3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " # To help users call this template properly...\n" 323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " assert(defined(invoker.sources), \"Sources must be defined\")\n" 3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) "\n" 3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " # If we want to accept an optional \"values\" argument, we don't\n" 3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " # want to dereference something that may not be defined.\n" 327effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " if (defined(invoker.values)) {\n" 328effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " values = invoker.values\n" 329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " } else {\n" 330effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch " values = \"some default value\"\n" 3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " }\n" 3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) " }\n"; 3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Value RunDefined(Scope* scope, 3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const FunctionCallNode* function, 3363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ListNode* args_list, 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Err* err) { 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::vector<const ParseNode*>& args_vector = args_list->contents(); 339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (args_vector.size() != 1) { 340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *err = Err(function, "Wrong number of arguments to defined().", 341effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "Expecting exactly one."); 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 343d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 344d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const IdentifierNode* identifier = args_vector[0]->AsIdentifier(); 346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (identifier) { 347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Passed an identifier "defined(foo)". 348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (scope->GetValue(identifier->value().value())) 349effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, true); 350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, false); 351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 352effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const AccessorNode* accessor = args_vector[0]->AsAccessor(); 354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (accessor) { 355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Passed an accessor "defined(foo.bar)". 356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (accessor->member()) { 357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // The base of the accessor must be a scope if it's defined. 358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Value* base = scope->GetValue(accessor->base().value()); 359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!base) 360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, false); 361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (!base->VerifyTypeIs(Value::SCOPE, err)) 362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Check the member inside the scope to see if its defined. 365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (base->scope_value()->GetValue(accessor->member()->value().value())) 366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, true); 367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(function, false); 368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // Argument is invalid. 372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch *err = Err(function, "Bad thing passed to defined().", 373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "It should be of the form defined(foo) or defined(foo.bar)."); 374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return Value(); 375d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 376d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// getenv ---------------------------------------------------------------------- 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kGetEnv[] = "getenv"; 380e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kGetEnv_HelpShort[] = 381e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "getenv: Get an environment variable."; 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kGetEnv_Help[] = 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "getenv: Get an environment variable.\n" 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " value = getenv(env_var_name)\n" 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " Returns the value of the given enironment variable. If the value is\n" 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " not found, it will try to look up the variable with the \"opposite\"\n" 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " case (based on the case of the first letter of the variable), but\n" 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " is otherwise case-sensitive.\n" 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " If the environment variable is not found, the empty string will be\n" 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " returned. Note: it might be nice to extend this if we had the concept\n" 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " of \"none\" in the language to indicate lookup failure.\n" 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Example:\n" 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "\n" 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " home_dir = getenv(\"HOME\")\n"; 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Value RunGetEnv(Scope* scope, 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const FunctionCallNode* function, 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<Value>& args, 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Err* err) { 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!EnsureSingleStringArg(function, args, err)) 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Value(); 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string result; 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!env->GetVar(args[0].string_value().c_str(), &result)) 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Value(function, ""); // Not found, return empty string. 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return Value(function, result); 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// import ---------------------------------------------------------------------- 416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kImport[] = "import"; 418e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kImport_HelpShort[] = 419e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "import: Import a file into the current scope."; 420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kImport_Help[] = 421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "import: Import a file into the current scope.\n" 422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " The import command loads the rules and variables resulting from\n" 424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " executing the given file into the current scope.\n" 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " By convention, imported files are named with a .gni extension.\n" 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " An import is different than a C++ \"include\". The imported file is\n" 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " executed in a standalone environment from the caller of the import\n" 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " command. The results of this execution are cached for other files that\n" 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " import the same .gni file.\n" 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " Note that you can not import a BUILD.gn file that's otherwise used\n" 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " in the build. Files must either be imported or implicitly loaded as\n" 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " a result of deps rules, but not both.\n" 436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " The imported file's scope will be merged with the scope at the point\n" 438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " import was called. If there is a conflict (both the current scope and\n" 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " the imported file define some variable or rule with the same name but\n" 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " different value), a runtime error will be thrown. Therefore, it's good\n" 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " practice to minimize the stuff that an imported file defines.\n" 442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Examples:\n" 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " import(\"//build/rules/idl_compilation_rule.gni\")\n" 446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " # Looks in the current directory.\n" 448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " import(\"my_vars.gni\")\n"; 449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunImport(Scope* scope, 451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!EnsureSingleStringArg(function, args, err)) 455d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 456d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const SourceDir& input_dir = scope->GetSourceDir(); 458d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch SourceFile import_file = 459d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch input_dir.ResolveRelativeFile(args[0].string_value()); 460d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->settings()->import_manager().DoImport(import_file, function, 461d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope, err); 462d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 463d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 464d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// set_sources_assignment_filter ----------------------------------------------- 466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; 468e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kSetSourcesAssignmentFilter_HelpShort[] = 469e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "set_sources_assignment_filter: Set a pattern to filter source files."; 470a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kSetSourcesAssignmentFilter_Help[] = 47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "set_sources_assignment_filter: Set a pattern to filter source files.\n" 47268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 47368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " The sources assignment filter is a list of patterns that remove files\n" 47468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " from the list implicitly whenever the \"sources\" variable is\n" 47568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " assigned to. This is intended to be used to globally filter out files\n" 47668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " with platform-specific naming schemes when they don't apply, for\n" 47768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " example, you may want to filter out all \"*_win.cc\" files on non-\n" 47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " Windows platforms.\n" 47968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " See \"gn help patterns\" for specifics on patterns.\n" 48168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " Typically this will be called once in the master build config script\n" 48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " to set up the filter for the current platform. Subsequent calls will\n" 48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " overwrite the previous values.\n" 48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " If you want to bypass the filter and add a file even if it might\n" 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " be filtered out, call set_sources_assignment_filter([]) to clear the\n" 48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " list of filters. This will apply until the current scope exits\n" 48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "\n" 49068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "Example:\n" 49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " # Filter out all _win files.\n" 49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) " set_sources_assignment_filter([ \"*_win.cc\", \"*_win.h\" ])\n"; 493a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunSetSourcesAssignmentFilter(Scope* scope, 495a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 496a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 498d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (args.size() != 1) { 499d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch *err = Err(function, "set_sources_assignment_filter takes one argument."); 500d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } else { 501d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<PatternList> f(new PatternList); 502d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch f->SetFromValue(args[0], err); 503d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!err->has_error()) 504d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->set_sources_assignment_filter(f.Pass()); 505d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 506d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 507d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 508d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// print ----------------------------------------------------------------------- 510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kPrint[] = "print"; 512e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kPrint_HelpShort[] = 513e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "print: Prints to the console."; 514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kPrint_Help[] = 515e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "print: Prints to the console.\n" 516e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "\n" 517a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " Prints all arguments to the console separated by spaces. A newline is\n" 518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " automatically appended to the end.\n" 519a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 520a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " This function is intended for debugging. Note that build files are run\n" 521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " in parallel so you may get interleaved prints. A buildfile may also\n" 522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " be executed more than once in parallel in the context of different\n" 523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " toolchains so the prints from one file may be duplicated or\n" 524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " interleaved with itself.\n" 525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "Examples:\n" 527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " print(\"Hello world\")\n" 528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) "\n" 529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) " print(sources, deps)\n"; 530a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 531a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunPrint(Scope* scope, 532a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 533a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::vector<Value>& args, 534a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 535c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string output; 536d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch for (size_t i = 0; i < args.size(); i++) { 537d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (i != 0) 538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output.push_back(' '); 539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output.append(args[i].ToString(false)); 540d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 541c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch output.push_back('\n'); 542c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 543c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const BuildSettings::PrintCallback& cb = 544c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scope->settings()->build_settings()->print_callback(); 545c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (cb.is_null()) 546c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch printf("%s", output.c_str()); 547c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch else 548c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch cb.Run(output); 549c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 550d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 551d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 552d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 553a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// ----------------------------------------------------------------------------- 554d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 555a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)FunctionInfo::FunctionInfo() 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 558a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(NULL), 559a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(NULL), 560e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(NULL), 561e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(NULL), 562e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(false) { 563d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 564d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 565e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(SelfEvaluatingArgsFunction seaf, 566e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 567e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 568e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(seaf), 5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) executed_block_runner(NULL), 5723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) no_block_runner(NULL), 573e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 574e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 575e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 578e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(GenericBlockFunction gbf, 579e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 580e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 581e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(gbf), 584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(NULL), 585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(NULL), 586e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 587e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 588e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 589d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 590d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 591e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(ExecutedBlockFunction ebf, 592e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 593e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 594e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 5963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 597a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(ebf), 598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(NULL), 599e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 600e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 601e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 602d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 603d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 604e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochFunctionInfo::FunctionInfo(NoBlockFunction nbf, 605e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help_short, 606e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const char* in_help, 607e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool in_is_target) 6083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : self_evaluating_args_runner(NULL), 6093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) generic_block_runner(NULL), 610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) executed_block_runner(NULL), 611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) no_block_runner(nbf), 612e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help_short(in_help_short), 613e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch help(in_help), 614e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target(in_is_target) { 615d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 616d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Setup the function map via a static initializer. We use this because it 618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// avoids race conditions without having to do some global setup function or 619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// locking-heavy singleton checks at runtime. In practice, we always need this 620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// before we can do anything interesting, so it's OK to wait for the 621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// initializer. 622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)struct FunctionInfoInitializer { 623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionInfoMap map; 624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionInfoInitializer() { 626e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch #define INSERT_FUNCTION(command, is_target) \ 627e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch map[k##command] = FunctionInfo(&Run##command, \ 628e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch k##command##_HelpShort, \ 629e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch k##command##_Help, \ 630e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_target); 631e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 632e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Action, true) 633e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ActionForEach, true) 634e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Component, true) 635e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Executable, true) 636e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Group, true) 637e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SharedLibrary, true) 638e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SourceSet, true) 639e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(StaticLibrary, true) 640e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Test, true) 641e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 642e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Assert, false) 643e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Config, false) 644e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Copy, false) 645e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(DeclareArgs, false) 646e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Defined, false) 647e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ExecScript, false) 648e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(GetEnv, false) 649e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Import, false) 650e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Print, false) 651e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ProcessFileTemplate, false) 652e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ReadFile, false) 653e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(RebasePath, false) 654e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SetDefaults, false) 655e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SetDefaultToolchain, false) 656e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(SetSourcesAssignmentFilter, false) 657e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Template, false) 658e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Tool, false) 659e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(Toolchain, false) 660e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(ToolchainArgs, false) 661e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch INSERT_FUNCTION(WriteFile, false) 662a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 663a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) #undef INSERT_FUNCTION 664a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 665a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}; 666a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const FunctionInfoInitializer function_info; 667d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 668a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const FunctionInfoMap& GetFunctions() { 669a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return function_info.map; 670d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 671d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 672a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)Value RunFunction(Scope* scope, 673a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionCallNode* function, 6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ListNode* args_list, 675a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) BlockNode* block, 676a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Err* err) { 677d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const Token& name = function->function(); 678d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 679a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const FunctionInfoMap& function_map = GetFunctions(); 680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FunctionInfoMap::const_iterator found_function = 681a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) function_map.find(name.value()); 682a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found_function == function_map.end()) { 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No built-in function matching this, check for a template. 684effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const Template* templ = 685d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scope->GetTemplate(function->function().value().as_string()); 686effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (templ) { 6873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value args = args_list->Execute(scope, err); 6883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err->has_error()) 6893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 690effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return templ->Invoke(scope, function, args.list_value(), block, err); 6913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 692d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 693a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) *err = Err(name, "Unknown function."); 694a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Value(); 695a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 696a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 6973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (found_function->second.self_evaluating_args_runner) { 6983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return found_function->second.self_evaluating_args_runner( 6993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scope, function, args_list, err); 7003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 7013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 7023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // All other function types take a pre-executed set of args. 7033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Value args = args_list->Execute(scope, err); 7043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (err->has_error()) 7053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return Value(); 7063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 707a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found_function->second.generic_block_runner) { 708a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!block) { 709a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FillNeedsBlockError(function, err); 710a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Value(); 711a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 712a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return found_function->second.generic_block_runner( 7133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scope, function, args.list_value(), block, err); 714a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 715a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (found_function->second.executed_block_runner) { 717a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!block) { 718a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) FillNeedsBlockError(function, err); 719a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Value(); 720a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 721d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 722d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Scope block_scope(scope); 723d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch block->ExecuteBlockInScope(&block_scope, err); 724d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (err->has_error()) 725d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return Value(); 726a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return found_function->second.executed_block_runner( 7273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) function, args.list_value(), &block_scope, err); 728d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch } 729d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Otherwise it's a no-block function. 7313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return found_function->second.no_block_runner(scope, function, 7323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args.list_value(), err); 733d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 734a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 735a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} // namespace functions 736