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. Defaults to 4.\n" | |
scottmg
2014/08/26 22:41:49
It ends up being 16 for gyp on a z620 fwiw. I don'
| |
238 "\n" | |
239 " The value used will be the one from the default toolchain of the\n" | |
240 " current build.\n" | |
214 "\n" | 241 "\n" |
215 "Invoking targets in toolchains:\n" | 242 "Invoking targets in toolchains:\n" |
216 "\n" | 243 "\n" |
217 " By default, when a target depends on another, there is an implicit\n" | 244 " 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" | 245 " toolchain label that is inherited, so the dependee has the same one\n" |
219 " as the dependent.\n" | 246 " as the dependent.\n" |
220 "\n" | 247 "\n" |
221 " You can override this and refer to any other toolchain by explicitly\n" | 248 " You can override this and refer to any other toolchain by explicitly\n" |
222 " labeling the toolchain to use. For example:\n" | 249 " labeling the toolchain to use. For example:\n" |
223 " datadeps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" | 250 " datadeps = [ \"//plugins:mine(//toolchains:plugin_toolchain)\" ]\n" |
224 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" | 251 " The string \"//build/toolchains:plugin_toolchain\" is a label that\n" |
225 " identifies the toolchain declaration for compiling the sources.\n" | 252 " identifies the toolchain declaration for compiling the sources.\n" |
226 "\n" | 253 "\n" |
227 " To load a file in an alternate toolchain, GN does the following:\n" | 254 " To load a file in an alternate toolchain, GN does the following:\n" |
228 "\n" | 255 "\n" |
229 " 1. Loads the file with the toolchain definition in it (as determined\n" | 256 " 1. Loads the file with the toolchain definition in it (as determined\n" |
230 " by the toolchain label).\n" | 257 " by the toolchain label).\n" |
231 " 2. Re-runs the master build configuration file, applying the\n" | 258 " 2. Re-runs the master build configuration file, applying the\n" |
232 " arguments specified by the toolchain_args section of the toolchain\n" | 259 " arguments specified by the toolchain_args section of the toolchain\n" |
233 " definition (see \"gn help toolchain_args\").\n" | 260 " definition (see \"gn help toolchain_args\").\n" |
234 " 3. Loads the destination build file in the context of the\n" | 261 " 3. Loads the destination build file in the context of the\n" |
235 " configuration file in the previous step.\n" | 262 " configuration file in the previous step.\n" |
236 "\n" | 263 "\n" |
237 "Example:\n" | 264 "Example:\n" |
238 " toolchain(\"plugin_toolchain\") {\n" | 265 " toolchain(\"plugin_toolchain\") {\n" |
266 " concurrent_links = 8\n" | |
267 "\n" | |
239 " tool(\"cc\") {\n" | 268 " tool(\"cc\") {\n" |
240 " command = \"gcc $in\"\n" | 269 " command = \"gcc $in\"\n" |
270 " ...\n" | |
241 " }\n" | 271 " }\n" |
242 "\n" | 272 "\n" |
243 " toolchain_args() {\n" | 273 " toolchain_args() {\n" |
244 " is_plugin = true\n" | 274 " is_plugin = true\n" |
245 " is_32bit = true\n" | 275 " is_32bit = true\n" |
246 " is_64bit = false\n" | 276 " is_64bit = false\n" |
247 " }\n" | 277 " }\n" |
248 " }\n"; | 278 " }\n"; |
249 | 279 |
250 Value RunToolchain(Scope* scope, | 280 Value RunToolchain(Scope* scope, |
(...skipping 29 matching lines...) Expand all Loading... | |
280 // Read deps (if any). | 310 // Read deps (if any). |
281 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); | 311 const Value* deps_value = block_scope.GetValue(variables::kDeps, true); |
282 if (deps_value) { | 312 if (deps_value) { |
283 ExtractListOfLabels( | 313 ExtractListOfLabels( |
284 *deps_value, block_scope.GetSourceDir(), | 314 *deps_value, block_scope.GetSourceDir(), |
285 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); | 315 ToolchainLabelForScope(&block_scope), &toolchain->deps(), err); |
286 if (err->has_error()) | 316 if (err->has_error()) |
287 return Value(); | 317 return Value(); |
288 } | 318 } |
289 | 319 |
320 // Read concurrent_links (if any). | |
321 const Value* concurrent_links_value = | |
322 block_scope.GetValue("concurrent_links", true); | |
323 if (concurrent_links_value) { | |
324 if (!concurrent_links_value->VerifyTypeIs(Value::INTEGER, err)) | |
325 return Value(); | |
326 if (concurrent_links_value->int_value() < 0 || | |
327 concurrent_links_value->int_value() > std::numeric_limits<int>::max()) { | |
328 *err = Err(*concurrent_links_value, "Value out of range."); | |
329 return Value(); | |
330 } | |
331 toolchain->set_concurrent_links( | |
332 static_cast<int>(concurrent_links_value->int_value())); | |
333 } | |
334 | |
290 if (!block_scope.CheckForUnusedVars(err)) | 335 if (!block_scope.CheckForUnusedVars(err)) |
291 return Value(); | 336 return Value(); |
292 | 337 |
293 // Save this toolchain. | 338 // Save this toolchain. |
294 toolchain->ToolchainSetupComplete(); | 339 toolchain->ToolchainSetupComplete(); |
295 Scope::ItemVector* collector = scope->GetItemCollector(); | 340 Scope::ItemVector* collector = scope->GetItemCollector(); |
296 if (!collector) { | 341 if (!collector) { |
297 *err = Err(function, "Can't define a toolchain in this context."); | 342 *err = Err(function, "Can't define a toolchain in this context."); |
298 return Value(); | 343 return Value(); |
299 } | 344 } |
(...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" | 496 " 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" | 497 " 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" | 498 " 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" | 499 " is not already there. The result will show up in the\n" |
455 " {{output_name}} substitution pattern.\n" | 500 " {{output_name}} substitution pattern.\n" |
456 "\n" | 501 "\n" |
457 " This is typically used to prepend \"lib\" to libraries on\n" | 502 " This is typically used to prepend \"lib\" to libraries on\n" |
458 " Posix systems:\n" | 503 " Posix systems:\n" |
459 " output_prefix = \"lib\"\n" | 504 " output_prefix = \"lib\"\n" |
460 "\n" | 505 "\n" |
461 // TODO(brettw) document "pool" when it works. | |
462 //" pool [string, optional]\n" | |
463 //"\n" | |
464 " restat [boolean]\n" | 506 " restat [boolean]\n" |
465 " Valid for: all tools (optional, defaults to false)\n" | 507 " Valid for: all tools (optional, defaults to false)\n" |
466 "\n" | 508 "\n" |
467 " Requests that Ninja check the file timestamp after this tool has\n" | 509 " 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" | 510 " 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" | 511 " the ability to skip writing output if the output file has not\n" |
470 " changed.\n" | 512 " changed.\n" |
471 "\n" | 513 "\n" |
472 " Normally, Ninja will assume that when a tool runs the output\n" | 514 " 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" | 515 " 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(), | 777 !ReadString(&block_scope, "lib_switch", tool.get(), |
736 &Tool::set_lib_switch, err) || | 778 &Tool::set_lib_switch, err) || |
737 !ReadString(&block_scope, "lib_dir_switch", tool.get(), | 779 !ReadString(&block_scope, "lib_dir_switch", tool.get(), |
738 &Tool::set_lib_dir_switch, err) || | 780 &Tool::set_lib_dir_switch, err) || |
739 !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(), | 781 !ReadPattern(&block_scope, "link_output", subst_validator, tool.get(), |
740 &Tool::set_link_output, err) || | 782 &Tool::set_link_output, err) || |
741 !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(), | 783 !ReadPattern(&block_scope, "depend_output", subst_validator, tool.get(), |
742 &Tool::set_depend_output, err) || | 784 &Tool::set_depend_output, err) || |
743 !ReadString(&block_scope, "output_prefix", tool.get(), | 785 !ReadString(&block_scope, "output_prefix", tool.get(), |
744 &Tool::set_output_prefix, err) || | 786 &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) || | 787 !ReadBool(&block_scope, "restat", tool.get(), &Tool::set_restat, err) || |
747 !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(), | 788 !ReadPattern(&block_scope, "rspfile", subst_validator, tool.get(), |
748 &Tool::set_rspfile, err) || | 789 &Tool::set_rspfile, err) || |
749 !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(), | 790 !ReadPattern(&block_scope, "rspfile_content", subst_validator, tool.get(), |
750 &Tool::set_rspfile_content, err)) { | 791 &Tool::set_rspfile_content, err)) { |
751 return Value(); | 792 return Value(); |
752 } | 793 } |
753 | 794 |
754 if (tool_type != Toolchain::TYPE_COPY && tool_type != Toolchain::TYPE_STAMP) { | 795 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 | 796 // 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(); | 911 return Value(); |
871 | 912 |
872 Scope::KeyValueMap values; | 913 Scope::KeyValueMap values; |
873 block_scope.GetCurrentScopeValues(&values); | 914 block_scope.GetCurrentScopeValues(&values); |
874 toolchain->args() = values; | 915 toolchain->args() = values; |
875 | 916 |
876 return Value(); | 917 return Value(); |
877 } | 918 } |
878 | 919 |
879 } // namespace functions | 920 } // namespace functions |
OLD | NEW |