| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "tools/gn/functions.h" | 5 #include "tools/gn/functions.h" | 
| 6 | 6 | 
| 7 #include <stddef.h> | 7 #include <stddef.h> | 
| 8 #include <iostream> | 8 #include <iostream> | 
| 9 #include <utility> | 9 #include <utility> | 
| 10 | 10 | 
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 174 } | 174 } | 
| 175 | 175 | 
| 176 namespace functions { | 176 namespace functions { | 
| 177 | 177 | 
| 178 // assert ---------------------------------------------------------------------- | 178 // assert ---------------------------------------------------------------------- | 
| 179 | 179 | 
| 180 const char kAssert[] = "assert"; | 180 const char kAssert[] = "assert"; | 
| 181 const char kAssert_HelpShort[] = | 181 const char kAssert_HelpShort[] = | 
| 182     "assert: Assert an expression is true at generation time."; | 182     "assert: Assert an expression is true at generation time."; | 
| 183 const char kAssert_Help[] = | 183 const char kAssert_Help[] = | 
| 184     "assert: Assert an expression is true at generation time.\n" | 184     R"(assert: Assert an expression is true at generation time. | 
| 185     "\n" | 185 | 
| 186     "  assert(<condition> [, <error string>])\n" | 186   assert(<condition> [, <error string>]) | 
| 187     "\n" | 187 | 
| 188     "  If the condition is false, the build will fail with an error. If the\n" | 188   If the condition is false, the build will fail with an error. If the | 
| 189     "  optional second argument is provided, that string will be printed\n" | 189   optional second argument is provided, that string will be printed | 
| 190     "  with the error message.\n" | 190   with the error message. | 
| 191     "\n" | 191 | 
| 192     "Examples:\n" | 192 Examples | 
| 193     "  assert(is_win)\n" | 193 | 
| 194     "  assert(defined(sources), \"Sources must be defined\")\n"; | 194   assert(is_win) | 
|  | 195   assert(defined(sources), "Sources must be defined"); | 
|  | 196 )"; | 
| 195 | 197 | 
| 196 Value RunAssert(Scope* scope, | 198 Value RunAssert(Scope* scope, | 
| 197                 const FunctionCallNode* function, | 199                 const FunctionCallNode* function, | 
| 198                 const std::vector<Value>& args, | 200                 const std::vector<Value>& args, | 
| 199                 Err* err) { | 201                 Err* err) { | 
| 200   if (args.size() != 1 && args.size() != 2) { | 202   if (args.size() != 1 && args.size() != 2) { | 
| 201     *err = Err(function->function(), "Wrong number of arguments.", | 203     *err = Err(function->function(), "Wrong number of arguments.", | 
| 202                "assert() takes one or two argument, " | 204                "assert() takes one or two argument, " | 
| 203                "were you expecting somethig else?"); | 205                "were you expecting somethig else?"); | 
| 204   } else if (args[0].type() != Value::BOOLEAN) { | 206   } else if (args[0].type() != Value::BOOLEAN) { | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 238   } | 240   } | 
| 239   return Value(); | 241   return Value(); | 
| 240 } | 242 } | 
| 241 | 243 | 
| 242 // config ---------------------------------------------------------------------- | 244 // config ---------------------------------------------------------------------- | 
| 243 | 245 | 
| 244 const char kConfig[] = "config"; | 246 const char kConfig[] = "config"; | 
| 245 const char kConfig_HelpShort[] = | 247 const char kConfig_HelpShort[] = | 
| 246     "config: Defines a configuration object."; | 248     "config: Defines a configuration object."; | 
| 247 const char kConfig_Help[] = | 249 const char kConfig_Help[] = | 
| 248     "config: Defines a configuration object.\n" | 250     R"(config: Defines a configuration object. | 
| 249     "\n" | 251 | 
| 250     "  Configuration objects can be applied to targets and specify sets of\n" | 252   Configuration objects can be applied to targets and specify sets of compiler | 
| 251     "  compiler flags, includes, defines, etc. They provide a way to\n" | 253   flags, includes, defines, etc. They provide a way to conveniently group sets | 
| 252     "  conveniently group sets of this configuration information.\n" | 254   of this configuration information. | 
| 253     "\n" | 255 | 
| 254     "  A config is referenced by its label just like a target.\n" | 256   A config is referenced by its label just like a target. | 
| 255     "\n" | 257 | 
| 256     "  The values in a config are additive only. If you want to remove a flag\n" | 258   The values in a config are additive only. If you want to remove a flag you | 
| 257     "  you need to remove the corresponding config that sets it. The final\n" | 259   need to remove the corresponding config that sets it. The final set of flags, | 
| 258     "  set of flags, defines, etc. for a target is generated in this order:\n" | 260   defines, etc. for a target is generated in this order: | 
| 259     "\n" | 261 | 
| 260     "   1. The values specified directly on the target (rather than using a\n" | 262    1. The values specified directly on the target (rather than using a config. | 
| 261     "      config.\n" | 263    2. The configs specified in the target's "configs" list, in order. | 
| 262     "   2. The configs specified in the target's \"configs\" list, in order.\n" | 264    3. Public_configs from a breadth-first traversal of the dependency tree in | 
| 263     "   3. Public_configs from a breadth-first traversal of the dependency\n" | 265       the order that the targets appear in "deps". | 
| 264     "      tree in the order that the targets appear in \"deps\".\n" | 266    4. All dependent configs from a breadth-first traversal of the dependency | 
| 265     "   4. All dependent configs from a breadth-first traversal of the\n" | 267       tree in the order that the targets appear in "deps". | 
| 266     "      dependency tree in the order that the targets appear in \"deps\".\n" | 268 | 
| 267     "\n" | 269 Variables valid in a config definition | 
| 268     "Variables valid in a config definition\n" | 270 )" | 
| 269     "\n" | 271 | 
| 270     CONFIG_VALUES_VARS_HELP | 272     CONFIG_VALUES_VARS_HELP | 
| 271     "  Nested configs: configs\n" | 273 | 
| 272     "\n" | 274 R"(  Nested configs: configs | 
| 273     "Variables on a target used to apply configs\n" | 275 | 
| 274     "\n" | 276 Variables on a target used to apply configs | 
| 275     "  all_dependent_configs, configs, public_configs\n" | 277 | 
| 276     "\n" | 278   all_dependent_configs, configs, public_configs | 
| 277     "Example\n" | 279 | 
| 278     "\n" | 280 Example | 
| 279     "  config(\"myconfig\") {\n" | 281 | 
| 280     "    includes = [ \"include/common\" ]\n" | 282   config("myconfig") { | 
| 281     "    defines = [ \"ENABLE_DOOM_MELON\" ]\n" | 283     includes = [ "include/common" ] | 
| 282     "  }\n" | 284     defines = [ "ENABLE_DOOM_MELON" ] | 
| 283     "\n" | 285   } | 
| 284     "  executable(\"mything\") {\n" | 286 | 
| 285     "    configs = [ \":myconfig\" ]\n" | 287   executable("mything") { | 
| 286     "  }\n"; | 288     configs = [ ":myconfig" ] | 
|  | 289   } | 
|  | 290 )"; | 
| 287 | 291 | 
| 288 Value RunConfig(const FunctionCallNode* function, | 292 Value RunConfig(const FunctionCallNode* function, | 
| 289                 const std::vector<Value>& args, | 293                 const std::vector<Value>& args, | 
| 290                 Scope* scope, | 294                 Scope* scope, | 
| 291                 Err* err) { | 295                 Err* err) { | 
| 292   NonNestableBlock non_nestable(scope, function, "config"); | 296   NonNestableBlock non_nestable(scope, function, "config"); | 
| 293   if (!non_nestable.Enter(err)) | 297   if (!non_nestable.Enter(err)) | 
| 294     return Value(); | 298     return Value(); | 
| 295 | 299 | 
| 296   if (!EnsureSingleStringArg(function, args, err) || | 300   if (!EnsureSingleStringArg(function, args, err) || | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 335 | 339 | 
| 336   return Value(); | 340   return Value(); | 
| 337 } | 341 } | 
| 338 | 342 | 
| 339 // declare_args ---------------------------------------------------------------- | 343 // declare_args ---------------------------------------------------------------- | 
| 340 | 344 | 
| 341 const char kDeclareArgs[] = "declare_args"; | 345 const char kDeclareArgs[] = "declare_args"; | 
| 342 const char kDeclareArgs_HelpShort[] = | 346 const char kDeclareArgs_HelpShort[] = | 
| 343     "declare_args: Declare build arguments."; | 347     "declare_args: Declare build arguments."; | 
| 344 const char kDeclareArgs_Help[] = | 348 const char kDeclareArgs_Help[] = | 
| 345     "declare_args: Declare build arguments.\n" | 349     R"(declare_args: Declare build arguments. | 
| 346     "\n" | 350 | 
| 347     "  Introduces the given arguments into the current scope. If they are\n" | 351   Introduces the given arguments into the current scope. If they are not | 
| 348     "  not specified on the command line or in a toolchain's arguments,\n" | 352   specified on the command line or in a toolchain's arguments, the default | 
| 349     "  the default values given in the declare_args block will be used.\n" | 353   values given in the declare_args block will be used. However, these defaults | 
| 350     "  However, these defaults will not override command-line values.\n" | 354   will not override command-line values. | 
| 351     "\n" | 355 | 
| 352     "  See also \"gn help buildargs\" for an overview.\n" | 356   See also "gn help buildargs" for an overview. | 
| 353     "\n" | 357 | 
| 354     "  The precise behavior of declare args is:\n" | 358   The precise behavior of declare args is: | 
| 355     "\n" | 359 | 
| 356     "   1. The declare_arg block executes. Any variables in the enclosing\n" | 360    1. The declare_arg block executes. Any variables in the enclosing scope are | 
| 357     "      scope are available for reading.\n" | 361       available for reading. | 
| 358     "\n" | 362 | 
| 359     "   2. At the end of executing the block, any variables set within that\n" | 363    2. At the end of executing the block, any variables set within that scope | 
| 360     "      scope are saved globally as build arguments, with their current\n" | 364       are saved globally as build arguments, with their current values being | 
| 361     "      values being saved as the \"default value\" for that argument.\n" | 365       saved as the "default value" for that argument. | 
| 362     "\n" | 366 | 
| 363     "   3. User-defined overrides are applied. Anything set in \"gn args\"\n" | 367    3. User-defined overrides are applied. Anything set in "gn args" now | 
| 364     "      now overrides any default values. The resulting set of variables\n" | 368       overrides any default values. The resulting set of variables is promoted | 
| 365     "      is promoted to be readable from the following code in the file.\n" | 369       to be readable from the following code in the file. | 
| 366     "\n" | 370 | 
| 367     "  This has some ramifications that may not be obvious:\n" | 371   This has some ramifications that may not be obvious: | 
| 368     "\n" | 372 | 
| 369     "    - You should not perform difficult work inside a declare_args block\n" | 373     - You should not perform difficult work inside a declare_args block since | 
| 370     "      since this only sets a default value that may be discarded. In\n" | 374       this only sets a default value that may be discarded. In particular, | 
| 371     "      particular, don't use the result of exec_script() to set the\n" | 375       don't use the result of exec_script() to set the default value. If you | 
| 372     "      default value. If you want to have a script-defined default, set\n" | 376       want to have a script-defined default, set some default "undefined" value | 
| 373     "      some default \"undefined\" value like [], \"\", or -1, and after\n" | 377       like [], "", or -1, and after the declare_args block, call exec_script if | 
| 374     "      the declare_args block, call exec_script if the value is unset by\n" | 378       the value is unset by the user. | 
| 375     "      the user.\n" | 379 | 
| 376     "\n" | 380     - Any code inside of the declare_args block will see the default values of | 
| 377     "    - Any code inside of the declare_args block will see the default\n" | 381       previous variables defined in the block rather than the user-overridden | 
| 378     "      values of previous variables defined in the block rather than\n" | 382       value. This can be surprising because you will be used to seeing the | 
| 379     "      the user-overridden value. This can be surprising because you will\n" | 383       overridden value. If you need to make the default value of one arg | 
| 380     "      be used to seeing the overridden value. If you need to make the\n" | 384       dependent on the possibly-overridden value of another, write two separate | 
| 381     "      default value of one arg dependent on the possibly-overridden\n" | 385       declare_args blocks: | 
| 382     "      value of another, write two separate declare_args blocks:\n" | 386 | 
| 383     "\n" | 387         declare_args() { | 
| 384     "        declare_args() {\n" | 388           enable_foo = true | 
| 385     "          enable_foo = true\n" | 389         } | 
| 386     "        }\n" | 390         declare_args() { | 
| 387     "        declare_args() {\n" | 391           # Bar defaults to same user-overridden state as foo. | 
| 388     "          # Bar defaults to same user-overridden state as foo.\n" | 392           enable_bar = enable_foo | 
| 389     "          enable_bar = enable_foo\n" | 393         } | 
| 390     "        }\n" | 394 | 
| 391     "\n" | 395 Example | 
| 392     "Example\n" | 396 | 
| 393     "\n" | 397   declare_args() { | 
| 394     "  declare_args() {\n" | 398     enable_teleporter = true | 
| 395     "    enable_teleporter = true\n" | 399     enable_doom_melon = false | 
| 396     "    enable_doom_melon = false\n" | 400   } | 
| 397     "  }\n" | 401 | 
| 398     "\n" | 402   If you want to override the (default disabled) Doom Melon: | 
| 399     "  If you want to override the (default disabled) Doom Melon:\n" | 403     gn --args="enable_doom_melon=true enable_teleporter=false" | 
| 400     "    gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n" | 404   This also sets the teleporter, but it's already defaulted to on so it will | 
| 401     "  This also sets the teleporter, but it's already defaulted to on so\n" | 405   have no effect. | 
| 402     "  it will have no effect.\n"; | 406 )"; | 
| 403 | 407 | 
| 404 Value RunDeclareArgs(Scope* scope, | 408 Value RunDeclareArgs(Scope* scope, | 
| 405                      const FunctionCallNode* function, | 409                      const FunctionCallNode* function, | 
| 406                      const std::vector<Value>& args, | 410                      const std::vector<Value>& args, | 
| 407                      BlockNode* block, | 411                      BlockNode* block, | 
| 408                      Err* err) { | 412                      Err* err) { | 
| 409   NonNestableBlock non_nestable(scope, function, "declare_args"); | 413   NonNestableBlock non_nestable(scope, function, "declare_args"); | 
| 410   if (!non_nestable.Enter(err)) | 414   if (!non_nestable.Enter(err)) | 
| 411     return Value(); | 415     return Value(); | 
| 412 | 416 | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 424       values, scope, err); | 428       values, scope, err); | 
| 425   return Value(); | 429   return Value(); | 
| 426 } | 430 } | 
| 427 | 431 | 
| 428 // defined --------------------------------------------------------------------- | 432 // defined --------------------------------------------------------------------- | 
| 429 | 433 | 
| 430 const char kDefined[] = "defined"; | 434 const char kDefined[] = "defined"; | 
| 431 const char kDefined_HelpShort[] = | 435 const char kDefined_HelpShort[] = | 
| 432     "defined: Returns whether an identifier is defined."; | 436     "defined: Returns whether an identifier is defined."; | 
| 433 const char kDefined_Help[] = | 437 const char kDefined_Help[] = | 
| 434     "defined: Returns whether an identifier is defined.\n" | 438     R"(defined: Returns whether an identifier is defined. | 
| 435     "\n" | 439 | 
| 436     "  Returns true if the given argument is defined. This is most useful in\n" | 440   Returns true if the given argument is defined. This is most useful in | 
| 437     "  templates to assert that the caller set things up properly.\n" | 441   templates to assert that the caller set things up properly. | 
| 438     "\n" | 442 | 
| 439     "  You can pass an identifier:\n" | 443   You can pass an identifier: | 
| 440     "    defined(foo)\n" | 444     defined(foo) | 
| 441     "  which will return true or false depending on whether foo is defined in\n" | 445   which will return true or false depending on whether foo is defined in the | 
| 442     "  the current scope.\n" | 446   current scope. | 
| 443     "\n" | 447 | 
| 444     "  You can also check a named scope:\n" | 448   You can also check a named scope: | 
| 445     "    defined(foo.bar)\n" | 449     defined(foo.bar) | 
| 446     "  which will return true or false depending on whether bar is defined in\n" | 450   which will return true or false depending on whether bar is defined in the | 
| 447     "  the named scope foo. It will throw an error if foo is not defined or\n" | 451   named scope foo. It will throw an error if foo is not defined or is not a | 
| 448     "  is not a scope.\n" | 452   scope. | 
| 449     "\n" | 453 | 
| 450     "Example:\n" | 454 Example | 
| 451     "\n" | 455 | 
| 452     "  template(\"mytemplate\") {\n" | 456   template("mytemplate") { | 
| 453     "    # To help users call this template properly...\n" | 457     # To help users call this template properly... | 
| 454     "    assert(defined(invoker.sources), \"Sources must be defined\")\n" | 458     assert(defined(invoker.sources), "Sources must be defined") | 
| 455     "\n" | 459 | 
| 456     "    # If we want to accept an optional \"values\" argument, we don't\n" | 460     # If we want to accept an optional "values" argument, we don't | 
| 457     "    # want to dereference something that may not be defined.\n" | 461     # want to dereference something that may not be defined. | 
| 458     "    if (defined(invoker.values)) {\n" | 462     if (defined(invoker.values)) { | 
| 459     "      values = invoker.values\n" | 463       values = invoker.values | 
| 460     "    } else {\n" | 464     } else { | 
| 461     "      values = \"some default value\"\n" | 465       values = "some default value" | 
| 462     "    }\n" | 466     } | 
| 463     "  }\n"; | 467   } | 
|  | 468 )"; | 
| 464 | 469 | 
| 465 Value RunDefined(Scope* scope, | 470 Value RunDefined(Scope* scope, | 
| 466                  const FunctionCallNode* function, | 471                  const FunctionCallNode* function, | 
| 467                  const ListNode* args_list, | 472                  const ListNode* args_list, | 
| 468                  Err* err) { | 473                  Err* err) { | 
| 469   const auto& args_vector = args_list->contents(); | 474   const auto& args_vector = args_list->contents(); | 
| 470   if (args_vector.size() != 1) { | 475   if (args_vector.size() != 1) { | 
| 471     *err = Err(function, "Wrong number of arguments to defined().", | 476     *err = Err(function, "Wrong number of arguments to defined().", | 
| 472                "Expecting exactly one."); | 477                "Expecting exactly one."); | 
| 473     return Value(); | 478     return Value(); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 506       "It should be of the form defined(foo) or defined(foo.bar)."); | 511       "It should be of the form defined(foo) or defined(foo.bar)."); | 
| 507   return Value(); | 512   return Value(); | 
| 508 } | 513 } | 
| 509 | 514 | 
| 510 // getenv ---------------------------------------------------------------------- | 515 // getenv ---------------------------------------------------------------------- | 
| 511 | 516 | 
| 512 const char kGetEnv[] = "getenv"; | 517 const char kGetEnv[] = "getenv"; | 
| 513 const char kGetEnv_HelpShort[] = | 518 const char kGetEnv_HelpShort[] = | 
| 514     "getenv: Get an environment variable."; | 519     "getenv: Get an environment variable."; | 
| 515 const char kGetEnv_Help[] = | 520 const char kGetEnv_Help[] = | 
| 516     "getenv: Get an environment variable.\n" | 521     R"(getenv: Get an environment variable. | 
| 517     "\n" | 522 | 
| 518     "  value = getenv(env_var_name)\n" | 523   value = getenv(env_var_name) | 
| 519     "\n" | 524 | 
| 520     "  Returns the value of the given enironment variable. If the value is\n" | 525   Returns the value of the given enironment variable. If the value is not | 
| 521     "  not found, it will try to look up the variable with the \"opposite\"\n" | 526   found, it will try to look up the variable with the "opposite" case (based on | 
| 522     "  case (based on the case of the first letter of the variable), but\n" | 527   the case of the first letter of the variable), but is otherwise | 
| 523     "  is otherwise case-sensitive.\n" | 528   case-sensitive. | 
| 524     "\n" | 529 | 
| 525     "  If the environment variable is not found, the empty string will be\n" | 530   If the environment variable is not found, the empty string will be returned. | 
| 526     "  returned. Note: it might be nice to extend this if we had the concept\n" | 531   Note: it might be nice to extend this if we had the concept of "none" in the | 
| 527     "  of \"none\" in the language to indicate lookup failure.\n" | 532   language to indicate lookup failure. | 
| 528     "\n" | 533 | 
| 529     "Example:\n" | 534 Example | 
| 530     "\n" | 535 | 
| 531     "  home_dir = getenv(\"HOME\")\n"; | 536   home_dir = getenv("HOME") | 
|  | 537 )"; | 
| 532 | 538 | 
| 533 Value RunGetEnv(Scope* scope, | 539 Value RunGetEnv(Scope* scope, | 
| 534                 const FunctionCallNode* function, | 540                 const FunctionCallNode* function, | 
| 535                 const std::vector<Value>& args, | 541                 const std::vector<Value>& args, | 
| 536                 Err* err) { | 542                 Err* err) { | 
| 537   if (!EnsureSingleStringArg(function, args, err)) | 543   if (!EnsureSingleStringArg(function, args, err)) | 
| 538     return Value(); | 544     return Value(); | 
| 539 | 545 | 
| 540   std::unique_ptr<base::Environment> env(base::Environment::Create()); | 546   std::unique_ptr<base::Environment> env(base::Environment::Create()); | 
| 541 | 547 | 
| 542   std::string result; | 548   std::string result; | 
| 543   if (!env->GetVar(args[0].string_value().c_str(), &result)) | 549   if (!env->GetVar(args[0].string_value().c_str(), &result)) | 
| 544     return Value(function, "");  // Not found, return empty string. | 550     return Value(function, "");  // Not found, return empty string. | 
| 545   return Value(function, result); | 551   return Value(function, result); | 
| 546 } | 552 } | 
| 547 | 553 | 
| 548 // import ---------------------------------------------------------------------- | 554 // import ---------------------------------------------------------------------- | 
| 549 | 555 | 
| 550 const char kImport[] = "import"; | 556 const char kImport[] = "import"; | 
| 551 const char kImport_HelpShort[] = | 557 const char kImport_HelpShort[] = | 
| 552     "import: Import a file into the current scope."; | 558     "import: Import a file into the current scope."; | 
| 553 const char kImport_Help[] = | 559 const char kImport_Help[] = | 
| 554     "import: Import a file into the current scope.\n" | 560     R"(import: Import a file into the current scope. | 
| 555     "\n" | 561 | 
| 556     "  The import command loads the rules and variables resulting from\n" | 562   The import command loads the rules and variables resulting from executing the | 
| 557     "  executing the given file into the current scope.\n" | 563   given file into the current scope. | 
| 558     "\n" | 564 | 
| 559     "  By convention, imported files are named with a .gni extension.\n" | 565   By convention, imported files are named with a .gni extension. | 
| 560     "\n" | 566 | 
| 561     "  An import is different than a C++ \"include\". The imported file is\n" | 567   An import is different than a C++ "include". The imported file is executed in | 
| 562     "  executed in a standalone environment from the caller of the import\n" | 568   a standalone environment from the caller of the import command. The results | 
| 563     "  command. The results of this execution are cached for other files that\n" | 569   of this execution are cached for other files that import the same .gni file. | 
| 564     "  import the same .gni file.\n" | 570 | 
| 565     "\n" | 571   Note that you can not import a BUILD.gn file that's otherwise used in the | 
| 566     "  Note that you can not import a BUILD.gn file that's otherwise used\n" | 572   build. Files must either be imported or implicitly loaded as a result of deps | 
| 567     "  in the build. Files must either be imported or implicitly loaded as\n" | 573   rules, but not both. | 
| 568     "  a result of deps rules, but not both.\n" | 574 | 
| 569     "\n" | 575   The imported file's scope will be merged with the scope at the point import | 
| 570     "  The imported file's scope will be merged with the scope at the point\n" | 576   was called. If there is a conflict (both the current scope and the imported | 
| 571     "  import was called. If there is a conflict (both the current scope and\n" | 577   file define some variable or rule with the same name but different value), a | 
| 572     "  the imported file define some variable or rule with the same name but\n" | 578   runtime error will be thrown. Therefore, it's good practice to minimize the | 
| 573     "  different value), a runtime error will be thrown. Therefore, it's good\n" | 579   stuff that an imported file defines. | 
| 574     "  practice to minimize the stuff that an imported file defines.\n" | 580 | 
| 575     "\n" | 581   Variables and templates beginning with an underscore '_' are considered | 
| 576     "  Variables and templates beginning with an underscore '_' are\n" | 582   private and will not be imported. Imported files can use such variables for | 
| 577     "  considered private and will not be imported. Imported files can use\n" | 583   internal computation without affecting other files. | 
| 578     "  such variables for internal computation without affecting other files.\n" | 584 | 
| 579     "\n" | 585 Examples | 
| 580     "Examples:\n" | 586 | 
| 581     "\n" | 587   import("//build/rules/idl_compilation_rule.gni") | 
| 582     "  import(\"//build/rules/idl_compilation_rule.gni\")\n" | 588 | 
| 583     "\n" | 589   # Looks in the current directory. | 
| 584     "  # Looks in the current directory.\n" | 590   import("my_vars.gni") | 
| 585     "  import(\"my_vars.gni\")\n"; | 591 )"; | 
| 586 | 592 | 
| 587 Value RunImport(Scope* scope, | 593 Value RunImport(Scope* scope, | 
| 588                 const FunctionCallNode* function, | 594                 const FunctionCallNode* function, | 
| 589                 const std::vector<Value>& args, | 595                 const std::vector<Value>& args, | 
| 590                 Err* err) { | 596                 Err* err) { | 
| 591   if (!EnsureSingleStringArg(function, args, err)) | 597   if (!EnsureSingleStringArg(function, args, err)) | 
| 592     return Value(); | 598     return Value(); | 
| 593 | 599 | 
| 594   const SourceDir& input_dir = scope->GetSourceDir(); | 600   const SourceDir& input_dir = scope->GetSourceDir(); | 
| 595   SourceFile import_file = | 601   SourceFile import_file = | 
| 596       input_dir.ResolveRelativeFile(args[0], err, | 602       input_dir.ResolveRelativeFile(args[0], err, | 
| 597           scope->settings()->build_settings()->root_path_utf8()); | 603           scope->settings()->build_settings()->root_path_utf8()); | 
| 598   if (!err->has_error()) { | 604   if (!err->has_error()) { | 
| 599     scope->settings()->import_manager().DoImport(import_file, function, | 605     scope->settings()->import_manager().DoImport(import_file, function, | 
| 600                                                  scope, err); | 606                                                  scope, err); | 
| 601   } | 607   } | 
| 602   return Value(); | 608   return Value(); | 
| 603 } | 609 } | 
| 604 | 610 | 
| 605 // set_sources_assignment_filter ----------------------------------------------- | 611 // set_sources_assignment_filter ----------------------------------------------- | 
| 606 | 612 | 
| 607 const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; | 613 const char kSetSourcesAssignmentFilter[] = "set_sources_assignment_filter"; | 
| 608 const char kSetSourcesAssignmentFilter_HelpShort[] = | 614 const char kSetSourcesAssignmentFilter_HelpShort[] = | 
| 609     "set_sources_assignment_filter: Set a pattern to filter source files."; | 615     "set_sources_assignment_filter: Set a pattern to filter source files."; | 
| 610 const char kSetSourcesAssignmentFilter_Help[] = | 616 const char kSetSourcesAssignmentFilter_Help[] = | 
| 611     "set_sources_assignment_filter: Set a pattern to filter source files.\n" | 617     R"(set_sources_assignment_filter: Set a pattern to filter source files. | 
| 612     "\n" | 618 | 
| 613     "  The sources assignment filter is a list of patterns that remove files\n" | 619   The sources assignment filter is a list of patterns that remove files from | 
| 614     "  from the list implicitly whenever the \"sources\" variable is\n" | 620   the list implicitly whenever the "sources" variable is assigned to. This will | 
| 615     "  assigned to. This will do nothing for non-lists.\n" | 621   do nothing for non-lists. | 
| 616     "\n" | 622 | 
| 617     "  This is intended to be used to globally filter out files with\n" | 623   This is intended to be used to globally filter out files with | 
| 618     "  platform-specific naming schemes when they don't apply, for example\n" | 624   platform-specific naming schemes when they don't apply, for example you may | 
| 619     "  you may want to filter out all \"*_win.cc\" files on non-Windows\n" | 625   want to filter out all "*_win.cc" files on non-Windows platforms. | 
| 620     "  platforms.\n" | 626 | 
| 621     "\n" | 627   Typically this will be called once in the master build config script to set | 
| 622     "  Typically this will be called once in the master build config script\n" | 628   up the filter for the current platform. Subsequent calls will overwrite the | 
| 623     "  to set up the filter for the current platform. Subsequent calls will\n" | 629   previous values. | 
| 624     "  overwrite the previous values.\n" | 630 | 
| 625     "\n" | 631   If you want to bypass the filter and add a file even if it might be filtered | 
| 626     "  If you want to bypass the filter and add a file even if it might\n" | 632   out, call set_sources_assignment_filter([]) to clear the list of filters. | 
| 627     "  be filtered out, call set_sources_assignment_filter([]) to clear the\n" | 633   This will apply until the current scope exits | 
| 628     "  list of filters. This will apply until the current scope exits\n" | 634 | 
| 629     "\n" | 635 How to use patterns | 
| 630     "How to use patterns\n" | 636 | 
| 631     "\n" | 637   File patterns are VERY limited regular expressions. They must match the | 
| 632     "  File patterns are VERY limited regular expressions. They must match\n" | 638   entire input string to be counted as a match. In regular expression parlance, | 
| 633     "  the entire input string to be counted as a match. In regular\n" | 639   there is an implicit "^...$" surrounding your input. If you want to match a | 
| 634     "  expression parlance, there is an implicit \"^...$\" surrounding your\n" | 640   substring, you need to use wildcards at the beginning and end. | 
| 635     "  input. If you want to match a substring, you need to use wildcards at\n" | 641 | 
| 636     "  the beginning and end.\n" | 642   There are only two special tokens understood by the pattern matcher. | 
| 637     "\n" | 643   Everything else is a literal. | 
| 638     "  There are only two special tokens understood by the pattern matcher.\n" | 644 | 
| 639     "  Everything else is a literal.\n" | 645    - "*" Matches zero or more of any character. It does not depend on the | 
| 640     "\n" | 646      preceding character (in regular expression parlance it is equivalent to | 
| 641     "   * Matches zero or more of any character. It does not depend on the\n" | 647      ".*"). | 
| 642     "     preceding character (in regular expression parlance it is\n" | 648 | 
| 643     "     equivalent to \".*\").\n" | 649    - "\b" Matches a path boundary. This will match the beginning or end of a | 
| 644     "\n" | 650      string, or a slash. | 
| 645     "  \\b Matches a path boundary. This will match the beginning or end of\n" | 651 | 
| 646     "     a string, or a slash.\n" | 652 Pattern examples | 
| 647     "\n" | 653 | 
| 648     "Pattern examples\n" | 654   "*asdf*" | 
| 649     "\n" | 655       Matches a string containing "asdf" anywhere. | 
| 650     "  \"*asdf*\"\n" | 656 | 
| 651     "      Matches a string containing \"asdf\" anywhere.\n" | 657   "asdf" | 
| 652     "\n" | 658       Matches only the exact string "asdf". | 
| 653     "  \"asdf\"\n" | 659 | 
| 654     "      Matches only the exact string \"asdf\".\n" | 660   "*.cc" | 
| 655     "\n" | 661       Matches strings ending in the literal ".cc". | 
| 656     "  \"*.cc\"\n" | 662 | 
| 657     "      Matches strings ending in the literal \".cc\".\n" | 663   "\bwin/*" | 
| 658     "\n" | 664       Matches "win/foo" and "foo/win/bar.cc" but not "iwin/foo". | 
| 659     "  \"\\bwin/*\"\n" | 665 | 
| 660     "      Matches \"win/foo\" and \"foo/win/bar.cc\" but not \"iwin/foo\".\n" | 666 Sources assignment example | 
| 661     "\n" | 667 | 
| 662     "Sources assignment example\n" | 668   # Filter out all _win files. | 
| 663     "\n" | 669   set_sources_assignment_filter([ "*_win.cc", "*_win.h" ]) | 
| 664     "  # Filter out all _win files.\n" | 670   sources = [ "a.cc", "b_win.cc" ] | 
| 665     "  set_sources_assignment_filter([ \"*_win.cc\", \"*_win.h\" ])\n" | 671   print(sources) | 
| 666     "  sources = [ \"a.cc\", \"b_win.cc\" ]\n" | 672   # Will print [ "a.cc" ]. b_win one was filtered out. | 
| 667     "  print(sources)\n" | 673 )"; | 
| 668     "  # Will print [ \"a.cc\" ]. b_win one was filtered out.\n"; |  | 
| 669 | 674 | 
| 670 Value RunSetSourcesAssignmentFilter(Scope* scope, | 675 Value RunSetSourcesAssignmentFilter(Scope* scope, | 
| 671                                     const FunctionCallNode* function, | 676                                     const FunctionCallNode* function, | 
| 672                                     const std::vector<Value>& args, | 677                                     const std::vector<Value>& args, | 
| 673                                     Err* err) { | 678                                     Err* err) { | 
| 674   if (args.size() != 1) { | 679   if (args.size() != 1) { | 
| 675     *err = Err(function, "set_sources_assignment_filter takes one argument."); | 680     *err = Err(function, "set_sources_assignment_filter takes one argument."); | 
| 676   } else { | 681   } else { | 
| 677     std::unique_ptr<PatternList> f(new PatternList); | 682     std::unique_ptr<PatternList> f(new PatternList); | 
| 678     f->SetFromValue(args[0], err); | 683     f->SetFromValue(args[0], err); | 
| 679     if (!err->has_error()) | 684     if (!err->has_error()) | 
| 680       scope->set_sources_assignment_filter(std::move(f)); | 685       scope->set_sources_assignment_filter(std::move(f)); | 
| 681   } | 686   } | 
| 682   return Value(); | 687   return Value(); | 
| 683 } | 688 } | 
| 684 | 689 | 
| 685 // pool ------------------------------------------------------------------------ | 690 // pool ------------------------------------------------------------------------ | 
| 686 | 691 | 
| 687 const char kPool[] = "pool"; | 692 const char kPool[] = "pool"; | 
| 688 const char kPool_HelpShort[] = | 693 const char kPool_HelpShort[] = | 
| 689     "pool: Defines a pool object."; | 694     "pool: Defines a pool object."; | 
| 690 const char kPool_Help[] = | 695 const char kPool_Help[] = | 
| 691     "pool: Defines a pool object.\n" | 696     R"*(pool: Defines a pool object. | 
| 692     "\n" | 697 | 
| 693     "  Pool objects can be applied to a tool to limit the parallelism of the\n" | 698   Pool objects can be applied to a tool to limit the parallelism of the | 
| 694     "  build. This object has a single property \"depth\" corresponding to\n" | 699   build. This object has a single property "depth" corresponding to | 
| 695     "  the number of tasks that may run simultaneously.\n" | 700   the number of tasks that may run simultaneously. | 
| 696     "\n" | 701 | 
| 697     "  As the file containing the pool definition may be executed in the\n" | 702   As the file containing the pool definition may be executed in the | 
| 698     "  context of more than one toolchain it is recommended to specify an\n" | 703   context of more than one toolchain it is recommended to specify an | 
| 699     "  explicit toolchain when defining and referencing a pool.\n" | 704   explicit toolchain when defining and referencing a pool. | 
| 700     "\n" | 705 | 
| 701     "  A pool is referenced by its label just like a target.\n" | 706   A pool is referenced by its label just like a target. | 
| 702     "\n" | 707 | 
| 703     "Variables\n" | 708 Variables | 
| 704     "\n" | 709 | 
| 705     "  depth*\n" | 710   depth* | 
| 706     "  * = required\n" | 711   * = required | 
| 707     "\n" | 712 | 
| 708     "Example\n" | 713 Example | 
| 709     "\n" | 714 | 
| 710     "  if (current_toolchain == default_toolchain) {\n" | 715   if (current_toolchain == default_toolchain) { | 
| 711     "    pool(\"link_pool\") {\n" | 716     pool("link_pool") { | 
| 712     "      depth = 1\n" | 717       depth = 1 | 
| 713     "    }\n" | 718     } | 
| 714     "  }\n" | 719   } | 
| 715     "\n" | 720 | 
| 716     "  toolchain(\"toolchain\") {\n" | 721   toolchain("toolchain") { | 
| 717     "    tool(\"link\") {\n" | 722     tool("link") { | 
| 718     "      command = \"...\"\n" | 723       command = "..." | 
| 719     "      pool = \":link_pool($default_toolchain)\")\n" | 724       pool = ":link_pool($default_toolchain)") | 
| 720     "    }\n" | 725     } | 
| 721     "  }\n"; | 726   } | 
|  | 727 )*"; | 
| 722 | 728 | 
| 723 const char kDepth[] = "depth"; | 729 const char kDepth[] = "depth"; | 
| 724 | 730 | 
| 725 Value RunPool(const FunctionCallNode* function, | 731 Value RunPool(const FunctionCallNode* function, | 
| 726               const std::vector<Value>& args, | 732               const std::vector<Value>& args, | 
| 727               Scope* scope, | 733               Scope* scope, | 
| 728               Err* err) { | 734               Err* err) { | 
| 729   NonNestableBlock non_nestable(scope, function, "pool"); | 735   NonNestableBlock non_nestable(scope, function, "pool"); | 
| 730   if (!non_nestable.Enter(err)) | 736   if (!non_nestable.Enter(err)) | 
| 731     return Value(); | 737     return Value(); | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 769 | 775 | 
| 770   return Value(); | 776   return Value(); | 
| 771 } | 777 } | 
| 772 | 778 | 
| 773 // print ----------------------------------------------------------------------- | 779 // print ----------------------------------------------------------------------- | 
| 774 | 780 | 
| 775 const char kPrint[] = "print"; | 781 const char kPrint[] = "print"; | 
| 776 const char kPrint_HelpShort[] = | 782 const char kPrint_HelpShort[] = | 
| 777     "print: Prints to the console."; | 783     "print: Prints to the console."; | 
| 778 const char kPrint_Help[] = | 784 const char kPrint_Help[] = | 
| 779     "print: Prints to the console.\n" | 785     R"(print: Prints to the console. | 
| 780     "\n" | 786 | 
| 781     "  Prints all arguments to the console separated by spaces. A newline is\n" | 787   Prints all arguments to the console separated by spaces. A newline is | 
| 782     "  automatically appended to the end.\n" | 788   automatically appended to the end. | 
| 783     "\n" | 789 | 
| 784     "  This function is intended for debugging. Note that build files are run\n" | 790   This function is intended for debugging. Note that build files are run in | 
| 785     "  in parallel so you may get interleaved prints. A buildfile may also\n" | 791   parallel so you may get interleaved prints. A buildfile may also be executed | 
| 786     "  be executed more than once in parallel in the context of different\n" | 792   more than once in parallel in the context of different toolchains so the | 
| 787     "  toolchains so the prints from one file may be duplicated or\n" | 793   prints from one file may be duplicated or | 
| 788     "  interleaved with itself.\n" | 794   interleaved with itself. | 
| 789     "\n" | 795 | 
| 790     "Examples:\n" | 796 Examples | 
| 791     "  print(\"Hello world\")\n" | 797 | 
| 792     "\n" | 798   print("Hello world") | 
| 793     "  print(sources, deps)\n"; | 799 | 
|  | 800   print(sources, deps) | 
|  | 801 )"; | 
| 794 | 802 | 
| 795 Value RunPrint(Scope* scope, | 803 Value RunPrint(Scope* scope, | 
| 796                const FunctionCallNode* function, | 804                const FunctionCallNode* function, | 
| 797                const std::vector<Value>& args, | 805                const std::vector<Value>& args, | 
| 798                Err* err) { | 806                Err* err) { | 
| 799   std::string output; | 807   std::string output; | 
| 800   for (size_t i = 0; i < args.size(); i++) { | 808   for (size_t i = 0; i < args.size(); i++) { | 
| 801     if (i != 0) | 809     if (i != 0) | 
| 802       output.push_back(' '); | 810       output.push_back(' '); | 
| 803     output.append(args[i].ToString(false)); | 811     output.append(args[i].ToString(false)); | 
| 804   } | 812   } | 
| 805   output.push_back('\n'); | 813   output.push_back('\n'); | 
| 806 | 814 | 
| 807   const BuildSettings::PrintCallback& cb = | 815   const BuildSettings::PrintCallback& cb = | 
| 808       scope->settings()->build_settings()->print_callback(); | 816       scope->settings()->build_settings()->print_callback(); | 
| 809   if (cb.is_null()) | 817   if (cb.is_null()) | 
| 810     printf("%s", output.c_str()); | 818     printf("%s", output.c_str()); | 
| 811   else | 819   else | 
| 812     cb.Run(output); | 820     cb.Run(output); | 
| 813 | 821 | 
| 814   return Value(); | 822   return Value(); | 
| 815 } | 823 } | 
| 816 | 824 | 
| 817 // split_list ------------------------------------------------------------------ | 825 // split_list ------------------------------------------------------------------ | 
| 818 | 826 | 
| 819 const char kSplitList[] = "split_list"; | 827 const char kSplitList[] = "split_list"; | 
| 820 const char kSplitList_HelpShort[] = | 828 const char kSplitList_HelpShort[] = | 
| 821     "split_list: Splits a list into N different sub-lists."; | 829     "split_list: Splits a list into N different sub-lists."; | 
| 822 const char kSplitList_Help[] = | 830 const char kSplitList_Help[] = | 
| 823     "split_list: Splits a list into N different sub-lists.\n" | 831     R"(split_list: Splits a list into N different sub-lists. | 
| 824     "\n" | 832 | 
| 825     "  result = split_list(input, n)\n" | 833   result = split_list(input, n) | 
| 826     "\n" | 834 | 
| 827     "  Given a list and a number N, splits the list into N sub-lists of\n" | 835   Given a list and a number N, splits the list into N sub-lists of | 
| 828     "  approximately equal size. The return value is a list of the sub-lists.\n" | 836   approximately equal size. The return value is a list of the sub-lists. The | 
| 829     "  The result will always be a list of size N. If N is greater than the\n" | 837   result will always be a list of size N. If N is greater than the number of | 
| 830     "  number of elements in the input, it will be padded with empty lists.\n" | 838   elements in the input, it will be padded with empty lists. | 
| 831     "\n" | 839 | 
| 832     "  The expected use is to divide source files into smaller uniform\n" | 840   The expected use is to divide source files into smaller uniform chunks. | 
| 833     "  chunks.\n" | 841 | 
| 834     "\n" | 842 Example | 
| 835     "Example\n" | 843 | 
| 836     "\n" | 844   The code: | 
| 837     "  The code:\n" | 845     mylist = [1, 2, 3, 4, 5, 6] | 
| 838     "    mylist = [1, 2, 3, 4, 5, 6]\n" | 846     print(split_list(mylist, 3)) | 
| 839     "    print(split_list(mylist, 3))\n" | 847 | 
| 840     "\n" | 848   Will print: | 
| 841     "  Will print:\n" | 849     [[1, 2], [3, 4], [5, 6] | 
| 842     "    [[1, 2], [3, 4], [5, 6]\n"; | 850 )"; | 
| 843 Value RunSplitList(Scope* scope, | 851 Value RunSplitList(Scope* scope, | 
| 844                    const FunctionCallNode* function, | 852                    const FunctionCallNode* function, | 
| 845                    const ListNode* args_list, | 853                    const ListNode* args_list, | 
| 846                    Err* err) { | 854                    Err* err) { | 
| 847   const auto& args_vector = args_list->contents(); | 855   const auto& args_vector = args_list->contents(); | 
| 848   if (args_vector.size() != 2) { | 856   if (args_vector.size() != 2) { | 
| 849     *err = Err(function, "Wrong number of arguments to split_list().", | 857     *err = Err(function, "Wrong number of arguments to split_list().", | 
| 850                "Expecting exactly two."); | 858                "Expecting exactly two."); | 
| 851     return Value(); | 859     return Value(); | 
| 852   } | 860   } | 
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1099   } | 1107   } | 
| 1100 | 1108 | 
| 1101   // Otherwise it's a no-block function. | 1109   // Otherwise it's a no-block function. | 
| 1102   if (!VerifyNoBlockForFunctionCall(function, block, err)) | 1110   if (!VerifyNoBlockForFunctionCall(function, block, err)) | 
| 1103     return Value(); | 1111     return Value(); | 
| 1104   return found_function->second.no_block_runner(scope, function, | 1112   return found_function->second.no_block_runner(scope, function, | 
| 1105                                                 args.list_value(), err); | 1113                                                 args.list_value(), err); | 
| 1106 } | 1114 } | 
| 1107 | 1115 | 
| 1108 }  // namespace functions | 1116 }  // namespace functions | 
| OLD | NEW | 
|---|