1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <algorithm> 6 #include <limits> 7 8 #include "tools/gn/err.h" 9 #include "tools/gn/functions.h" 10 #include "tools/gn/parse_tree.h" 11 #include "tools/gn/scheduler.h" 12 #include "tools/gn/scope.h" 13 #include "tools/gn/settings.h" 14 #include "tools/gn/tool.h" 15 #include "tools/gn/toolchain.h" 16 #include "tools/gn/value_extractors.h" 17 #include "tools/gn/variables.h" 18 19 namespace functions { 20 21 namespace { 22 23 // This is jsut a unique value to take the address of to use as the key for 24 // the toolchain property on a scope. 25 const int kToolchainPropertyKey = 0; 26 27 bool ReadBool(Scope* scope, 28 const char* var, 29 Tool* tool, 30 void (Tool::*set)(bool), 31 Err* err) { 32 const Value* v = scope->GetValue(var, true); 33 if (!v) 34 return true; // Not present is fine. 35 if (!v->VerifyTypeIs(Value::BOOLEAN, err)) 36 return false; 37 38 (tool->*set)(v->boolean_value()); 39 return true; 40 } 41 42 // Reads the given string from the scope (if present) and puts the result into 43 // dest. If the value is not a string, sets the error and returns false. 44 bool ReadString(Scope* scope, 45 const char* var, 46 Tool* tool, 47 void (Tool::*set)(const std::string&), 48 Err* err) { 49 const Value* v = scope->GetValue(var, true); 50 if (!v) 51 return true; // Not present is fine. 52 if (!v->VerifyTypeIs(Value::STRING, err)) 53 return false; 54 55 (tool->*set)(v->string_value()); 56 return true; 57 } 58 59 // Calls the given validate function on each type in the list. On failure, 60 // sets the error, blame the value, and return false. 61 bool ValidateSubstitutionList(const std::vector<SubstitutionType>& list, 62 bool (*validate)(SubstitutionType), 63 const Value* origin, 64 Err* err) { 65 for (size_t i = 0; i < list.size(); i++) { 66 SubstitutionType cur_type = list[i]; 67 if (!validate(cur_type)) { 68 *err = Err(*origin, "Pattern not valid here.", 69 "You used the pattern " + std::string(kSubstitutionNames[cur_type]) + 70 " which is not valid\nfor this variable."); 71 return false; 72 } 73 } 74 return true; 75 } 76 77 bool ReadPattern(Scope* scope, 78 const char* name, 79 bool (*validate)(SubstitutionType), 80 Tool* tool, 81 void (Tool::*set)(const SubstitutionPattern&), 82 Err* err) { 83 const Value* value = scope->GetValue(name, true); 84 if (!value) 85 return true; // Not present is fine. 86 if (!value->VerifyTypeIs(Value::STRING, err)) 87 return false; 88 89 SubstitutionPattern pattern; 90 if (!pattern.Parse(*value, err)) 91 return false; 92 if (!ValidateSubstitutionList(pattern.required_types(), validate, value, err)) 93 return false; 94 95 (tool->*set)(pattern); 96 return true; 97 } 98 99 bool ReadOutputExtension(Scope* scope, Tool* tool, Err* err) { 100 const Value* value = scope->GetValue("default_output_extension", true); 101 if (!value) 102 return true; // Not present is fine. 103 if (!value->VerifyTypeIs(Value::STRING, err)) 104 return false; 105 106 if (value->string_value().empty()) 107 return true; // Accept empty string. 108 109 if (value->string_value()[0] != '.') { 110 *err = Err(*value, "default_output_extension must begin with a '.'"); 111 return false; 112 } 113 114 tool->set_default_output_extension(value->string_value()); 115 return true; 116 } 117 118 bool ReadDepsFormat(Scope* scope, Tool* tool, Err* err) { 119 const Value* value = scope->GetValue("depsformat", true); 120 if (!value) 121 return true; // Not present is fine. 122 if (!value->VerifyTypeIs(Value::STRING, err)) 123 return false; 124 125 if (value->string_value() == "gcc") { 126 tool->set_depsformat(Tool::DEPS_GCC); 127 } else if (value->string_value() == "msvc") { 128 tool->set_depsformat(Tool::DEPS_MSVC); 129 } else { 130 *err = Err(*value, "Deps format must be \"gcc\" or \"msvc\"."); 131 return false; 132 } 133 return true; 134 } 135 136 bool ReadOutputs(Scope* scope, 137 const FunctionCallNode* tool_function, 138 bool (*validate)(SubstitutionType), 139 Tool* tool, 140 Err* err) { 141 const Value* value = scope->GetValue("outputs", true); 142 if (!value) { 143 *err = Err(tool_function, "\"outputs\" must be specified for this tool."); 144 return false; 145 } 146 147 SubstitutionList list; 148 if (!list.Parse(*value, err)) 149 return false; 150 151 // Validate the right kinds of patterns are used. 152 if (!ValidateSubstitutionList(list.required_types(), validate, value, err)) 153 return false; 154 155 // There should always be at least one output. 156 if (list.list().empty()) { 157 *err = Err(*value, "Outputs list is empty.", "I need some outputs."); 158 return false; 159 } 160 161 tool->set_outputs(list); 162 return true; 163 } 164 165 bool IsCompilerTool(Toolchain::ToolType type) { 166 return type == Toolchain::TYPE_CC || 167 type == Toolchain::TYPE_CXX || 168 type == Toolchain::TYPE_OBJC || 169 type == Toolchain::TYPE_OBJCXX || 170 type == Toolchain::TYPE_RC || 171 type == Toolchain::TYPE_ASM; 172 } 173 174 bool IsLinkerTool(Toolchain::ToolType type) { 175 return type == Toolchain::TYPE_ALINK || 176 type == Toolchain::TYPE_SOLINK || 177 type == Toolchain::TYPE_LINK; 178 } 179 180 bool IsPatternInOutputList(const SubstitutionList& output_list, 181 const SubstitutionPattern& pattern) { 182 for (size_t output_i = 0; output_i < output_list.list().size(); output_i++) { 183 const SubstitutionPattern& cur = output_list.list()[output_i]; 184 if (pattern.ranges().size() == cur.ranges().size() && 185 std::equal(pattern.ranges().begin(), pattern.ranges().end(), 186 cur.ranges().begin())) 187 return true; 188 } 189 return false; 190 } 191 192 } // namespace 193 194 // toolchain ------------------------------------------------------------------- 195 196 const char kToolchain[] = "toolchain"; 197 const char kToolchain_HelpShort[] = 198 "toolchain: Defines a toolchain."; 199 const char kToolchain_Help[] = 200 "toolchain: Defines a toolchain.\n" 201 "\n" 202 " A toolchain is a set of commands and build flags used to compile the\n" 203 " source code. You can have more than one toolchain in use at once in\n" 204 " a build.\n" 205 "\n" 206 "Functions and variables\n" 207 "\n" 208 " tool()\n" 209 " The tool() function call specifies the commands commands to run for\n" 210 " a given step. See \"gn help tool\".\n" 211 "\n" 212 " toolchain_args()\n" 213 " List of arguments to pass to the toolchain when invoking this\n" 214 " toolchain. This applies only to non-default toolchains. See\n" 215 " \"gn help toolchain_args\" for more.\n" 216 "\n" 217 " deps\n" 218 " Dependencies of this toolchain. These dependencies will be resolved\n" 219 " before any target in the toolchain is compiled. To avoid circular\n" 220 " dependencies these must be targets defined in another toolchain.\n" 221 "\n" 222 " This is expressed as a list of targets, and generally these targets\n" 223 " will always specify a toolchain:\n" 224 " deps = [ \"//foo/bar:baz(//build/toolchain:bootstrap)\" ]\n" 225 "\n" 226 " This concept is somewhat inefficient to express in Ninja (it\n" 227 " requires a lot of duplicate of rules) so should only be used when\n" 228 " absolutely necessary.\n" 229 "\n" 230 " concurrent_links\n" 231 " In integer expressing the number of links that Ninja will perform in\n" 232 " parallel. GN will create a pool for shared library and executable\n" 233 " link steps with this many processes. Since linking is memory- and\n" 234 " I/O-intensive, projects with many large targets may want to limit\n" 235 " the number of parallel steps to avoid overloading the computer.\n" 236 " Since creating static libraries is generally not as intensive\n" 237 " there is no limit to \"alink\" steps.\n" 238 "\n" 239 " Defaults to 0 which Ninja interprets as \"no limit\".\n" 240 "\n" 241 " The value used will be the one from the default toolchain of the\n" 242 " current build.\n" 243 "\n" 244 "Invoking targets in toolchains:\n" 245 "\n" 246 " By default, when a target depends on another, there is an implicit\n" 247 " toolchain label that is inherited, so the dependee has the same one\n" 248 " as the dependent.\n" 249 "\n" 250 " You can override this and refer to any other toolchain by explicitly\n" 251 " labeling the toolchain to use. For example:\n" 252 " data_deps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" 253 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" 254 " identifies the toolchain declaration for compiling the sources.\n" 255 "\n" 256 " To load a file in an alternate toolchain, GN does the following:\n" 257 "\n" 258 " 1. Loads the file with the toolchain definition in it (as determined\n" 259 " by the toolchain label).\n" 260 " 2. Re-runs the master build configuration file, applying the\n" 261 " arguments specified by the toolchain_args section of the toolchain\n" 262 " definition (see \"gn help toolchain_args\").\n" 263 " 3. Loads the destination build file in the context of the\n" 264 " configuration file in the previous step.\n" 265 "\n" 266 "Example:\n" 267 " toolchain(\"plugin_toolchain\") {\n" 268 " concurrent_links = 8\n" 269 "\n" 270 " tool(\"cc\") {\n" 271 " command = \"gcc $in\"\n" 272 " ...\n" 273 " }\n" 274 "\n" 275 " toolchain_args() {\n" 276 " is_plugin = true\n" 277 " is_32bit = true\n" 278 " is_64bit = false\n" 279 " }\n" 280 " }\n"; 281 282 Value RunToolchain(Scope* scope, 283 const FunctionCallNode* function, 284 const std::vector<Value>& args, 285 BlockNode* block, 286 Err* err) { 287 if (!EnsureNotProcessingImport(function, scope, err) || 288 !EnsureNotProcessingBuildConfig(function, scope, err)) 289 return Value(); 290 291 // Note that we don't want to use MakeLabelForScope since that will include 292 // the toolchain name in the label, and toolchain labels don't themselves 293 // have toolchain names. 294 const SourceDir& input_dir = scope->GetSourceDir(); 295 Label label(input_dir, args[0].string_value()); 296 if (g_scheduler->verbose_logging()) 297 g_scheduler->Log("Definining toolchain", label.GetUserVisibleName(false)); 298 299 // This object will actually be copied into the one owned by the toolchain 300 // manager, but that has to be done in the lock. 301 scoped_ptr<Toolchain> toolchain(new Toolchain(scope->settings(), label)); 302 toolchain->set_defined_from(function); 303 toolchain->visibility().SetPublic(); 304 305 Scope block_scope(scope); 306 block_scope.SetProperty(&kToolchainPropertyKey, toolchain.get()); 307 block->ExecuteBlockInScope(&block_scope, err); 308 block_scope.SetProperty(&kToolchainPropertyKey, NULL); 309 if (err->has_error()) 310 return Value(); 311 312 // Read deps (if any). 313 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); 314 if (deps_value) { 315 ExtractListOfLabels( 316 *deps_value, block_scope.GetSourceDir(), 317 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); 318 if (err->has_error()) 319 return Value(); 320 } 321 322 // Read concurrent_links (if any). 323 const Value* concurrent_links_value = 324 block_scope.GetValue("concurrent_links", true); 325 if (concurrent_links_value) { 326 if (!concurrent_links_value->VerifyTypeIs(Value::INTEGER, err)) 327 return Value(); 328 if (concurrent_links_value->int_value() < 0 || 329 concurrent_links_value->int_value() > std::numeric_limits<int>::max()) { 330 *err = Err(*concurrent_links_value, "Value out of range."); 331 return Value(); 332 } 333 toolchain->set_concurrent_links( 334 static_cast<int>(concurrent_links_value->int_value())); 335 } 336 337 if (!block_scope.CheckForUnusedVars(err)) 338 return Value(); 339 340 // Save this toolchain. 341 toolchain->ToolchainSetupComplete(); 342 Scope::ItemVector* collector = scope->GetItemCollector(); 343 if (!collector) { 344 *err = Err(function, "Can't define a toolchain in this context."); 345 return Value(); 346 } 347 collector->push_back(new scoped_ptr<Item>(toolchain.PassAs<Item>())); 348 return Value(); 349 } 350 351 // tool ------------------------------------------------------------------------ 352 353 const char kTool[] = "tool"; 354 const char kTool_HelpShort[] = 355 "tool: Specify arguments to a toolchain tool."; 356 const char kTool_Help[] = 357 "tool: Specify arguments to a toolchain tool.\n" 358 "\n" 359 "Usage:\n" 360 "\n" 361 " tool(<tool type>) {\n" 362 " <tool variables...>\n" 363 " }\n" 364 "\n" 365 "Tool types\n" 366 "\n" 367 " Compiler tools:\n" 368 " \"cc\": C compiler\n" 369 " \"cxx\": C++ compiler\n" 370 " \"objc\": Objective C compiler\n" 371 " \"objcxx\": Objective C++ compiler\n" 372 " \"rc\": Resource compiler (Windows .rc files)\n" 373 " \"asm\": Assembler\n" 374 "\n" 375 " Linker tools:\n" 376 " \"alink\": Linker for static libraries (archives)\n" 377 " \"solink\": Linker for shared libraries\n" 378 " \"link\": Linker for executables\n" 379 "\n" 380 " Other tools:\n" 381 " \"stamp\": Tool for creating stamp files\n" 382 " \"copy\": Tool to copy files.\n" 383 "\n" 384 "Tool variables\n" 385 "\n" 386 " command [string with substitutions]\n" 387 " Valid for: all tools (required)\n" 388 "\n" 389 " The command to run.\n" 390 "\n" 391 " default_output_extension [string]\n" 392 " Valid for: linker tools\n" 393 "\n" 394 " Extension for the main output of a linkable tool. It includes\n" 395 " the leading dot. This will be the default value for the\n" 396 " {{output_extension}} expansion (discussed below) but will be\n" 397 " overridden by by the \"output extension\" variable in a target,\n" 398 " if one is specified. Empty string means no extension.\n" 399 "\n" 400 " GN doesn't actually do anything with this extension other than\n" 401 " pass it along, potentially with target-specific overrides. One\n" 402 " would typically use the {{output_extension}} value in the\n" 403 " \"outputs\" to read this value.\n" 404 "\n" 405 " Example: default_output_extension = \".exe\"\n" 406 "\n" 407 " depfile [string]\n" 408 " Valid for: compiler tools (optional)\n" 409 "\n" 410 " If the tool can write \".d\" files, this specifies the name of\n" 411 " the resulting file. These files are used to list header file\n" 412 " dependencies (or other implicit input dependencies) that are\n" 413 " discovered at build time. See also \"depsformat\".\n" 414 "\n" 415 " Example: depfile = \"{{output}}.d\"\n" 416 "\n" 417 " depsformat [string]\n" 418 " Valid for: compiler tools (when depfile is specified)\n" 419 "\n" 420 " Format for the deps outputs. This is either \"gcc\" or \"msvc\".\n" 421 " See the ninja documentation for \"deps\" for more information.\n" 422 "\n" 423 " Example: depsformat = \"gcc\"\n" 424 "\n" 425 " description [string with substitutions, optional]\n" 426 " Valid for: all tools\n" 427 "\n" 428 " What to print when the command is run.\n" 429 "\n" 430 " Example: description = \"Compiling {{source}}\"\n" 431 "\n" 432 " lib_switch [string, optional, link tools only]\n" 433 " lib_dir_switch [string, optional, link tools only]\n" 434 " Valid for: Linker tools except \"alink\"\n" 435 "\n" 436 " These strings will be prepended to the libraries and library\n" 437 " search directories, respectively, because linkers differ on how\n" 438 " specify them. If you specified:\n" 439 " lib_switch = \"-l\"\n" 440 " lib_dir_switch = \"-L\"\n" 441 " then the \"{{libs}}\" expansion for [ \"freetype\", \"expat\"]\n" 442 " would be \"-lfreetype -lexpat\".\n" 443 "\n" 444 " outputs [list of strings with substitutions]\n" 445 " Valid for: Linker and compiler tools (required)\n" 446 "\n" 447 " An array of names for the output files the tool produces. These\n" 448 " are relative to the build output directory. There must always be\n" 449 " at least one output file. There can be more than one output (a\n" 450 " linker might produce a library and an import library, for\n" 451 " example).\n" 452 "\n" 453 " This array just declares to GN what files the tool will\n" 454 " produce. It is your responsibility to specify the tool command\n" 455 " that actually produces these files.\n" 456 "\n" 457 " If you specify more than one output for shared library links,\n" 458 " you should consider setting link_output and depend_output.\n" 459 " Otherwise, the first entry in the outputs list should always be\n" 460 " the main output which will be linked to.\n" 461 "\n" 462 " Example for a compiler tool that produces .obj files:\n" 463 " outputs = [\n" 464 " \"{{source_out_dir}}/{{source_name_part}}.obj\"\n" 465 " ]\n" 466 "\n" 467 " Example for a linker tool that produces a .dll and a .lib. The\n" 468 " use of {{output_extension}} rather than hardcoding \".dll\"\n" 469 " allows the extension of the library to be overridden on a\n" 470 " target-by-target basis, but in this example, it always\n" 471 " produces a \".lib\" import library:\n" 472 " outputs = [\n" 473 " \"{{root_out_dir}}/{{target_output_name}}" 474 "{{output_extension}}\",\n" 475 " \"{{root_out_dir}}/{{target_output_name}}.lib\",\n" 476 " ]\n" 477 "\n" 478 " link_output [string with substitutions]\n" 479 " depend_output [string with substitutions]\n" 480 " Valid for: \"solink\" only (optional)\n" 481 "\n" 482 " These two files specify whch of the outputs from the solink\n" 483 " tool should be used for linking and dependency tracking. These\n" 484 " should match entries in the \"outputs\". If unspecified, the\n" 485 " first item in the \"outputs\" array will be used for both. See\n" 486 " \"Separate linking and dependencies for shared libraries\"\n" 487 " below for more.\n" 488 "\n" 489 " On Windows, where the tools produce a .dll shared library and\n" 490 " a .lib import library, you will want both of these to be the\n" 491 " import library. On Linux, if you're not doing the separate\n" 492 " linking/dependency optimization, both of these should be the\n" 493 " .so output.\n" 494 "\n" 495 " output_prefix [string]\n" 496 " Valid for: Linker tools (optional)\n" 497 "\n" 498 " Prefix to use for the output name. Defaults to empty. This\n" 499 " prefix will be prepended to the name of the target (or the\n" 500 " output_name if one is manually specified for it) if the prefix\n" 501 " is not already there. The result will show up in the\n" 502 " {{output_name}} substitution pattern.\n" 503 "\n" 504 " This is typically used to prepend \"lib\" to libraries on\n" 505 " Posix systems:\n" 506 " output_prefix = \"lib\"\n" 507 "\n" 508 " restat [boolean]\n" 509 " Valid for: all tools (optional, defaults to false)\n" 510 "\n" 511 " Requests that Ninja check the file timestamp after this tool has\n" 512 " run to determine if anything changed. Set this if your tool has\n" 513 " the ability to skip writing output if the output file has not\n" 514 " changed.\n" 515 "\n" 516 " Normally, Ninja will assume that when a tool runs the output\n" 517 " be new and downstream dependents must be rebuild. When this is\n" 518 " set to trye, Ninja can skip rebuilding downstream dependents for\n" 519 " input changes that don't actually affect the output.\n" 520 "\n" 521 " Example:\n" 522 " restat = true\n" 523 "\n" 524 " rspfile [string with substitutions]\n" 525 " Valid for: all tools (optional)\n" 526 "\n" 527 " Name of the response file. If empty, no response file will be\n" 528 " used. See \"rspfile_content\".\n" 529 "\n" 530 " rspfile_content [string with substitutions]\n" 531 " Valid for: all tools (required when \"rspfile\" is specified)\n" 532 "\n" 533 " The contents to be written to the response file. This may\n" 534 " include all or part of the command to send to the tool which\n" 535 " allows you to get around OS command-line length limits.\n" 536 "\n" 537 " This example adds the inputs and libraries to a response file,\n" 538 " but passes the linker flags directly on the command line:\n" 539 " tool(\"link\") {\n" 540 " command = \"link -o {{output}} {{ldflags}} @{{output}}.rsp\"\n" 541 " rspfile = \"{{output}}.rsp\"\n" 542 " rspfile_content = \"{{inputs}} {{solibs}} {{libs}}\"\n" 543 " }\n" 544 "\n" 545 "Expansions for tool variables" 546 "\n" 547 " All paths are relative to the root build directory, which is the\n" 548 " current directory for running all tools. These expansions are\n" 549 " available to all tools:\n" 550 "\n" 551 " {{label}}\n" 552 " The label of the current target. This is typically used in the\n" 553 " \"description\" field for link tools. The toolchain will be\n" 554 " omitted from the label for targets in the default toolchain, and\n" 555 " will be included for targets in other toolchains.\n" 556 "\n" 557 " {{output}}\n" 558 " The relative path and name of the output)((s) of the current\n" 559 " build step. If there is more than one output, this will expand\n" 560 " to a list of all of them.\n" 561 " Example: \"out/base/my_file.o\"\n" 562 "\n" 563 " {{target_gen_dir}}\n" 564 " {{target_out_dir}}\n" 565 " The directory of the generated file and output directories,\n" 566 " respectively, for the current target. There is no trailing\n" 567 " slash.\n" 568 " Example: \"out/base/test\"\n" 569 "\n" 570 " {{target_output_name}}\n" 571 " The short name of the current target with no path information,\n" 572 " or the value of the \"output_name\" variable if one is specified\n" 573 " in the target. This will include the \"output_prefix\" if any.\n" 574 " Example: \"libfoo\" for the target named \"foo\" and an\n" 575 " output prefix for the linker tool of \"lib\".\n" 576 "\n" 577 " Compiler tools have the notion of a single input and a single output,\n" 578 " along with a set of compiler-specific flags. The following expansions\n" 579 " are available:\n" 580 "\n" 581 " {{cflags}}\n" 582 " {{cflags_c}}\n" 583 " {{cflags_cc}}\n" 584 " {{cflags_objc}}\n" 585 " {{cflags_objcc}}\n" 586 " {{defines}}\n" 587 " {{include_dirs}}\n" 588 " Strings correspond that to the processed flags/defines/include\n" 589 " directories specified for the target.\n" 590 " Example: \"--enable-foo --enable-bar\"\n" 591 "\n" 592 " Defines will be prefixed by \"-D\" and include directories will\n" 593 " be prefixed by \"-I\" (these work with Posix tools as well as\n" 594 " Microsoft ones).\n" 595 "\n" 596 " {{source}}\n" 597 " The relative path and name of the current input file.\n" 598 " Example: \"../../base/my_file.cc\"\n" 599 "\n" 600 " {{source_file_part}}\n" 601 " The file part of the source including the extension (with no\n" 602 " directory information).\n" 603 " Example: \"foo.cc\"\n" 604 "\n" 605 " {{source_name_part}}\n" 606 " The filename part of the source file with no directory or\n" 607 " extension.\n" 608 " Example: \"foo\"\n" 609 "\n" 610 " {{source_gen_dir}}\n" 611 " {{source_out_dir}}\n" 612 " The directory in the generated file and output directories,\n" 613 " respectively, for the current input file. If the source file\n" 614 " is in the same directory as the target is declared in, they will\n" 615 " will be the same as the \"target\" versions above.\n" 616 " Example: \"gen/base/test\"\n" 617 "\n" 618 " Linker tools have multiple inputs and (potentially) multiple outputs\n" 619 " The following expansions are available:\n" 620 "\n" 621 " {{inputs}}\n" 622 " {{inputs_newline}}\n" 623 " Expands to the inputs to the link step. This will be a list of\n" 624 " object files and static libraries.\n" 625 " Example: \"obj/foo.o obj/bar.o obj/somelibrary.a\"\n" 626 "\n" 627 " The \"_newline\" version will separate the input files with\n" 628 " newlines instead of spaces. This is useful in response files:\n" 629 " some linkers can take a \"-filelist\" flag which expects newline\n" 630 " separated files, and some Microsoft tools have a fixed-sized\n" 631 " buffer for parsing each line of a response file.\n" 632 "\n" 633 " {{ldflags}}\n" 634 " Expands to the processed set of ldflags and library search paths\n" 635 " specified for the target.\n" 636 " Example: \"-m64, -fPIC -pthread -L/usr/local/mylib\"\n" 637 "\n" 638 " {{libs}}\n" 639 " Expands to the list of system libraries to link to. Each will\n" 640 " be prefixed by the \"lib_prefix\".\n" 641 "\n" 642 " As a special case to support Mac, libraries with names ending in\n" 643 " \".framework\" will be added to the {{libs}} with \"-framework\"\n" 644 " preceeding it, and the lib prefix will be ignored.\n" 645 "\n" 646 " Example: \"-lfoo -lbar\"\n" 647 "\n" 648 " {{output_extension}}\n" 649 " The value of the \"output_extension\" variable in the target,\n" 650 " or the value of the \"default_output_extension\" value in the\n" 651 " tool if the target does not specify an output extension.\n" 652 " Example: \".so\"\n" 653 "\n" 654 " {{solibs}}\n" 655 " Extra libraries from shared library dependencide not specified\n" 656 " in the {{inputs}}. This is the list of link_output files from\n" 657 " shared libraries (if the solink tool specifies a \"link_output\"\n" 658 " variable separate from the \"depend_output\").\n" 659 "\n" 660 " These should generally be treated the same as libs by your tool.\n" 661 " Example: \"libfoo.so libbar.so\"\n" 662 "\n" 663 " The copy tool allows the common compiler/linker substitutions, plus\n" 664 " {{source}} which is the source of the copy. The stamp tool allows\n" 665 " only the common tool substitutions.\n" 666 "\n" 667 "Separate linking and dependencies for shared libraries\n" 668 "\n" 669 " Shared libraries are special in that not all changes to them require\n" 670 " that dependent targets be re-linked. If the shared library is changed\n" 671 " but no imports or exports are different, dependent code needn't be\n" 672 " relinked, which can speed up the build.\n" 673 "\n" 674 " If your link step can output a list of exports from a shared library\n" 675 " and writes the file only if the new one is different, the timestamp of\n" 676 " this file can be used for triggering re-links, while the actual shared\n" 677 " library would be used for linking.\n" 678 "\n" 679 " You will need to specify\n" 680 " restat = true\n" 681 " in the linker tool to make this work, so Ninja will detect if the\n" 682 " timestamp of the dependency file has changed after linking (otherwise\n" 683 " it will always assume that running a command updates the output):\n" 684 "\n" 685 " tool(\"solink\") {\n" 686 " command = \"...\"\n" 687 " outputs = [\n" 688 " \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n" 689 " \"{{root_out_dir}}/{{target_output_name}}" 690 "{{output_extension}}.TOC\",\n" 691 " ]\n" 692 " link_output =\n" 693 " \"{{root_out_dir}}/{{target_output_name}}{{output_extension}}\",\n" 694 " depend_output =\n" 695 " \"{{root_out_dir}}/{{target_output_name}}" 696 "{{output_extension}}.TOC\",\n" 697 " restat = true\n" 698 " }\n" 699 "\n" 700 "Example\n" 701 "\n" 702 " toolchain(\"my_toolchain\") {\n" 703 " # Put these at the top to apply to all tools below.\n" 704 " lib_prefix = \"-l\"\n" 705 " lib_dir_prefix = \"-L\"\n" 706 "\n" 707 " tool(\"cc\") {\n" 708 " command = \"gcc \\$in -o \\$out\"\n" 709 " outputs = [ \"{{source_out_dir}}/{{source_name_part}}.o\"\n" 710 " description = \"GCC \\$in\"\n" 711 " }\n" 712 " tool(\"cxx\") {\n" 713 " command = \"g++ \\$in -o \\$out\"\n" 714 " outputs = [ \"{{source_out_dir}}/{{source_name_part}}.o\"\n" 715 " description = \"G++ \\$in\"\n" 716 " }\n" 717 " }\n"; 718 719 Value RunTool(Scope* scope, 720 const FunctionCallNode* function, 721 const std::vector<Value>& args, 722 BlockNode* block, 723 Err* err) { 724 // Find the toolchain definition we're executing inside of. The toolchain 725 // function will set a property pointing to it that we'll pick up. 726 Toolchain* toolchain = reinterpret_cast<Toolchain*>( 727 scope->GetProperty(&kToolchainPropertyKey, NULL)); 728 if (!toolchain) { 729 *err = Err(function->function(), "tool() called outside of toolchain().", 730 "The tool() function can only be used inside a toolchain() " 731 "definition."); 732 return Value(); 733 } 734 735 if (!EnsureSingleStringArg(function, args, err)) 736 return Value(); 737 const std::string& tool_name = args[0].string_value(); 738 Toolchain::ToolType tool_type = Toolchain::ToolNameToType(tool_name); 739 if (tool_type == Toolchain::TYPE_NONE) { 740 *err = Err(args[0], "Unknown tool type"); 741 return Value(); 742 } 743 744 // Run the tool block. 745 Scope block_scope(scope); 746 block->ExecuteBlockInScope(&block_scope, err); 747 if (err->has_error()) 748 return Value(); 749 750 // Figure out which validator to use for the substitution pattern for this 751 // tool type. There are different validators for the "outputs" than for the 752 // rest of the strings. 753 bool (*subst_validator)(SubstitutionType) = NULL; 754 bool (*subst_output_validator)(SubstitutionType) = NULL; 755 if (IsCompilerTool(tool_type)) { 756 subst_validator = &IsValidCompilerSubstitution; 757 subst_output_validator = &IsValidCompilerOutputsSubstitution; 758 } else if (IsLinkerTool(tool_type)) { 759 subst_validator = &IsValidLinkerSubstitution; 760 subst_output_validator = &IsValidLinkerOutputsSubstitution; 761 } else if (tool_type == Toolchain::TYPE_COPY) { 762 subst_validator = &IsValidCopySubstitution; 763 subst_output_validator = &IsValidCopySubstitution; 764 } else { 765 subst_validator = &IsValidToolSubstutition; 766 subst_output_validator = &IsValidToolSubstutition; 767 } 768 769 scoped_ptr<Tool> tool(new Tool); 770 771 if (!ReadPattern(&block_scope, "command", subst_validator, tool.get(), 772 &Tool::set_command, err) || 773 !ReadOutputExtension(&block_scope, tool.get(), err) || 774 !ReadPattern(&block_scope, "depfile", subst_validator, tool.get(), 775 &Tool::set_depfile, err) || 776 !ReadDepsFormat(&block_scope, tool.get(), err) || 777 !ReadPattern(&block_scope, "description", subst_validator, tool.get(), 778 &Tool::set_description, err) || 779 !ReadString(&block_scope, "lib_switch", tool.get(), 780 &Tool::set_lib_switch, err) || 781 !ReadString(&block_scope, "lib_dir_switch", tool.get(), 782 &Tool::set_lib_dir_switch, err) || 783 !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(), 784 &Tool::set_link_output, err) || 785 !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(), 786 &Tool::set_depend_output, err) || 787 !ReadString(&block_scope, "output_prefix", tool.get(), 788 &Tool::set_output_prefix, err) || 789 !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) || 790 !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(), 791 &Tool::set_rspfile, err) || 792 !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(), 793 &Tool::set_rspfile_content, err)) { 794 return Value(); 795 } 796 797 if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) { 798 // All tools except the copy and stamp tools should have outputs. The copy 799 // and stamp tool's outputs are generated internally. 800 if (!ReadOutputs(&block_scope, function, subst_output_validator, 801 tool.get(), err)) 802 return Value(); 803 } 804 805 // Validate that the link_output and depend_output refer to items in the 806 // outputs and aren't defined for irrelevant tool types. 807 if (!tool->link_output().empty()) { 808 if (tool_type != Toolchain::TYPE_SOLINK) { 809 *err = Err(function, "This tool specifies a link_output.", 810 "This is only valid for solink tools."); 811 return Value(); 812 } 813 if (!IsPatternInOutputList(tool->outputs(), tool->link_output())) { 814 *err = Err(function, "This tool's link_output is bad.", 815 "It must match one of the outputs."); 816 return Value(); 817 } 818 } 819 if (!tool->depend_output().empty()) { 820 if (tool_type != Toolchain::TYPE_SOLINK) { 821 *err = Err(function, "This tool specifies a depend_output.", 822 "This is only valid for solink tools."); 823 return Value(); 824 } 825 if (!IsPatternInOutputList(tool->outputs(), tool->depend_output())) { 826 *err = Err(function, "This tool's depend_output is bad.", 827 "It must match one of the outputs."); 828 return Value(); 829 } 830 } 831 if ((!tool->link_output().empty() && tool->depend_output().empty()) || 832 (tool->link_output().empty() && !tool->depend_output().empty())) { 833 *err = Err(function, "Both link_output and depend_output should either " 834 "be specified or they should both be empty."); 835 return Value(); 836 } 837 838 // Make sure there weren't any vars set in this tool that were unused. 839 if (!block_scope.CheckForUnusedVars(err)) 840 return Value(); 841 842 toolchain->SetTool(tool_type, tool.Pass()); 843 return Value(); 844 } 845 846 // toolchain_args -------------------------------------------------------------- 847 848 extern const char kToolchainArgs[] = "toolchain_args"; 849 extern const char kToolchainArgs_HelpShort[] = 850 "toolchain_args: Set build arguments for toolchain build setup."; 851 extern const char kToolchainArgs_Help[] = 852 "toolchain_args: Set build arguments for toolchain build setup.\n" 853 "\n" 854 " Used inside a toolchain definition to pass arguments to an alternate\n" 855 " toolchain's invocation of the build.\n" 856 "\n" 857 " When you specify a target using an alternate toolchain, the master\n" 858 " build configuration file is re-interpreted in the context of that\n" 859 " toolchain (see \"gn help toolchain\"). The toolchain_args function\n" 860 " allows you to control the arguments passed into this alternate\n" 861 " invocation of the build.\n" 862 "\n" 863 " Any default system arguments or arguments passed in on the command-\n" 864 " line will also be passed to the alternate invocation unless explicitly\n" 865 " overridden by toolchain_args.\n" 866 "\n" 867 " The toolchain_args will be ignored when the toolchain being defined\n" 868 " is the default. In this case, it's expected you want the default\n" 869 " argument values.\n" 870 "\n" 871 " See also \"gn help buildargs\" for an overview of these arguments.\n" 872 "\n" 873 "Example:\n" 874 " toolchain(\"my_weird_toolchain\") {\n" 875 " ...\n" 876 " toolchain_args() {\n" 877 " # Override the system values for a generic Posix system.\n" 878 " is_win = false\n" 879 " is_posix = true\n" 880 "\n" 881 " # Pass this new value for specific setup for my toolchain.\n" 882 " is_my_weird_system = true\n" 883 " }\n" 884 " }\n"; 885 886 Value RunToolchainArgs(Scope* scope, 887 const FunctionCallNode* function, 888 const std::vector<Value>& args, 889 BlockNode* block, 890 Err* err) { 891 // Find the toolchain definition we're executing inside of. The toolchain 892 // function will set a property pointing to it that we'll pick up. 893 Toolchain* toolchain = reinterpret_cast<Toolchain*>( 894 scope->GetProperty(&kToolchainPropertyKey, NULL)); 895 if (!toolchain) { 896 *err = Err(function->function(), 897 "toolchain_args() called outside of toolchain().", 898 "The toolchain_args() function can only be used inside a " 899 "toolchain() definition."); 900 return Value(); 901 } 902 903 if (!args.empty()) { 904 *err = Err(function->function(), "This function takes no arguments."); 905 return Value(); 906 } 907 908 // This function makes a new scope with various variable sets on it, which 909 // we then save on the toolchain to use when re-invoking the build. 910 Scope block_scope(scope); 911 block->ExecuteBlockInScope(&block_scope, err); 912 if (err->has_error()) 913 return Value(); 914 915 Scope::KeyValueMap values; 916 block_scope.GetCurrentScopeValues(&values); 917 toolchain->args() = values; 918 919 return Value(); 920 } 921 922 } // namespace functions 923