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 "tools/gn/functions.h" 6 7 #include <iostream> 8 9 #include "base/strings/string_util.h" 10 #include "tools/gn/config.h" 11 #include "tools/gn/config_values_generator.h" 12 #include "tools/gn/err.h" 13 #include "tools/gn/input_file.h" 14 #include "tools/gn/parse_tree.h" 15 #include "tools/gn/scheduler.h" 16 #include "tools/gn/scope.h" 17 #include "tools/gn/settings.h" 18 #include "tools/gn/token.h" 19 #include "tools/gn/value.h" 20 21 namespace { 22 23 // This is called when a template is invoked. When we see a template 24 // declaration, that funciton is RunTemplate. 25 Value RunTemplateInvocation(Scope* scope, 26 const FunctionCallNode* invocation, 27 const std::vector<Value>& args, 28 BlockNode* block, 29 const FunctionCallNode* rule, 30 Err* err) { 31 if (!EnsureNotProcessingImport(invocation, scope, err)) 32 return Value(); 33 34 Scope block_scope(scope); 35 if (!FillTargetBlockScope(scope, invocation, 36 invocation->function().value().as_string(), 37 block, args, &block_scope, err)) 38 return Value(); 39 40 // Run the block for the rule invocation. 41 block->ExecuteBlockInScope(&block_scope, err); 42 if (err->has_error()) 43 return Value(); 44 45 // Now run the rule itself with that block as the current scope. 46 rule->block()->ExecuteBlockInScope(&block_scope, err); 47 if (err->has_error()) 48 return Value(); 49 50 block_scope.CheckForUnusedVars(err); 51 return Value(); 52 } 53 54 } // namespace 55 56 // ---------------------------------------------------------------------------- 57 58 bool EnsureNotProcessingImport(const ParseNode* node, 59 const Scope* scope, 60 Err* err) { 61 if (scope->IsProcessingImport()) { 62 *err = Err(node, "Not valid from an import.", 63 "Imports are for defining defaults, variables, and rules. The\n" 64 "appropriate place for this kind of thing is really in a normal\n" 65 "BUILD file."); 66 return false; 67 } 68 return true; 69 } 70 71 bool EnsureNotProcessingBuildConfig(const ParseNode* node, 72 const Scope* scope, 73 Err* err) { 74 if (scope->IsProcessingBuildConfig()) { 75 *err = Err(node, "Not valid from the build config.", 76 "You can't do this kind of thing from the build config script, " 77 "silly!\nPut it in a regular BUILD file."); 78 return false; 79 } 80 return true; 81 } 82 83 bool FillTargetBlockScope(const Scope* scope, 84 const FunctionCallNode* function, 85 const std::string& target_type, 86 const BlockNode* block, 87 const std::vector<Value>& args, 88 Scope* block_scope, 89 Err* err) { 90 if (!block) { 91 FillNeedsBlockError(function, err); 92 return false; 93 } 94 95 // Copy the target defaults, if any, into the scope we're going to execute 96 // the block in. 97 const Scope* default_scope = scope->GetTargetDefaults(target_type); 98 if (default_scope) { 99 if (!default_scope->NonRecursiveMergeTo(block_scope, function, 100 "target defaults", err)) 101 return false; 102 } 103 104 // The name is the single argument to the target function. 105 if (!EnsureSingleStringArg(function, args, err)) 106 return false; 107 108 // Set the target name variable to the current target, and mark it used 109 // because we don't want to issue an error if the script ignores it. 110 const base::StringPiece target_name("target_name"); 111 block_scope->SetValue(target_name, Value(function, args[0].string_value()), 112 function); 113 block_scope->MarkUsed(target_name); 114 return true; 115 } 116 117 void FillNeedsBlockError(const FunctionCallNode* function, Err* err) { 118 *err = Err(function->function(), "This function call requires a block.", 119 "The block's \"{\" must be on the same line as the function " 120 "call's \")\"."); 121 } 122 123 bool EnsureSingleStringArg(const FunctionCallNode* function, 124 const std::vector<Value>& args, 125 Err* err) { 126 if (args.size() != 1) { 127 *err = Err(function->function(), "Incorrect arguments.", 128 "This function requires a single string argument."); 129 return false; 130 } 131 return args[0].VerifyTypeIs(Value::STRING, err); 132 } 133 134 const Label& ToolchainLabelForScope(const Scope* scope) { 135 return scope->settings()->toolchain_label(); 136 } 137 138 Label MakeLabelForScope(const Scope* scope, 139 const FunctionCallNode* function, 140 const std::string& name) { 141 const Label& toolchain_label = ToolchainLabelForScope(scope); 142 return Label(scope->GetSourceDir(), name, toolchain_label.dir(), 143 toolchain_label.name()); 144 } 145 146 namespace functions { 147 148 // assert ---------------------------------------------------------------------- 149 150 const char kAssert[] = "assert"; 151 const char kAssert_Help[] = 152 "assert: Assert an expression is true at generation time.\n" 153 "\n" 154 " assert(<condition> [, <error string>])\n" 155 "\n" 156 " If the condition is false, the build will fail with an error. If the\n" 157 " optional second argument is provided, that string will be printed\n" 158 " with the error message.\n" 159 "\n" 160 "Examples:\n" 161 " assert(is_win)\n" 162 " assert(defined(sources), \"Sources must be defined\")\n"; 163 164 Value RunAssert(Scope* scope, 165 const FunctionCallNode* function, 166 const std::vector<Value>& args, 167 Err* err) { 168 if (args.size() != 1 && args.size() != 2) { 169 *err = Err(function->function(), "Wrong number of arguments.", 170 "assert() takes one or two argument, " 171 "were you expecting somethig else?"); 172 } else if (args[0].type() != Value::BOOLEAN) { 173 *err = Err(function->function(), "Assertion value not a bool."); 174 } else if (!args[0].boolean_value()) { 175 if (args.size() == 2) { 176 // Optional string message. 177 if (args[1].type() != Value::STRING) { 178 *err = Err(function->function(), "Assertion failed.", 179 "<<<ERROR MESSAGE IS NOT A STRING>>>"); 180 } else { 181 *err = Err(function->function(), "Assertion failed.", 182 args[1].string_value()); 183 } 184 } else { 185 *err = Err(function->function(), "Assertion failed."); 186 } 187 188 if (args[0].origin()) { 189 // If you do "assert(foo)" we'd ideally like to show you where foo was 190 // set, and in this case the origin of the args will tell us that. 191 // However, if you do "assert(foo && bar)" the source of the value will 192 // be the assert like, which isn't so helpful. 193 // 194 // So we try to see if the args are from the same line or not. This will 195 // break if you do "assert(\nfoo && bar)" and we may show the second line 196 // as the source, oh well. The way around this is to check to see if the 197 // origin node is inside our function call block. 198 Location origin_location = args[0].origin()->GetRange().begin(); 199 if (origin_location.file() != function->function().location().file() || 200 origin_location.line_number() != 201 function->function().location().line_number()) { 202 err->AppendSubErr(Err(args[0].origin()->GetRange(), "", 203 "This is where it was set.")); 204 } 205 } 206 } 207 return Value(); 208 } 209 210 // config ---------------------------------------------------------------------- 211 212 const char kConfig[] = "config"; 213 const char kConfig_Help[] = 214 "config: Defines a configuration object.\n" 215 "\n" 216 " Configuration objects can be applied to targets and specify sets of\n" 217 " compiler flags, includes, defines, etc. They provide a way to\n" 218 " conveniently group sets of this configuration information.\n" 219 "\n" 220 " A config is referenced by its label just like a target.\n" 221 "\n" 222 " The values in a config are additive only. If you want to remove a flag\n" 223 " you need to remove the corresponding config that sets it. The final\n" 224 " set of flags, defines, etc. for a target is generated in this order:\n" 225 "\n" 226 " 1. The values specified directly on the target (rather than using a\n" 227 " config.\n" 228 " 2. The configs specified in the target's \"configs\" list, in order.\n" 229 " 3. Direct dependent configs from a breadth-first traversal of the\n" 230 " dependency tree in the order that the targets appear in \"deps\".\n" 231 " 4. All dependent configs from a breadth-first traversal of the\n" 232 " dependency tree in the order that the targets appear in \"deps\".\n" 233 "\n" 234 "Variables valid in a config definition:\n" 235 CONFIG_VALUES_VARS_HELP 236 "\n" 237 "Variables on a target used to apply configs:\n" 238 " all_dependent_configs, configs, direct_dependent_configs,\n" 239 " forward_dependent_configs_from\n" 240 "\n" 241 "Example:\n" 242 " config(\"myconfig\") {\n" 243 " includes = [ \"include/common\" ]\n" 244 " defines = [ \"ENABLE_DOOM_MELON\" ]\n" 245 " }\n" 246 "\n" 247 " executable(\"mything\") {\n" 248 " configs = [ \":myconfig\" ]\n" 249 " }\n"; 250 251 Value RunConfig(const FunctionCallNode* function, 252 const std::vector<Value>& args, 253 Scope* scope, 254 Err* err) { 255 if (!EnsureSingleStringArg(function, args, err) || 256 !EnsureNotProcessingImport(function, scope, err)) 257 return Value(); 258 259 Label label(MakeLabelForScope(scope, function, args[0].string_value())); 260 261 if (g_scheduler->verbose_logging()) 262 g_scheduler->Log("Defining config", label.GetUserVisibleName(true)); 263 264 // Create the new config. 265 scoped_ptr<Config> config(new Config(scope->settings(), label)); 266 config->set_defined_from(function); 267 268 // Fill it. 269 const SourceDir& input_dir = scope->GetSourceDir(); 270 ConfigValuesGenerator gen(&config->config_values(), scope, input_dir, err); 271 gen.Run(); 272 if (err->has_error()) 273 return Value(); 274 275 // Mark as complete. 276 scope->settings()->build_settings()->ItemDefined(config.PassAs<Item>()); 277 return Value(); 278 } 279 280 // declare_args ---------------------------------------------------------------- 281 282 const char kDeclareArgs[] = "declare_args"; 283 const char kDeclareArgs_Help[] = 284 "declare_args: Declare build arguments used by this file.\n" 285 "\n" 286 " Introduces the given arguments into the current scope. If they are\n" 287 " not specified on the command line or in a toolchain's arguments,\n" 288 " the default values given in the declare_args block will be used.\n" 289 " However, these defaults will not override command-line values.\n" 290 "\n" 291 " See also \"gn help buildargs\" for an overview.\n" 292 "\n" 293 "Example:\n" 294 " declare_args() {\n" 295 " enable_teleporter = true\n" 296 " enable_doom_melon = false\n" 297 " }\n" 298 "\n" 299 " If you want to override the (default disabled) Doom Melon:\n" 300 " gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n" 301 " This also sets the teleporter, but it's already defaulted to on so\n" 302 " it will have no effect.\n"; 303 304 Value RunDeclareArgs(Scope* scope, 305 const FunctionCallNode* function, 306 const std::vector<Value>& args, 307 BlockNode* block, 308 Err* err) { 309 Scope block_scope(scope); 310 block->ExecuteBlockInScope(&block_scope, err); 311 if (err->has_error()) 312 return Value(); 313 314 // Pass the values from our scope into the Args object for adding to the 315 // scope with the proper values (taking into account the defaults given in 316 // the block_scope, and arguments passed into the build). 317 Scope::KeyValueMap values; 318 block_scope.GetCurrentScopeValues(&values); 319 scope->settings()->build_settings()->build_args().DeclareArgs( 320 values, scope, err); 321 return Value(); 322 } 323 324 // defined --------------------------------------------------------------------- 325 326 const char kDefined[] = "defined"; 327 const char kDefined_Help[] = 328 "defined: Returns whether an identifier is defined.\n" 329 "\n" 330 " Returns true if the given argument is defined. This is most useful in\n" 331 " templates to assert that the caller set things up properly.\n" 332 "\n" 333 "Example:\n" 334 "\n" 335 " template(\"mytemplate\") {\n" 336 " # To help users call this template properly...\n" 337 " assert(defined(sources), \"Sources must be defined\")\n" 338 "\n" 339 " # If we want to accept an optional \"values\" argument, we don't\n" 340 " # want to dereference something that may not be defined.\n" 341 " if (!defined(outputs)) {\n" 342 " outputs = []\n" 343 " }\n" 344 " }\n"; 345 346 Value RunDefined(Scope* scope, 347 const FunctionCallNode* function, 348 const ListNode* args_list, 349 Err* err) { 350 const std::vector<const ParseNode*>& args_vector = args_list->contents(); 351 const IdentifierNode* identifier = NULL; 352 if (args_vector.size() != 1 || 353 !(identifier = args_vector[0]->AsIdentifier())) { 354 *err = Err(function, "Bad argument to defined().", 355 "defined() takes one argument which should be an identifier."); 356 return Value(); 357 } 358 359 if (scope->GetValue(identifier->value().value())) 360 return Value(function, true); 361 return Value(function, false); 362 } 363 364 // import ---------------------------------------------------------------------- 365 366 const char kImport[] = "import"; 367 const char kImport_Help[] = 368 "import: Import a file into the current scope.\n" 369 "\n" 370 " The import command loads the rules and variables resulting from\n" 371 " executing the given file into the current scope.\n" 372 "\n" 373 " By convention, imported files are named with a .gni extension.\n" 374 "\n" 375 " An import is different than a C++ \"include\". The imported file is\n" 376 " executed in a standalone environment from the caller of the import\n" 377 " command. The results of this execution are cached for other files that\n" 378 " import the same .gni file.\n" 379 "\n" 380 " Note that you can not import a BUILD.gn file that's otherwise used\n" 381 " in the build. Files must either be imported or implicitly loaded as\n" 382 " a result of deps rules, but not both.\n" 383 "\n" 384 " The imported file's scope will be merged with the scope at the point\n" 385 " import was called. If there is a conflict (both the current scope and\n" 386 " the imported file define some variable or rule with the same name but\n" 387 " different value), a runtime error will be thrown. Therefore, it's good\n" 388 " practice to minimize the stuff that an imported file defines.\n" 389 "\n" 390 "Examples:\n" 391 "\n" 392 " import(\"//build/rules/idl_compilation_rule.gni\")\n" 393 "\n" 394 " # Looks in the current directory.\n" 395 " import(\"my_vars.gni\")\n"; 396 397 Value RunImport(Scope* scope, 398 const FunctionCallNode* function, 399 const std::vector<Value>& args, 400 Err* err) { 401 if (!EnsureSingleStringArg(function, args, err)) 402 return Value(); 403 404 const SourceDir& input_dir = scope->GetSourceDir(); 405 SourceFile import_file = 406 input_dir.ResolveRelativeFile(args[0].string_value()); 407 scope->settings()->import_manager().DoImport(import_file, function, 408 scope, err); 409 return Value(); 410 } 411 412 // set_sources_assignment_filter ----------------------------------------------- 413 414 const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; 415 const char kSetSourcesAssignmentFilter_Help[] = 416 "set_sources_assignment_filter: Set a pattern to filter source files.\n" 417 "\n" 418 " The sources assignment filter is a list of patterns that remove files\n" 419 " from the list implicitly whenever the \"sources\" variable is\n" 420 " assigned to. This is intended to be used to globally filter out files\n" 421 " with platform-specific naming schemes when they don't apply, for\n" 422 " example, you may want to filter out all \"*_win.cc\" files on non-\n" 423 " Windows platforms.\n" 424 "\n" 425 " See \"gn help patterns\" for specifics on patterns.\n" 426 "\n" 427 " Typically this will be called once in the master build config script\n" 428 " to set up the filter for the current platform. Subsequent calls will\n" 429 " overwrite the previous values.\n" 430 "\n" 431 " If you want to bypass the filter and add a file even if it might\n" 432 " be filtered out, call set_sources_assignment_filter([]) to clear the\n" 433 " list of filters. This will apply until the current scope exits\n" 434 "\n" 435 "Example:\n" 436 " # Filter out all _win files.\n" 437 " set_sources_assignment_filter([ \"*_win.cc\", \"*_win.h\" ])\n"; 438 439 Value RunSetSourcesAssignmentFilter(Scope* scope, 440 const FunctionCallNode* function, 441 const std::vector<Value>& args, 442 Err* err) { 443 if (args.size() != 1) { 444 *err = Err(function, "set_sources_assignment_filter takes one argument."); 445 } else { 446 scoped_ptr<PatternList> f(new PatternList); 447 f->SetFromValue(args[0], err); 448 if (!err->has_error()) 449 scope->set_sources_assignment_filter(f.Pass()); 450 } 451 return Value(); 452 } 453 454 // print ----------------------------------------------------------------------- 455 456 const char kPrint[] = "print"; 457 const char kPrint_Help[] = 458 "print(...)\n" 459 " Prints all arguments to the console separated by spaces. A newline is\n" 460 " automatically appended to the end.\n" 461 "\n" 462 " This function is intended for debugging. Note that build files are run\n" 463 " in parallel so you may get interleaved prints. A buildfile may also\n" 464 " be executed more than once in parallel in the context of different\n" 465 " toolchains so the prints from one file may be duplicated or\n" 466 " interleaved with itself.\n" 467 "\n" 468 "Examples:\n" 469 " print(\"Hello world\")\n" 470 "\n" 471 " print(sources, deps)\n"; 472 473 Value RunPrint(Scope* scope, 474 const FunctionCallNode* function, 475 const std::vector<Value>& args, 476 Err* err) { 477 for (size_t i = 0; i < args.size(); i++) { 478 if (i != 0) 479 std::cout << " "; 480 std::cout << args[i].ToString(false); 481 } 482 std::cout << std::endl; 483 return Value(); 484 } 485 486 // ----------------------------------------------------------------------------- 487 488 FunctionInfo::FunctionInfo() 489 : self_evaluating_args_runner(NULL), 490 generic_block_runner(NULL), 491 executed_block_runner(NULL), 492 no_block_runner(NULL), 493 help(NULL) { 494 } 495 496 FunctionInfo::FunctionInfo(SelfEvaluatingArgsFunction seaf, const char* in_help) 497 : self_evaluating_args_runner(seaf), 498 generic_block_runner(NULL), 499 executed_block_runner(NULL), 500 no_block_runner(NULL), 501 help(in_help) { 502 } 503 504 FunctionInfo::FunctionInfo(GenericBlockFunction gbf, const char* in_help) 505 : self_evaluating_args_runner(NULL), 506 generic_block_runner(gbf), 507 executed_block_runner(NULL), 508 no_block_runner(NULL), 509 help(in_help) { 510 } 511 512 FunctionInfo::FunctionInfo(ExecutedBlockFunction ebf, const char* in_help) 513 : self_evaluating_args_runner(NULL), 514 generic_block_runner(NULL), 515 executed_block_runner(ebf), 516 no_block_runner(NULL), 517 help(in_help) { 518 } 519 520 FunctionInfo::FunctionInfo(NoBlockFunction nbf, const char* in_help) 521 : self_evaluating_args_runner(NULL), 522 generic_block_runner(NULL), 523 executed_block_runner(NULL), 524 no_block_runner(nbf), 525 help(in_help) { 526 } 527 528 // Setup the function map via a static initializer. We use this because it 529 // avoids race conditions without having to do some global setup function or 530 // locking-heavy singleton checks at runtime. In practice, we always need this 531 // before we can do anything interesting, so it's OK to wait for the 532 // initializer. 533 struct FunctionInfoInitializer { 534 FunctionInfoMap map; 535 536 FunctionInfoInitializer() { 537 #define INSERT_FUNCTION(command) \ 538 map[k##command] = FunctionInfo(&Run##command, k##command##_Help); 539 540 INSERT_FUNCTION(Assert) 541 INSERT_FUNCTION(Component) 542 INSERT_FUNCTION(Config) 543 INSERT_FUNCTION(Copy) 544 INSERT_FUNCTION(Custom) 545 INSERT_FUNCTION(DeclareArgs) 546 INSERT_FUNCTION(Defined) 547 INSERT_FUNCTION(ExecScript) 548 INSERT_FUNCTION(Executable) 549 INSERT_FUNCTION(Group) 550 INSERT_FUNCTION(Import) 551 INSERT_FUNCTION(Print) 552 INSERT_FUNCTION(ProcessFileTemplate) 553 INSERT_FUNCTION(ReadFile) 554 INSERT_FUNCTION(RebasePath) 555 INSERT_FUNCTION(SetDefaults) 556 INSERT_FUNCTION(SetDefaultToolchain) 557 INSERT_FUNCTION(SetSourcesAssignmentFilter) 558 INSERT_FUNCTION(SharedLibrary) 559 INSERT_FUNCTION(SourceSet) 560 INSERT_FUNCTION(StaticLibrary) 561 INSERT_FUNCTION(Template) 562 INSERT_FUNCTION(Test) 563 INSERT_FUNCTION(Tool) 564 INSERT_FUNCTION(Toolchain) 565 INSERT_FUNCTION(ToolchainArgs) 566 INSERT_FUNCTION(WriteFile) 567 568 #undef INSERT_FUNCTION 569 } 570 }; 571 const FunctionInfoInitializer function_info; 572 573 const FunctionInfoMap& GetFunctions() { 574 return function_info.map; 575 } 576 577 Value RunFunction(Scope* scope, 578 const FunctionCallNode* function, 579 const ListNode* args_list, 580 BlockNode* block, 581 Err* err) { 582 const Token& name = function->function(); 583 584 const FunctionInfoMap& function_map = GetFunctions(); 585 FunctionInfoMap::const_iterator found_function = 586 function_map.find(name.value()); 587 if (found_function == function_map.end()) { 588 // No build-in function matching this, check for a template. 589 const FunctionCallNode* rule = 590 scope->GetTemplate(function->function().value().as_string()); 591 if (rule) { 592 Value args = args_list->Execute(scope, err); 593 if (err->has_error()) 594 return Value(); 595 return RunTemplateInvocation(scope, function, args.list_value(), block, 596 rule, err); 597 } 598 599 *err = Err(name, "Unknown function."); 600 return Value(); 601 } 602 603 if (found_function->second.self_evaluating_args_runner) { 604 return found_function->second.self_evaluating_args_runner( 605 scope, function, args_list, err); 606 } 607 608 // All other function types take a pre-executed set of args. 609 Value args = args_list->Execute(scope, err); 610 if (err->has_error()) 611 return Value(); 612 613 if (found_function->second.generic_block_runner) { 614 if (!block) { 615 FillNeedsBlockError(function, err); 616 return Value(); 617 } 618 return found_function->second.generic_block_runner( 619 scope, function, args.list_value(), block, err); 620 } 621 622 if (found_function->second.executed_block_runner) { 623 if (!block) { 624 FillNeedsBlockError(function, err); 625 return Value(); 626 } 627 628 Scope block_scope(scope); 629 block->ExecuteBlockInScope(&block_scope, err); 630 if (err->has_error()) 631 return Value(); 632 return found_function->second.executed_block_runner( 633 function, args.list_value(), &block_scope, err); 634 } 635 636 // Otherwise it's a no-block function. 637 return found_function->second.no_block_runner(scope, function, 638 args.list_value(), err); 639 } 640 641 } // namespace functions 642