| 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 |