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 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 | 298 |
299 // toolchain ------------------------------------------------------------------- | 299 // toolchain ------------------------------------------------------------------- |
300 | 300 |
301 const char kToolchain[] = "toolchain"; | 301 const char kToolchain[] = "toolchain"; |
302 const char kToolchain_HelpShort[] = | 302 const char kToolchain_HelpShort[] = |
303 "toolchain: Defines a toolchain."; | 303 "toolchain: Defines a toolchain."; |
304 const char kToolchain_Help[] = | 304 const char kToolchain_Help[] = |
305 R"*(toolchain: Defines a toolchain. | 305 R"*(toolchain: Defines a toolchain. |
306 | 306 |
307 A toolchain is a set of commands and build flags used to compile the source | 307 A toolchain is a set of commands and build flags used to compile the source |
308 code. You can have more than one toolchain in use at once in a build. | 308 code. The toolchain() function defines these commands. |
| 309 |
| 310 Toolchain overview |
| 311 |
| 312 You can have more than one toolchain in use at once in a build and a target |
| 313 can exist simultaneously in multiple toolchains. A build file is executed |
| 314 once for each toolchain it is referenced in so the GN code can vary all |
| 315 parameters of each target (or which targets exist) on a per-toolchain basis. |
| 316 |
| 317 When you have a simple build with only one toolchain, the build config file |
| 318 is loaded only once at the beginning of the build. It must call |
| 319 set_default_toolchain() (see "gn help set_default_toolchain") to tell GN the |
| 320 label of the toolchain definition to use. The "toolchain_args" section of the |
| 321 toolchain definition is ignored. |
| 322 |
| 323 When a target has a dependency on a target using different toolchain (see "gn |
| 324 help labels" for how to specify this), GN will start a build using that |
| 325 secondary toolchain to resolve the target. GN will load the build config file |
| 326 with the build arguements overridden as specified in the toolchain_args. |
| 327 Because the default toolchain is already known, calls to |
| 328 set_default_toolchain() are ignored. |
| 329 |
| 330 To load a file in an alternate toolchain, GN does the following: |
| 331 |
| 332 1. Loads the file with the toolchain definition in it (as determined by the |
| 333 toolchain label). |
| 334 2. Re-runs the master build configuration file, applying the arguments |
| 335 specified by the toolchain_args section of the toolchain definition. |
| 336 3. Loads the destination build file in the context of the configuration file |
| 337 in the previous step. |
| 338 |
| 339 The toolchain configuration is two-way. In the default toolchain (i.e. the |
| 340 main build target) the configuration flows from the build config file to the |
| 341 toolchain. The build config file looks at the state of the build (OS type, |
| 342 CPU architecture, etc.) and decides which toolchain to use (via |
| 343 set_default_toolchain()). In secondary toolchains, the configuration flows |
| 344 from the toolchain to the build config file: the "toolchain_args" in the |
| 345 toolchain definition specifies the arguments to re-invoke the build. |
309 | 346 |
310 Functions and variables | 347 Functions and variables |
311 | 348 |
312 tool() | 349 tool() |
313 The tool() function call specifies the commands commands to run for a given | 350 The tool() function call specifies the commands commands to run for a given |
314 step. See "gn help tool". | 351 step. See "gn help tool". |
315 | 352 |
316 toolchain_args | 353 toolchain_args |
317 Overrides for build arguments to pass to the toolchain when invoking it. | 354 Overrides for build arguments to pass to the toolchain when invoking it. |
318 This is a variable of type "scope" where the variable names correspond to | 355 This is a variable of type "scope" where the variable names correspond to |
(...skipping 18 matching lines...) Expand all Loading... |
337 any target in the toolchain is compiled. To avoid circular dependencies | 374 any target in the toolchain is compiled. To avoid circular dependencies |
338 these must be targets defined in another toolchain. | 375 these must be targets defined in another toolchain. |
339 | 376 |
340 This is expressed as a list of targets, and generally these targets will | 377 This is expressed as a list of targets, and generally these targets will |
341 always specify a toolchain: | 378 always specify a toolchain: |
342 deps = [ "//foo/bar:baz(//build/toolchain:bootstrap)" ] | 379 deps = [ "//foo/bar:baz(//build/toolchain:bootstrap)" ] |
343 | 380 |
344 This concept is somewhat inefficient to express in Ninja (it requires a lot | 381 This concept is somewhat inefficient to express in Ninja (it requires a lot |
345 of duplicate of rules) so should only be used when absolutely necessary. | 382 of duplicate of rules) so should only be used when absolutely necessary. |
346 | 383 |
347 Invoking targets in toolchains | 384 Example of defining a toolchain |
348 | 385 |
349 By default, when a target depends on another, there is an implicit toolchain | 386 toolchain("32") { |
350 label that is inherited, so the dependee has the same one as the dependent. | |
351 | |
352 You can override this and refer to any other toolchain by explicitly | |
353 labeling the toolchain to use. For example: | |
354 data_deps = [ "//plugins:mine(//toolchains:plugin_toolchain)" ] | |
355 The string "//build/toolchains:plugin_toolchain" is a label that identifies | |
356 the toolchain declaration for compiling the sources. | |
357 | |
358 To load a file in an alternate toolchain, GN does the following: | |
359 | |
360 1. Loads the file with the toolchain definition in it (as determined by the | |
361 toolchain label). | |
362 2. Re-runs the master build configuration file, applying the arguments | |
363 specified by the toolchain_args section of the toolchain definition. | |
364 3. Loads the destination build file in the context of the configuration file | |
365 in the previous step. | |
366 | |
367 Example | |
368 | |
369 toolchain("plugin_toolchain") { | |
370 tool("cc") { | 387 tool("cc") { |
371 command = "gcc {{source}}" | 388 command = "gcc {{source}}" |
372 ... | 389 ... |
373 } | 390 } |
374 | 391 |
375 toolchain_args = { | 392 toolchain_args = { |
376 is_plugin = true | 393 use_doom_melon = true # Doom melon always required for 32-bit builds. |
377 is_32bit = true | 394 current_cpu = "x86" |
378 is_64bit = false | |
379 } | 395 } |
380 }; | 396 } |
| 397 |
| 398 toolchain("64") { |
| 399 tool("cc") { |
| 400 command = "gcc {{source}}" |
| 401 ... |
| 402 } |
| 403 |
| 404 toolchain_args = { |
| 405 # use_doom_melon is not overridden here, it will take the default. |
| 406 current_cpu = "x64" |
| 407 } |
| 408 } |
| 409 |
| 410 Example of cross-toolchain dependencies |
| 411 |
| 412 If a 64-bit target wants to depend on a 32-bit binary, it would specify a |
| 413 dependency using data_deps (data deps are like deps that are only needed at |
| 414 runtime and aren't linked, since you can't link a 32-bit and a 64-bit |
| 415 library). |
| 416 |
| 417 executable("my_program") { |
| 418 ... |
| 419 if (target_cpu == "x64") { |
| 420 # The 64-bit build needs this 32-bit helper. |
| 421 data_deps = [ ":helper(//toolchains:32)" ] |
| 422 } |
| 423 } |
| 424 |
| 425 if (target_cpu == "x86") { |
| 426 # Our helper library is only compiled in 32-bits. |
| 427 shared_library("helper") { |
| 428 ... |
| 429 } |
| 430 } |
381 )*"; | 431 )*"; |
382 | 432 |
383 Value RunToolchain(Scope* scope, | 433 Value RunToolchain(Scope* scope, |
384 const FunctionCallNode* function, | 434 const FunctionCallNode* function, |
385 const std::vector<Value>& args, | 435 const std::vector<Value>& args, |
386 BlockNode* block, | 436 BlockNode* block, |
387 Err* err) { | 437 Err* err) { |
388 NonNestableBlock non_nestable(scope, function, "toolchain"); | 438 NonNestableBlock non_nestable(scope, function, "toolchain"); |
389 if (!non_nestable.Enter(err)) | 439 if (!non_nestable.Enter(err)) |
390 return Value(); | 440 return Value(); |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1031 | 1081 |
1032 // Make sure there weren't any vars set in this tool that were unused. | 1082 // Make sure there weren't any vars set in this tool that were unused. |
1033 if (!block_scope.CheckForUnusedVars(err)) | 1083 if (!block_scope.CheckForUnusedVars(err)) |
1034 return Value(); | 1084 return Value(); |
1035 | 1085 |
1036 toolchain->SetTool(tool_type, std::move(tool)); | 1086 toolchain->SetTool(tool_type, std::move(tool)); |
1037 return Value(); | 1087 return Value(); |
1038 } | 1088 } |
1039 | 1089 |
1040 } // namespace functions | 1090 } // namespace functions |
OLD | NEW |