| 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 <algorithm> | 5 #include <algorithm> |
| 6 #include <limits> | 6 #include <limits> |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "tools/gn/err.h" | 9 #include "tools/gn/err.h" |
| 10 #include "tools/gn/functions.h" | 10 #include "tools/gn/functions.h" |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 " A toolchain is a set of commands and build flags used to compile the\n" | 307 " A toolchain is a set of commands and build flags used to compile the\n" |
| 308 " source code. You can have more than one toolchain in use at once in\n" | 308 " source code. You can have more than one toolchain in use at once in\n" |
| 309 " a build.\n" | 309 " a build.\n" |
| 310 "\n" | 310 "\n" |
| 311 "Functions and variables\n" | 311 "Functions and variables\n" |
| 312 "\n" | 312 "\n" |
| 313 " tool()\n" | 313 " tool()\n" |
| 314 " The tool() function call specifies the commands commands to run for\n" | 314 " The tool() function call specifies the commands commands to run for\n" |
| 315 " a given step. See \"gn help tool\".\n" | 315 " a given step. See \"gn help tool\".\n" |
| 316 "\n" | 316 "\n" |
| 317 " toolchain_args()\n" | 317 " toolchain_args\n" |
| 318 " List of arguments to pass to the toolchain when invoking this\n" | 318 " Overrides for build arguments to pass to the toolchain when invoking\n" |
| 319 " toolchain. This applies only to non-default toolchains. See\n" | 319 " it. This is a variable of type \"scope\" where the variable names\n" |
| 320 " \"gn help toolchain_args\" for more.\n" | 320 " correspond to varibles in declare_args() blocks.\n" |
| 321 "\n" |
| 322 " When you specify a target using an alternate toolchain, the master\n" |
| 323 " build configuration file is re-interpreted in the context of that\n" |
| 324 " toolchain (see \"gn help toolchain\"). The toolchain_args allows you\n" |
| 325 " to control the arguments passed into this alternate invocation of\n" |
| 326 " the build.\n" |
| 327 "\n" |
| 328 " Any default system arguments or arguments passed in via \"gn args\"\n" |
| 329 " will also be passed to the alternate invocation unless explicitly\n" |
| 330 " overridden by toolchain_args.\n" |
| 331 "\n" |
| 332 " The toolchain_args will be ignored when the toolchain being defined\n" |
| 333 " is the default. In this case, it's expected you want the default\n" |
| 334 " argument values.\n" |
| 335 "\n" |
| 336 " See also \"gn help buildargs\" for an overview of these arguments.\n" |
| 321 "\n" | 337 "\n" |
| 322 " deps\n" | 338 " deps\n" |
| 323 " Dependencies of this toolchain. These dependencies will be resolved\n" | 339 " Dependencies of this toolchain. These dependencies will be resolved\n" |
| 324 " before any target in the toolchain is compiled. To avoid circular\n" | 340 " before any target in the toolchain is compiled. To avoid circular\n" |
| 325 " dependencies these must be targets defined in another toolchain.\n" | 341 " dependencies these must be targets defined in another toolchain.\n" |
| 326 "\n" | 342 "\n" |
| 327 " This is expressed as a list of targets, and generally these targets\n" | 343 " This is expressed as a list of targets, and generally these targets\n" |
| 328 " will always specify a toolchain:\n" | 344 " will always specify a toolchain:\n" |
| 329 " deps = [ \"//foo/bar:baz(//build/toolchain:bootstrap)\" ]\n" | 345 " deps = [ \"//foo/bar:baz(//build/toolchain:bootstrap)\" ]\n" |
| 330 "\n" | 346 "\n" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 343 " data_deps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" | 359 " data_deps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" |
| 344 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" | 360 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" |
| 345 " identifies the toolchain declaration for compiling the sources.\n" | 361 " identifies the toolchain declaration for compiling the sources.\n" |
| 346 "\n" | 362 "\n" |
| 347 " To load a file in an alternate toolchain, GN does the following:\n" | 363 " To load a file in an alternate toolchain, GN does the following:\n" |
| 348 "\n" | 364 "\n" |
| 349 " 1. Loads the file with the toolchain definition in it (as determined\n" | 365 " 1. Loads the file with the toolchain definition in it (as determined\n" |
| 350 " by the toolchain label).\n" | 366 " by the toolchain label).\n" |
| 351 " 2. Re-runs the master build configuration file, applying the\n" | 367 " 2. Re-runs the master build configuration file, applying the\n" |
| 352 " arguments specified by the toolchain_args section of the toolchain\n" | 368 " arguments specified by the toolchain_args section of the toolchain\n" |
| 353 " definition (see \"gn help toolchain_args\").\n" | 369 " definition.\n" |
| 354 " 3. Loads the destination build file in the context of the\n" | 370 " 3. Loads the destination build file in the context of the\n" |
| 355 " configuration file in the previous step.\n" | 371 " configuration file in the previous step.\n" |
| 356 "\n" | 372 "\n" |
| 357 "Example:\n" | 373 "Example\n" |
| 374 "\n" |
| 358 " toolchain(\"plugin_toolchain\") {\n" | 375 " toolchain(\"plugin_toolchain\") {\n" |
| 359 " tool(\"cc\") {\n" | 376 " tool(\"cc\") {\n" |
| 360 " command = \"gcc {{source}}\"\n" | 377 " command = \"gcc {{source}}\"\n" |
| 361 " ...\n" | 378 " ...\n" |
| 362 " }\n" | 379 " }\n" |
| 363 "\n" | 380 "\n" |
| 364 " toolchain_args() {\n" | 381 " toolchain_args = {\n" |
| 365 " is_plugin = true\n" | 382 " is_plugin = true\n" |
| 366 " is_32bit = true\n" | 383 " is_32bit = true\n" |
| 367 " is_64bit = false\n" | 384 " is_64bit = false\n" |
| 368 " }\n" | 385 " }\n" |
| 369 " }\n"; | 386 " }\n"; |
| 370 | 387 |
| 371 Value RunToolchain(Scope* scope, | 388 Value RunToolchain(Scope* scope, |
| 372 const FunctionCallNode* function, | 389 const FunctionCallNode* function, |
| 373 const std::vector<Value>& args, | 390 const std::vector<Value>& args, |
| 374 BlockNode* block, | 391 BlockNode* block, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 405 // Read deps (if any). | 422 // Read deps (if any). |
| 406 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); | 423 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); |
| 407 if (deps_value) { | 424 if (deps_value) { |
| 408 ExtractListOfLabels( | 425 ExtractListOfLabels( |
| 409 *deps_value, block_scope.GetSourceDir(), | 426 *deps_value, block_scope.GetSourceDir(), |
| 410 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); | 427 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); |
| 411 if (err->has_error()) | 428 if (err->has_error()) |
| 412 return Value(); | 429 return Value(); |
| 413 } | 430 } |
| 414 | 431 |
| 432 // Read toolchain args (if any). |
| 433 const Value* toolchain_args = block_scope.GetValue("toolchain_args", true); |
| 434 if (toolchain_args) { |
| 435 if (!toolchain_args->VerifyTypeIs(Value::SCOPE, err)) |
| 436 return Value(); |
| 437 |
| 438 Scope::KeyValueMap values; |
| 439 toolchain_args->scope_value()->GetCurrentScopeValues(&values); |
| 440 toolchain->args() = values; |
| 441 } |
| 442 |
| 415 if (!block_scope.CheckForUnusedVars(err)) | 443 if (!block_scope.CheckForUnusedVars(err)) |
| 416 return Value(); | 444 return Value(); |
| 417 | 445 |
| 418 // Save this toolchain. | 446 // Save this toolchain. |
| 419 toolchain->ToolchainSetupComplete(); | 447 toolchain->ToolchainSetupComplete(); |
| 420 Scope::ItemVector* collector = scope->GetItemCollector(); | 448 Scope::ItemVector* collector = scope->GetItemCollector(); |
| 421 if (!collector) { | 449 if (!collector) { |
| 422 *err = Err(function, "Can't define a toolchain in this context."); | 450 *err = Err(function, "Can't define a toolchain in this context."); |
| 423 return Value(); | 451 return Value(); |
| 424 } | 452 } |
| (...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 } | 1036 } |
| 1009 | 1037 |
| 1010 // Make sure there weren't any vars set in this tool that were unused. | 1038 // Make sure there weren't any vars set in this tool that were unused. |
| 1011 if (!block_scope.CheckForUnusedVars(err)) | 1039 if (!block_scope.CheckForUnusedVars(err)) |
| 1012 return Value(); | 1040 return Value(); |
| 1013 | 1041 |
| 1014 toolchain->SetTool(tool_type, std::move(tool)); | 1042 toolchain->SetTool(tool_type, std::move(tool)); |
| 1015 return Value(); | 1043 return Value(); |
| 1016 } | 1044 } |
| 1017 | 1045 |
| 1018 // toolchain_args -------------------------------------------------------------- | |
| 1019 | |
| 1020 extern const char kToolchainArgs[] = "toolchain_args"; | 1046 extern const char kToolchainArgs[] = "toolchain_args"; |
| 1021 extern const char kToolchainArgs_HelpShort[] = | 1047 extern const char kToolchainArgs_HelpShort[] = |
| 1022 "toolchain_args: Set build arguments for toolchain build setup."; | 1048 "toolchain_args: Set build arguments for toolchain build setup."; |
| 1023 extern const char kToolchainArgs_Help[] = | 1049 extern const char kToolchainArgs_Help[] = |
| 1024 "toolchain_args: Set build arguments for toolchain build setup.\n" | 1050 "toolchain_args: Set build arguments for toolchain build setup.\n" |
| 1025 "\n" | 1051 "\n" |
| 1026 " Used inside a toolchain definition to pass arguments to an alternate\n" | 1052 " DEPRECATED. Instead use:\n" |
| 1027 " toolchain's invocation of the build.\n" | 1053 " toolchain_args = { ... }\n" |
| 1028 "\n" | 1054 "\n" |
| 1029 " When you specify a target using an alternate toolchain, the master\n" | 1055 " See \"gn help toolchain\" for documentation.\n"; |
| 1030 " build configuration file is re-interpreted in the context of that\n" | |
| 1031 " toolchain (see \"gn help toolchain\"). The toolchain_args function\n" | |
| 1032 " allows you to control the arguments passed into this alternate\n" | |
| 1033 " invocation of the build.\n" | |
| 1034 "\n" | |
| 1035 " Any default system arguments or arguments passed in on the command-\n" | |
| 1036 " line will also be passed to the alternate invocation unless explicitly\n" | |
| 1037 " overridden by toolchain_args.\n" | |
| 1038 "\n" | |
| 1039 " The toolchain_args will be ignored when the toolchain being defined\n" | |
| 1040 " is the default. In this case, it's expected you want the default\n" | |
| 1041 " argument values.\n" | |
| 1042 "\n" | |
| 1043 " See also \"gn help buildargs\" for an overview of these arguments.\n" | |
| 1044 "\n" | |
| 1045 "Example:\n" | |
| 1046 " toolchain(\"my_weird_toolchain\") {\n" | |
| 1047 " ...\n" | |
| 1048 " toolchain_args() {\n" | |
| 1049 " # Override the system values for a generic Posix system.\n" | |
| 1050 " is_win = false\n" | |
| 1051 " is_posix = true\n" | |
| 1052 "\n" | |
| 1053 " # Pass this new value for specific setup for my toolchain.\n" | |
| 1054 " is_my_weird_system = true\n" | |
| 1055 " }\n" | |
| 1056 " }\n"; | |
| 1057 | 1056 |
| 1058 Value RunToolchainArgs(Scope* scope, | 1057 Value RunToolchainArgs(Scope* scope, |
| 1059 const FunctionCallNode* function, | 1058 const FunctionCallNode* function, |
| 1060 const std::vector<Value>& args, | 1059 const std::vector<Value>& args, |
| 1061 BlockNode* block, | 1060 BlockNode* block, |
| 1062 Err* err) { | 1061 Err* err) { |
| 1063 // Find the toolchain definition we're executing inside of. The toolchain | 1062 // This is a backwards-compatible shim that converts the old form of: |
| 1064 // function will set a property pointing to it that we'll pick up. | 1063 // toolchain_args() { |
| 1065 Toolchain* toolchain = reinterpret_cast<Toolchain*>( | 1064 // foo = bar |
| 1066 scope->GetProperty(&kToolchainPropertyKey, nullptr)); | 1065 // } |
| 1067 if (!toolchain) { | 1066 // to the new form: |
| 1068 *err = Err(function->function(), | 1067 // toolchain_args = { |
| 1069 "toolchain_args() called outside of toolchain().", | 1068 // foo = bar |
| 1070 "The toolchain_args() function can only be used inside a " | 1069 // } |
| 1071 "toolchain() definition."); | 1070 // It will be deleted when all users of toolchain_args as a function are |
| 1072 return Value(); | 1071 // deleted. |
| 1073 } | |
| 1074 | |
| 1075 if (!args.empty()) { | 1072 if (!args.empty()) { |
| 1076 *err = Err(function->function(), "This function takes no arguments."); | 1073 *err = Err(function->function(), "This function takes no arguments."); |
| 1077 return Value(); | 1074 return Value(); |
| 1078 } | 1075 } |
| 1079 | 1076 |
| 1080 // This function makes a new scope with various variable sets on it, which | 1077 std::unique_ptr<Scope> block_scope(new Scope(scope)); |
| 1081 // we then save on the toolchain to use when re-invoking the build. | 1078 block->Execute(block_scope.get(), err); |
| 1082 Scope block_scope(scope); | |
| 1083 block->Execute(&block_scope, err); | |
| 1084 if (err->has_error()) | 1079 if (err->has_error()) |
| 1085 return Value(); | 1080 return Value(); |
| 1086 | 1081 |
| 1087 Scope::KeyValueMap values; | 1082 block_scope->DetachFromContaining(); |
| 1088 block_scope.GetCurrentScopeValues(&values); | 1083 scope->SetValue("toolchain_args", Value(function, std::move(block_scope)), |
| 1089 toolchain->args() = values; | 1084 function); |
| 1090 | |
| 1091 return Value(); | 1085 return Value(); |
| 1092 } | 1086 } |
| 1093 | 1087 |
| 1094 } // namespace functions | 1088 } // namespace functions |
| OLD | NEW |