| 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 |