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 | 7 |
7 #include "tools/gn/err.h" | 8 #include "tools/gn/err.h" |
8 #include "tools/gn/functions.h" | 9 #include "tools/gn/functions.h" |
9 #include "tools/gn/parse_tree.h" | 10 #include "tools/gn/parse_tree.h" |
10 #include "tools/gn/scheduler.h" | 11 #include "tools/gn/scheduler.h" |
11 #include "tools/gn/scope.h" | 12 #include "tools/gn/scope.h" |
12 #include "tools/gn/settings.h" | 13 #include "tools/gn/settings.h" |
13 #include "tools/gn/tool.h" | 14 #include "tools/gn/tool.h" |
14 #include "tools/gn/toolchain.h" | 15 #include "tools/gn/toolchain.h" |
15 #include "tools/gn/value_extractors.h" | 16 #include "tools/gn/value_extractors.h" |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 const char kToolchain[] = "toolchain"; | 196 const char kToolchain[] = "toolchain"; |
196 const char kToolchain_HelpShort[] = | 197 const char kToolchain_HelpShort[] = |
197 "toolchain: Defines a toolchain."; | 198 "toolchain: Defines a toolchain."; |
198 const char kToolchain_Help[] = | 199 const char kToolchain_Help[] = |
199 "toolchain: Defines a toolchain.\n" | 200 "toolchain: Defines a toolchain.\n" |
200 "\n" | 201 "\n" |
201 " A toolchain is a set of commands and build flags used to compile the\n" | 202 " A toolchain is a set of commands and build flags used to compile the\n" |
202 " source code. You can have more than one toolchain in use at once in\n" | 203 " source code. You can have more than one toolchain in use at once in\n" |
203 " a build.\n" | 204 " a build.\n" |
204 "\n" | 205 "\n" |
205 " A toolchain specifies the commands to run for various input file\n" | 206 "Functions and variables\n" |
206 " types via the \"tool\" call (see \"gn help tool\") and specifies\n" | |
207 " arguments to be passed to the toolchain build via the\n" | |
208 " \"toolchain_args\" call (see \"gn help toolchain_args\").\n" | |
209 "\n" | 207 "\n" |
210 " In addition, a toolchain can specify dependencies via the \"deps\"\n" | 208 " tool()\n" |
211 " variable like a target. These dependencies will be resolved before any\n" | 209 " The tool() function call specifies the commands commands to run for\n" |
212 " target in the toolchain is compiled. To avoid circular dependencies\n" | 210 " a given step. See \"gn help tool\".\n" |
213 " these must be targets defined in another toolchain.\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" |
214 "\n" | 243 "\n" |
215 "Invoking targets in toolchains:\n" | 244 "Invoking targets in toolchains:\n" |
216 "\n" | 245 "\n" |
217 " By default, when a target depends on another, there is an implicit\n" | 246 " By default, when a target depends on another, there is an implicit\n" |
218 " toolchain label that is inherited, so the dependee has the same one\n" | 247 " toolchain label that is inherited, so the dependee has the same one\n" |
219 " as the dependent.\n" | 248 " as the dependent.\n" |
220 "\n" | 249 "\n" |
221 " You can override this and refer to any other toolchain by explicitly\n" | 250 " You can override this and refer to any other toolchain by explicitly\n" |
222 " labeling the toolchain to use. For example:\n" | 251 " labeling the toolchain to use. For example:\n" |
223 " datadeps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" | 252 " datadeps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" |
224 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" | 253 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" |
225 " identifies the toolchain declaration for compiling the sources.\n" | 254 " identifies the toolchain declaration for compiling the sources.\n" |
226 "\n" | 255 "\n" |
227 " To load a file in an alternate toolchain, GN does the following:\n" | 256 " To load a file in an alternate toolchain, GN does the following:\n" |
228 "\n" | 257 "\n" |
229 " 1. Loads the file with the toolchain definition in it (as determined\n" | 258 " 1. Loads the file with the toolchain definition in it (as determined\n" |
230 " by the toolchain label).\n" | 259 " by the toolchain label).\n" |
231 " 2. Re-runs the master build configuration file, applying the\n" | 260 " 2. Re-runs the master build configuration file, applying the\n" |
232 " arguments specified by the toolchain_args section of the toolchain\n" | 261 " arguments specified by the toolchain_args section of the toolchain\n" |
233 " definition (see \"gn help toolchain_args\").\n" | 262 " definition (see \"gn help toolchain_args\").\n" |
234 " 3. Loads the destination build file in the context of the\n" | 263 " 3. Loads the destination build file in the context of the\n" |
235 " configuration file in the previous step.\n" | 264 " configuration file in the previous step.\n" |
236 "\n" | 265 "\n" |
237 "Example:\n" | 266 "Example:\n" |
238 " toolchain(\"plugin_toolchain\") {\n" | 267 " toolchain(\"plugin_toolchain\") {\n" |
| 268 " concurrent_links = 8\n" |
| 269 "\n" |
239 " tool(\"cc\") {\n" | 270 " tool(\"cc\") {\n" |
240 " command = \"gcc $in\"\n" | 271 " command = \"gcc $in\"\n" |
| 272 " ...\n" |
241 " }\n" | 273 " }\n" |
242 "\n" | 274 "\n" |
243 " toolchain_args() {\n" | 275 " toolchain_args() {\n" |
244 " is_plugin = true\n" | 276 " is_plugin = true\n" |
245 " is_32bit = true\n" | 277 " is_32bit = true\n" |
246 " is_64bit = false\n" | 278 " is_64bit = false\n" |
247 " }\n" | 279 " }\n" |
248 " }\n"; | 280 " }\n"; |
249 | 281 |
250 Value RunToolchain(Scope* scope, | 282 Value RunToolchain(Scope* scope, |
(...skipping 29 matching lines...) Expand all Loading... |
280 // Read deps (if any). | 312 // Read deps (if any). |
281 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); | 313 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); |
282 if (deps_value) { | 314 if (deps_value) { |
283 ExtractListOfLabels( | 315 ExtractListOfLabels( |
284 *deps_value, block_scope.GetSourceDir(), | 316 *deps_value, block_scope.GetSourceDir(), |
285 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); | 317 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); |
286 if (err->has_error()) | 318 if (err->has_error()) |
287 return Value(); | 319 return Value(); |
288 } | 320 } |
289 | 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 |
290 if (!block_scope.CheckForUnusedVars(err)) | 337 if (!block_scope.CheckForUnusedVars(err)) |
291 return Value(); | 338 return Value(); |
292 | 339 |
293 // Save this toolchain. | 340 // Save this toolchain. |
294 toolchain->ToolchainSetupComplete(); | 341 toolchain->ToolchainSetupComplete(); |
295 Scope::ItemVector* collector = scope->GetItemCollector(); | 342 Scope::ItemVector* collector = scope->GetItemCollector(); |
296 if (!collector) { | 343 if (!collector) { |
297 *err = Err(function, "Can't define a toolchain in this context."); | 344 *err = Err(function, "Can't define a toolchain in this context."); |
298 return Value(); | 345 return Value(); |
299 } | 346 } |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 " Prefix to use for the output name. Defaults to empty. This\n" | 498 " Prefix to use for the output name. Defaults to empty. This\n" |
452 " prefix will be prepended to the name of the target (or the\n" | 499 " prefix will be prepended to the name of the target (or the\n" |
453 " output_name if one is manually specified for it) if the prefix\n" | 500 " output_name if one is manually specified for it) if the prefix\n" |
454 " is not already there. The result will show up in the\n" | 501 " is not already there. The result will show up in the\n" |
455 " {{output_name}} substitution pattern.\n" | 502 " {{output_name}} substitution pattern.\n" |
456 "\n" | 503 "\n" |
457 " This is typically used to prepend \"lib\" to libraries on\n" | 504 " This is typically used to prepend \"lib\" to libraries on\n" |
458 " Posix systems:\n" | 505 " Posix systems:\n" |
459 " output_prefix = \"lib\"\n" | 506 " output_prefix = \"lib\"\n" |
460 "\n" | 507 "\n" |
461 // TODO(brettw) document "pool" when it works. | |
462 //" pool [string, optional]\n" | |
463 //"\n" | |
464 " restat [boolean]\n" | 508 " restat [boolean]\n" |
465 " Valid for: all tools (optional, defaults to false)\n" | 509 " Valid for: all tools (optional, defaults to false)\n" |
466 "\n" | 510 "\n" |
467 " Requests that Ninja check the file timestamp after this tool has\n" | 511 " Requests that Ninja check the file timestamp after this tool has\n" |
468 " run to determine if anything changed. Set this if your tool has\n" | 512 " run to determine if anything changed. Set this if your tool has\n" |
469 " the ability to skip writing output if the output file has not\n" | 513 " the ability to skip writing output if the output file has not\n" |
470 " changed.\n" | 514 " changed.\n" |
471 "\n" | 515 "\n" |
472 " Normally, Ninja will assume that when a tool runs the output\n" | 516 " Normally, Ninja will assume that when a tool runs the output\n" |
473 " be new and downstream dependents must be rebuild. When this is\n" | 517 " be new and downstream dependents must be rebuild. When this is\n" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 !ReadString(&block_scope, "lib_switch", tool.get(), | 779 !ReadString(&block_scope, "lib_switch", tool.get(), |
736 &Tool::set_lib_switch, err) || | 780 &Tool::set_lib_switch, err) || |
737 !ReadString(&block_scope, "lib_dir_switch", tool.get(), | 781 !ReadString(&block_scope, "lib_dir_switch", tool.get(), |
738 &Tool::set_lib_dir_switch, err) || | 782 &Tool::set_lib_dir_switch, err) || |
739 !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(), | 783 !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(), |
740 &Tool::set_link_output, err) || | 784 &Tool::set_link_output, err) || |
741 !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(), | 785 !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(), |
742 &Tool::set_depend_output, err) || | 786 &Tool::set_depend_output, err) || |
743 !ReadString(&block_scope, "output_prefix", tool.get(), | 787 !ReadString(&block_scope, "output_prefix", tool.get(), |
744 &Tool::set_output_prefix, err) || | 788 &Tool::set_output_prefix, err) || |
745 !ReadString(&block_scope, "pool", tool.get(), &Tool::set_pool, err) || | |
746 !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) || | 789 !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) || |
747 !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(), | 790 !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(), |
748 &Tool::set_rspfile, err) || | 791 &Tool::set_rspfile, err) || |
749 !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(), | 792 !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(), |
750 &Tool::set_rspfile_content, err)) { | 793 &Tool::set_rspfile_content, err)) { |
751 return Value(); | 794 return Value(); |
752 } | 795 } |
753 | 796 |
754 if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) { | 797 if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) { |
755 // All tools except the copy and stamp tools should have outputs. The copy | 798 // All tools except the copy and stamp tools should have outputs. The copy |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 return Value(); | 913 return Value(); |
871 | 914 |
872 Scope::KeyValueMap values; | 915 Scope::KeyValueMap values; |
873 block_scope.GetCurrentScopeValues(&values); | 916 block_scope.GetCurrentScopeValues(&values); |
874 toolchain->args() = values; | 917 toolchain->args() = values; |
875 | 918 |
876 return Value(); | 919 return Value(); |
877 } | 920 } |
878 | 921 |
879 } // namespace functions | 922 } // namespace functions |
OLD | NEW |