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 |