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.
5 #include "tools/gn/functions.h"
9 #include "base/environment.h"
10 #include "base/strings/string_util.h"
11 #include "tools/gn/config.h"
12 #include "tools/gn/config_values_generator.h"
13 #include "tools/gn/err.h"
14 #include "tools/gn/input_file.h"
15 #include "tools/gn/parse_tree.h"
16 #include "tools/gn/scheduler.h"
17 #include "tools/gn/scope.h"
18 #include "tools/gn/settings.h"
19 #include "tools/gn/token.h"
20 #include "tools/gn/value.h"
24 // This is called when a template is invoked. When we see a template
25 // declaration, that funciton is RunTemplate.
26 Value RunTemplateInvocation(Scope* scope,
27 const FunctionCallNode* invocation,
28 const std::vector<Value>& args,
30 const FunctionCallNode* rule,
32 if (!EnsureNotProcessingImport(invocation, scope, err))
35 Scope block_scope(scope);
36 if (!FillTargetBlockScope(scope, invocation,
37 invocation->function().value().as_string(),
38 block, args, &block_scope, err))
41 // Run the block for the rule invocation.
42 block->ExecuteBlockInScope(&block_scope, err);
46 // Now run the rule itself with that block as the current scope.
47 rule->block()->ExecuteBlockInScope(&block_scope, err);
51 block_scope.CheckForUnusedVars(err);
57 // ----------------------------------------------------------------------------
59 bool EnsureNotProcessingImport(const ParseNode* node,
62 if (scope->IsProcessingImport()) {
63 *err = Err(node, "Not valid from an import.",
64 "Imports are for defining defaults, variables, and rules. The\n"
65 "appropriate place for this kind of thing is really in a normal\n"
72 bool EnsureNotProcessingBuildConfig(const ParseNode* node,
75 if (scope->IsProcessingBuildConfig()) {
76 *err = Err(node, "Not valid from the build config.",
77 "You can't do this kind of thing from the build config script, "
78 "silly!\nPut it in a regular BUILD file.");
84 bool FillTargetBlockScope(const Scope* scope,
85 const FunctionCallNode* function,
86 const std::string& target_type,
87 const BlockNode* block,
88 const std::vector<Value>& args,
92 FillNeedsBlockError(function, err);
96 // Copy the target defaults, if any, into the scope we're going to execute
98 const Scope* default_scope = scope->GetTargetDefaults(target_type);
100 if (!default_scope->NonRecursiveMergeTo(block_scope, function,
101 "target defaults", err))
105 // The name is the single argument to the target function.
106 if (!EnsureSingleStringArg(function, args, err))
109 // Set the target name variable to the current target, and mark it used
110 // because we don't want to issue an error if the script ignores it.
111 const base::StringPiece target_name("target_name");
112 block_scope->SetValue(target_name, Value(function, args[0].string_value()),
114 block_scope->MarkUsed(target_name);
118 void FillNeedsBlockError(const FunctionCallNode* function, Err* err) {
119 *err = Err(function->function(), "This function call requires a block.",
120 "The block's \"{\" must be on the same line as the function "
124 bool EnsureSingleStringArg(const FunctionCallNode* function,
125 const std::vector<Value>& args,
127 if (args.size() != 1) {
128 *err = Err(function->function(), "Incorrect arguments.",
129 "This function requires a single string argument.");
132 return args[0].VerifyTypeIs(Value::STRING, err);
135 const Label& ToolchainLabelForScope(const Scope* scope) {
136 return scope->settings()->toolchain_label();
139 Label MakeLabelForScope(const Scope* scope,
140 const FunctionCallNode* function,
141 const std::string& name) {
142 const Label& toolchain_label = ToolchainLabelForScope(scope);
143 return Label(scope->GetSourceDir(), name, toolchain_label.dir(),
144 toolchain_label.name());
147 namespace functions {
149 // assert ----------------------------------------------------------------------
151 const char kAssert[] = "assert";
152 const char kAssert_Help[] =
153 "assert: Assert an expression is true at generation time.\n"
155 " assert(<condition> [, <error string>])\n"
157 " If the condition is false, the build will fail with an error. If the\n"
158 " optional second argument is provided, that string will be printed\n"
159 " with the error message.\n"
163 " assert(defined(sources), \"Sources must be defined\")\n";
165 Value RunAssert(Scope* scope,
166 const FunctionCallNode* function,
167 const std::vector<Value>& args,
169 if (args.size() != 1 && args.size() != 2) {
170 *err = Err(function->function(), "Wrong number of arguments.",
171 "assert() takes one or two argument, "
172 "were you expecting somethig else?");
173 } else if (args[0].type() != Value::BOOLEAN) {
174 *err = Err(function->function(), "Assertion value not a bool.");
175 } else if (!args[0].boolean_value()) {
176 if (args.size() == 2) {
177 // Optional string message.
178 if (args[1].type() != Value::STRING) {
179 *err = Err(function->function(), "Assertion failed.",
180 "<<<ERROR MESSAGE IS NOT A STRING>>>");
182 *err = Err(function->function(), "Assertion failed.",
183 args[1].string_value());
186 *err = Err(function->function(), "Assertion failed.");
189 if (args[0].origin()) {
190 // If you do "assert(foo)" we'd ideally like to show you where foo was
191 // set, and in this case the origin of the args will tell us that.
192 // However, if you do "assert(foo && bar)" the source of the value will
193 // be the assert like, which isn't so helpful.
195 // So we try to see if the args are from the same line or not. This will
196 // break if you do "assert(\nfoo && bar)" and we may show the second line
197 // as the source, oh well. The way around this is to check to see if the
198 // origin node is inside our function call block.
199 Location origin_location = args[0].origin()->GetRange().begin();
200 if (origin_location.file() != function->function().location().file() ||
201 origin_location.line_number() !=
202 function->function().location().line_number()) {
203 err->AppendSubErr(Err(args[0].origin()->GetRange(), "",
204 "This is where it was set."));
211 // config ----------------------------------------------------------------------
213 const char kConfig[] = "config";
214 const char kConfig_Help[] =
215 "config: Defines a configuration object.\n"
217 " Configuration objects can be applied to targets and specify sets of\n"
218 " compiler flags, includes, defines, etc. They provide a way to\n"
219 " conveniently group sets of this configuration information.\n"
221 " A config is referenced by its label just like a target.\n"
223 " The values in a config are additive only. If you want to remove a flag\n"
224 " you need to remove the corresponding config that sets it. The final\n"
225 " set of flags, defines, etc. for a target is generated in this order:\n"
227 " 1. The values specified directly on the target (rather than using a\n"
229 " 2. The configs specified in the target's \"configs\" list, in order.\n"
230 " 3. Direct dependent configs from a breadth-first traversal of the\n"
231 " dependency tree in the order that the targets appear in \"deps\".\n"
232 " 4. All dependent configs from a breadth-first traversal of the\n"
233 " dependency tree in the order that the targets appear in \"deps\".\n"
235 "Variables valid in a config definition:\n"
236 CONFIG_VALUES_VARS_HELP
238 "Variables on a target used to apply configs:\n"
239 " all_dependent_configs, configs, direct_dependent_configs,\n"
240 " forward_dependent_configs_from\n"
243 " config(\"myconfig\") {\n"
244 " includes = [ \"include/common\" ]\n"
245 " defines = [ \"ENABLE_DOOM_MELON\" ]\n"
248 " executable(\"mything\") {\n"
249 " configs = [ \":myconfig\" ]\n"
252 Value RunConfig(const FunctionCallNode* function,
253 const std::vector<Value>& args,
256 if (!EnsureSingleStringArg(function, args, err) ||
257 !EnsureNotProcessingImport(function, scope, err))
260 Label label(MakeLabelForScope(scope, function, args[0].string_value()));
262 if (g_scheduler->verbose_logging())
263 g_scheduler->Log("Defining config", label.GetUserVisibleName(true));
265 // Create the new config.
266 scoped_ptr<Config> config(new Config(scope->settings(), label));
267 config->set_defined_from(function);
270 const SourceDir& input_dir = scope->GetSourceDir();
271 ConfigValuesGenerator gen(&config->config_values(), scope, input_dir, err);
273 if (err->has_error())
277 scope->settings()->build_settings()->ItemDefined(config.PassAs<Item>());
281 // declare_args ----------------------------------------------------------------
283 const char kDeclareArgs[] = "declare_args";
284 const char kDeclareArgs_Help[] =
285 "declare_args: Declare build arguments used by this file.\n"
287 " Introduces the given arguments into the current scope. If they are\n"
288 " not specified on the command line or in a toolchain's arguments,\n"
289 " the default values given in the declare_args block will be used.\n"
290 " However, these defaults will not override command-line values.\n"
292 " See also \"gn help buildargs\" for an overview.\n"
295 " declare_args() {\n"
296 " enable_teleporter = true\n"
297 " enable_doom_melon = false\n"
300 " If you want to override the (default disabled) Doom Melon:\n"
301 " gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n"
302 " This also sets the teleporter, but it's already defaulted to on so\n"
303 " it will have no effect.\n";
305 Value RunDeclareArgs(Scope* scope,
306 const FunctionCallNode* function,
307 const std::vector<Value>& args,
310 Scope block_scope(scope);
311 block->ExecuteBlockInScope(&block_scope, err);
312 if (err->has_error())
315 // Pass the values from our scope into the Args object for adding to the
316 // scope with the proper values (taking into account the defaults given in
317 // the block_scope, and arguments passed into the build).
318 Scope::KeyValueMap values;
319 block_scope.GetCurrentScopeValues(&values);
320 scope->settings()->build_settings()->build_args().DeclareArgs(
325 // defined ---------------------------------------------------------------------
327 const char kDefined[] = "defined";
328 const char kDefined_Help[] =
329 "defined: Returns whether an identifier is defined.\n"
331 " Returns true if the given argument is defined. This is most useful in\n"
332 " templates to assert that the caller set things up properly.\n"
336 " template(\"mytemplate\") {\n"
337 " # To help users call this template properly...\n"
338 " assert(defined(sources), \"Sources must be defined\")\n"
340 " # If we want to accept an optional \"values\" argument, we don't\n"
341 " # want to dereference something that may not be defined.\n"
342 " if (!defined(outputs)) {\n"
347 Value RunDefined(Scope* scope,
348 const FunctionCallNode* function,
349 const ListNode* args_list,
351 const std::vector<const ParseNode*>& args_vector = args_list->contents();
352 const IdentifierNode* identifier = NULL;
353 if (args_vector.size() != 1 ||
354 !(identifier = args_vector[0]->AsIdentifier())) {
355 *err = Err(function, "Bad argument to defined().",
356 "defined() takes one argument which should be an identifier.");
360 if (scope->GetValue(identifier->value().value()))
361 return Value(function, true);
362 return Value(function, false);
365 // getenv ----------------------------------------------------------------------
367 const char kGetEnv[] = "getenv";
368 const char kGetEnv_Help[] =
369 "getenv: Get an environment variable.\n"
371 " value = getenv(env_var_name)\n"
373 " Returns the value of the given enironment variable. If the value is\n"
374 " not found, it will try to look up the variable with the \"opposite\"\n"
375 " case (based on the case of the first letter of the variable), but\n"
376 " is otherwise case-sensitive.\n"
378 " If the environment variable is not found, the empty string will be\n"
379 " returned. Note: it might be nice to extend this if we had the concept\n"
380 " of \"none\" in the language to indicate lookup failure.\n"
384 " home_dir = getenv(\"HOME\")\n";
386 Value RunGetEnv(Scope* scope,
387 const FunctionCallNode* function,
388 const std::vector<Value>& args,
390 if (!EnsureSingleStringArg(function, args, err))
393 scoped_ptr<base::Environment> env(base::Environment::Create());
396 if (!env->GetVar(args[0].string_value().c_str(), &result))
397 return Value(function, ""); // Not found, return empty string.
398 return Value(function, result);
401 // import ----------------------------------------------------------------------
403 const char kImport[] = "import";
404 const char kImport_Help[] =
405 "import: Import a file into the current scope.\n"
407 " The import command loads the rules and variables resulting from\n"
408 " executing the given file into the current scope.\n"
410 " By convention, imported files are named with a .gni extension.\n"
412 " An import is different than a C++ \"include\". The imported file is\n"
413 " executed in a standalone environment from the caller of the import\n"
414 " command. The results of this execution are cached for other files that\n"
415 " import the same .gni file.\n"
417 " Note that you can not import a BUILD.gn file that's otherwise used\n"
418 " in the build. Files must either be imported or implicitly loaded as\n"
419 " a result of deps rules, but not both.\n"
421 " The imported file's scope will be merged with the scope at the point\n"
422 " import was called. If there is a conflict (both the current scope and\n"
423 " the imported file define some variable or rule with the same name but\n"
424 " different value), a runtime error will be thrown. Therefore, it's good\n"
425 " practice to minimize the stuff that an imported file defines.\n"
429 " import(\"//build/rules/idl_compilation_rule.gni\")\n"
431 " # Looks in the current directory.\n"
432 " import(\"my_vars.gni\")\n";
434 Value RunImport(Scope* scope,
435 const FunctionCallNode* function,
436 const std::vector<Value>& args,
438 if (!EnsureSingleStringArg(function, args, err))
441 const SourceDir& input_dir = scope->GetSourceDir();
442 SourceFile import_file =
443 input_dir.ResolveRelativeFile(args[0].string_value());
444 scope->settings()->import_manager().DoImport(import_file, function,
449 // set_sources_assignment_filter -----------------------------------------------
451 const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter";
452 const char kSetSourcesAssignmentFilter_Help[] =
453 "set_sources_assignment_filter: Set a pattern to filter source files.\n"
455 " The sources assignment filter is a list of patterns that remove files\n"
456 " from the list implicitly whenever the \"sources\" variable is\n"
457 " assigned to. This is intended to be used to globally filter out files\n"
458 " with platform-specific naming schemes when they don't apply, for\n"
459 " example, you may want to filter out all \"*_win.cc\" files on non-\n"
460 " Windows platforms.\n"
462 " See \"gn help patterns\" for specifics on patterns.\n"
464 " Typically this will be called once in the master build config script\n"
465 " to set up the filter for the current platform. Subsequent calls will\n"
466 " overwrite the previous values.\n"
468 " If you want to bypass the filter and add a file even if it might\n"
469 " be filtered out, call set_sources_assignment_filter([]) to clear the\n"
470 " list of filters. This will apply until the current scope exits\n"
473 " # Filter out all _win files.\n"
474 " set_sources_assignment_filter([ \"*_win.cc\", \"*_win.h\" ])\n";
476 Value RunSetSourcesAssignmentFilter(Scope* scope,
477 const FunctionCallNode* function,
478 const std::vector<Value>& args,
480 if (args.size() != 1) {
481 *err = Err(function, "set_sources_assignment_filter takes one argument.");
483 scoped_ptr<PatternList> f(new PatternList);
484 f->SetFromValue(args[0], err);
485 if (!err->has_error())
486 scope->set_sources_assignment_filter(f.Pass());
491 // print -----------------------------------------------------------------------
493 const char kPrint[] = "print";
494 const char kPrint_Help[] =
496 " Prints all arguments to the console separated by spaces. A newline is\n"
497 " automatically appended to the end.\n"
499 " This function is intended for debugging. Note that build files are run\n"
500 " in parallel so you may get interleaved prints. A buildfile may also\n"
501 " be executed more than once in parallel in the context of different\n"
502 " toolchains so the prints from one file may be duplicated or\n"
503 " interleaved with itself.\n"
506 " print(\"Hello world\")\n"
508 " print(sources, deps)\n";
510 Value RunPrint(Scope* scope,
511 const FunctionCallNode* function,
512 const std::vector<Value>& args,
514 for (size_t i = 0; i < args.size(); i++) {
517 std::cout << args[i].ToString(false);
519 std::cout << std::endl;
523 // -----------------------------------------------------------------------------
525 FunctionInfo::FunctionInfo()
526 : self_evaluating_args_runner(NULL),
527 generic_block_runner(NULL),
528 executed_block_runner(NULL),
529 no_block_runner(NULL),
533 FunctionInfo::FunctionInfo(SelfEvaluatingArgsFunction seaf, const char* in_help)
534 : self_evaluating_args_runner(seaf),
535 generic_block_runner(NULL),
536 executed_block_runner(NULL),
537 no_block_runner(NULL),
541 FunctionInfo::FunctionInfo(GenericBlockFunction gbf, const char* in_help)
542 : self_evaluating_args_runner(NULL),
543 generic_block_runner(gbf),
544 executed_block_runner(NULL),
545 no_block_runner(NULL),
549 FunctionInfo::FunctionInfo(ExecutedBlockFunction ebf, const char* in_help)
550 : self_evaluating_args_runner(NULL),
551 generic_block_runner(NULL),
552 executed_block_runner(ebf),
553 no_block_runner(NULL),
557 FunctionInfo::FunctionInfo(NoBlockFunction nbf, const char* in_help)
558 : self_evaluating_args_runner(NULL),
559 generic_block_runner(NULL),
560 executed_block_runner(NULL),
561 no_block_runner(nbf),
565 // Setup the function map via a static initializer. We use this because it
566 // avoids race conditions without having to do some global setup function or
567 // locking-heavy singleton checks at runtime. In practice, we always need this
568 // before we can do anything interesting, so it's OK to wait for the
570 struct FunctionInfoInitializer {
573 FunctionInfoInitializer() {
574 #define INSERT_FUNCTION(command) \
575 map[k##command] = FunctionInfo(&Run##command, k##command##_Help);
577 INSERT_FUNCTION(Assert)
578 INSERT_FUNCTION(Component)
579 INSERT_FUNCTION(Config)
580 INSERT_FUNCTION(Copy)
581 INSERT_FUNCTION(Custom)
582 INSERT_FUNCTION(DeclareArgs)
583 INSERT_FUNCTION(Defined)
584 INSERT_FUNCTION(ExecScript)
585 INSERT_FUNCTION(Executable)
586 INSERT_FUNCTION(GetEnv)
587 INSERT_FUNCTION(Group)
588 INSERT_FUNCTION(Import)
589 INSERT_FUNCTION(Print)
590 INSERT_FUNCTION(ProcessFileTemplate)
591 INSERT_FUNCTION(ReadFile)
592 INSERT_FUNCTION(RebasePath)
593 INSERT_FUNCTION(SetDefaults)
594 INSERT_FUNCTION(SetDefaultToolchain)
595 INSERT_FUNCTION(SetSourcesAssignmentFilter)
596 INSERT_FUNCTION(SharedLibrary)
597 INSERT_FUNCTION(SourceSet)
598 INSERT_FUNCTION(StaticLibrary)
599 INSERT_FUNCTION(Template)
600 INSERT_FUNCTION(Test)
601 INSERT_FUNCTION(Tool)
602 INSERT_FUNCTION(Toolchain)
603 INSERT_FUNCTION(ToolchainArgs)
604 INSERT_FUNCTION(WriteFile)
606 #undef INSERT_FUNCTION
609 const FunctionInfoInitializer function_info;
611 const FunctionInfoMap& GetFunctions() {
612 return function_info.map;
615 Value RunFunction(Scope* scope,
616 const FunctionCallNode* function,
617 const ListNode* args_list,
620 const Token& name = function->function();
622 const FunctionInfoMap& function_map = GetFunctions();
623 FunctionInfoMap::const_iterator found_function =
624 function_map.find(name.value());
625 if (found_function == function_map.end()) {
626 // No built-in function matching this, check for a template.
627 const FunctionCallNode* rule =
628 scope->GetTemplate(function->function().value().as_string());
630 Value args = args_list->Execute(scope, err);
631 if (err->has_error())
633 return RunTemplateInvocation(scope, function, args.list_value(), block,
637 *err = Err(name, "Unknown function.");
641 if (found_function->second.self_evaluating_args_runner) {
642 return found_function->second.self_evaluating_args_runner(
643 scope, function, args_list, err);
646 // All other function types take a pre-executed set of args.
647 Value args = args_list->Execute(scope, err);
648 if (err->has_error())
651 if (found_function->second.generic_block_runner) {
653 FillNeedsBlockError(function, err);
656 return found_function->second.generic_block_runner(
657 scope, function, args.list_value(), block, err);
660 if (found_function->second.executed_block_runner) {
662 FillNeedsBlockError(function, err);
666 Scope block_scope(scope);
667 block->ExecuteBlockInScope(&block_scope, err);
668 if (err->has_error())
670 return found_function->second.executed_block_runner(
671 function, args.list_value(), &block_scope, err);
674 // Otherwise it's a no-block function.
675 return found_function->second.no_block_runner(scope, function,
676 args.list_value(), err);
679 } // namespace functions