|  | Project: /_project.yaml | 
|  | Book: /_book.yaml | 
|  |  | 
|  | # Toolchains | 
|  |  | 
|  | {% include "_buttons.html" %} | 
|  |  | 
|  | This page describes the toolchain framework, which is a way for rule authors to | 
|  | decouple their rule logic from platform-based selection of tools. It is | 
|  | recommended to read the [rules](/extending/rules) and [platforms](/extending/platforms) | 
|  | pages before continuing. This page covers why toolchains are needed, how to | 
|  | define and use them, and how Bazel selects an appropriate toolchain based on | 
|  | platform constraints. | 
|  |  | 
|  | ## Motivation {:#motivation} | 
|  |  | 
|  | Let's first look at the problem toolchains are designed to solve. Suppose you | 
|  | are writing rules to support the "bar" programming language. Your `bar_binary` | 
|  | rule would compile `*.bar` files using the `barc` compiler, a tool that itself | 
|  | is built as another target in your workspace. Since users who write `bar_binary` | 
|  | targets shouldn't have to specify a dependency on the compiler, you make it an | 
|  | implicit dependency by adding it to the rule definition as a private attribute. | 
|  |  | 
|  | ```python | 
|  | bar_binary = rule( | 
|  | implementation = _bar_binary_impl, | 
|  | attrs = { | 
|  | "srcs": attr.label_list(allow_files = True), | 
|  | ... | 
|  | "_compiler": attr.label( | 
|  | default = "//bar_tools:barc_linux",  # the compiler running on linux | 
|  | providers = [BarcInfo], | 
|  | ), | 
|  | }, | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | `//bar_tools:barc_linux` is now a dependency of every `bar_binary` target, so | 
|  | it'll be built before any `bar_binary` target. It can be accessed by the rule's | 
|  | implementation function just like any other attribute: | 
|  |  | 
|  | ```python | 
|  | BarcInfo = provider( | 
|  | doc = "Information about how to invoke the barc compiler.", | 
|  | # In the real world, compiler_path and system_lib might hold File objects, | 
|  | # but for simplicity they are strings for this example. arch_flags is a list | 
|  | # of strings. | 
|  | fields = ["compiler_path", "system_lib", "arch_flags"], | 
|  | ) | 
|  |  | 
|  | def _bar_binary_impl(ctx): | 
|  | ... | 
|  | info = ctx.attr._compiler[BarcInfo] | 
|  | command = "%s -l %s %s" % ( | 
|  | info.compiler_path, | 
|  | info.system_lib, | 
|  | " ".join(info.arch_flags), | 
|  | ) | 
|  | ... | 
|  | ``` | 
|  |  | 
|  | The issue here is that the compiler's label is hardcoded into `bar_binary`, yet | 
|  | different targets may need different compilers depending on what platform they | 
|  | are being built for and what platform they are being built on -- called the | 
|  | *target platform* and *execution platform*, respectively. Furthermore, the rule | 
|  | author does not necessarily even know all the available tools and platforms, so | 
|  | it is not feasible to hardcode them in the rule's definition. | 
|  |  | 
|  | A less-than-ideal solution would be to shift the burden onto users, by making | 
|  | the `_compiler` attribute non-private. Then individual targets could be | 
|  | hardcoded to build for one platform or another. | 
|  |  | 
|  | ```python | 
|  | bar_binary( | 
|  | name = "myprog_on_linux", | 
|  | srcs = ["mysrc.bar"], | 
|  | compiler = "//bar_tools:barc_linux", | 
|  | ) | 
|  |  | 
|  | bar_binary( | 
|  | name = "myprog_on_windows", | 
|  | srcs = ["mysrc.bar"], | 
|  | compiler = "//bar_tools:barc_windows", | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | You can improve on this solution by using `select` to choose the `compiler` | 
|  | [based on the platform](/docs/configurable-attributes): | 
|  |  | 
|  | ```python | 
|  | config_setting( | 
|  | name = "on_linux", | 
|  | constraint_values = [ | 
|  | "@platforms//os:linux", | 
|  | ], | 
|  | ) | 
|  |  | 
|  | config_setting( | 
|  | name = "on_windows", | 
|  | constraint_values = [ | 
|  | "@platforms//os:windows", | 
|  | ], | 
|  | ) | 
|  |  | 
|  | bar_binary( | 
|  | name = "myprog", | 
|  | srcs = ["mysrc.bar"], | 
|  | compiler = select({ | 
|  | ":on_linux": "//bar_tools:barc_linux", | 
|  | ":on_windows": "//bar_tools:barc_windows", | 
|  | }), | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | But this is tedious and a bit much to ask of every single `bar_binary` user. | 
|  | If this style is not used consistently throughout the workspace, it leads to | 
|  | builds that work fine on a single platform but fail when extended to | 
|  | multi-platform scenarios. It also does not address the problem of adding support | 
|  | for new platforms and compilers without modifying existing rules or targets. | 
|  |  | 
|  | The toolchain framework solves this problem by adding an extra level of | 
|  | indirection. Essentially, you declare that your rule has an abstract dependency | 
|  | on *some* member of a family of targets (a toolchain type), and Bazel | 
|  | automatically resolves this to a particular target (a toolchain) based on the | 
|  | applicable platform constraints. Neither the rule author nor the target author | 
|  | need know the complete set of available platforms and toolchains. | 
|  |  | 
|  | ## Writing rules that use toolchains {:#writing-rules-toolchains} | 
|  |  | 
|  | Under the toolchain framework, instead of having rules depend directly on tools, | 
|  | they instead depend on *toolchain types*. A toolchain type is a simple target | 
|  | that represents a class of tools that serve the same role for different | 
|  | platforms. For instance, you can declare a type that represents the bar | 
|  | compiler: | 
|  |  | 
|  | ```python | 
|  | # By convention, toolchain_type targets are named "toolchain_type" and | 
|  | # distinguished by their package path. So the full path for this would be | 
|  | # //bar_tools:toolchain_type. | 
|  | toolchain_type(name = "toolchain_type") | 
|  | ``` | 
|  |  | 
|  | The rule definition in the previous section is modified so that instead of | 
|  | taking in the compiler as an attribute, it declares that it consumes a | 
|  | `//bar_tools:toolchain_type` toolchain. | 
|  |  | 
|  | ```python | 
|  | bar_binary = rule( | 
|  | implementation = _bar_binary_impl, | 
|  | attrs = { | 
|  | "srcs": attr.label_list(allow_files = True), | 
|  | ... | 
|  | # No `_compiler` attribute anymore. | 
|  | }, | 
|  | toolchains = ["//bar_tools:toolchain_type"], | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | The implementation function now accesses this dependency under `ctx.toolchains` | 
|  | instead of `ctx.attr`, using the toolchain type as the key. | 
|  |  | 
|  | ```python | 
|  | def _bar_binary_impl(ctx): | 
|  | ... | 
|  | info = ctx.toolchains["//bar_tools:toolchain_type"].barcinfo | 
|  | # The rest is unchanged. | 
|  | command = "%s -l %s %s" % ( | 
|  | info.compiler_path, | 
|  | info.system_lib, | 
|  | " ".join(info.arch_flags), | 
|  | ) | 
|  | ... | 
|  | ``` | 
|  |  | 
|  | `ctx.toolchains["//bar_tools:toolchain_type"]` returns the | 
|  | [`ToolchainInfo` provider](/rules/lib/toplevel/platform_common#ToolchainInfo) | 
|  | of whatever target Bazel resolved the toolchain dependency to. The fields of the | 
|  | `ToolchainInfo` object are set by the underlying tool's rule; in the next | 
|  | section, this rule is defined such that there is a `barcinfo` field that wraps | 
|  | a `BarcInfo` object. | 
|  |  | 
|  | Bazel's procedure for resolving toolchains to targets is described | 
|  | [below](#toolchain-resolution). Only the resolved toolchain target is actually | 
|  | made a dependency of the `bar_binary` target, not the whole space of candidate | 
|  | toolchains. | 
|  |  | 
|  | ### Mandatory and Optional Toolchains {:#optional-toolchains} | 
|  |  | 
|  | By default, when a rule expresses a toolchain type dependency using a bare label | 
|  | (as shown above), the toolchain type is considered to be **mandatory**. If Bazel | 
|  | is unable to find a matching toolchain (see | 
|  | [Toolchain resolution](#toolchain-resolution) below) for a mandatory toolchain | 
|  | type, this is an error and analysis halts. | 
|  |  | 
|  | It is possible instead to declare an **optional** toolchain type dependency, as | 
|  | follows: | 
|  |  | 
|  | ```python | 
|  | bar_binary = rule( | 
|  | ... | 
|  | toolchains = [ | 
|  | config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = False), | 
|  | ], | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | When an optional toolchain type cannot be resolved, analysis continues, and the | 
|  | result of `ctx.toolchains["//bar_tools:toolchain_type"]` is `None`. | 
|  |  | 
|  | The [`config_common.toolchain_type`](/rules/lib/toplevel/config_common#toolchain_type) | 
|  | function defaults to mandatory. | 
|  |  | 
|  | The following forms can be used: | 
|  |  | 
|  | -  Mandatory toolchain types: | 
|  | -  `toolchains = ["//bar_tools:toolchain_type"]` | 
|  | -  `toolchains = [config_common.toolchain_type("//bar_tools:toolchain_type")]` | 
|  | -  `toolchains = [config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = True)]` | 
|  | - Optional toolchain types: | 
|  | -  `toolchains = [config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = False)]` | 
|  |  | 
|  | ```python | 
|  | bar_binary = rule( | 
|  | ... | 
|  | toolchains = [ | 
|  | "//foo_tools:toolchain_type", | 
|  | config_common.toolchain_type("//bar_tools:toolchain_type", mandatory = False), | 
|  | ], | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | You can mix and match forms in the same rule, also. However, if the same | 
|  | toolchain type is listed multiple times, it will take the most strict version, | 
|  | where mandatory is more strict than optional. | 
|  |  | 
|  | ### Writing aspects that use toolchains {:#writing-aspects-toolchains} | 
|  |  | 
|  | Aspects have access to the same toolchain API as rules: you can define required | 
|  | toolchain types, access toolchains via the context, and use them to generate new | 
|  | actions using the toolchain. | 
|  |  | 
|  | ```py | 
|  | bar_aspect = aspect( | 
|  | implementation = _bar_aspect_impl, | 
|  | attrs = {}, | 
|  | toolchains = ['//bar_tools:toolchain_type'], | 
|  | ) | 
|  |  | 
|  | def _bar_aspect_impl(target, ctx): | 
|  | toolchain = ctx.toolchains['//bar_tools:toolchain_type'] | 
|  | # Use the toolchain provider like in a rule. | 
|  | return [] | 
|  | ``` | 
|  |  | 
|  | ## Defining toolchains {:#toolchain-definitions} | 
|  |  | 
|  | To define some toolchains for a given toolchain type, you need three things: | 
|  |  | 
|  | 1. A language-specific rule representing the kind of tool or tool suite. By | 
|  | convention this rule's name is suffixed with "\_toolchain". | 
|  |  | 
|  | 1.  **Note:** The `\_toolchain` rule cannot create any build actions. | 
|  | Rather, it collects artifacts from other rules and forwards them to the | 
|  | rule that uses the toolchain. That rule is responsible for creating all | 
|  | build actions. | 
|  |  | 
|  | 2. Several targets of this rule type, representing versions of the tool or tool | 
|  | suite for different platforms. | 
|  |  | 
|  | 3. For each such target, an associated target of the generic | 
|  | [`toolchain`](/reference/be/platforms-and-toolchains#toolchain) | 
|  | rule, to provide metadata used by the toolchain framework. This `toolchain` | 
|  | target also refers to the `toolchain_type` associated with this toolchain. | 
|  | This means that a given `_toolchain` rule could be associated with any | 
|  | `toolchain_type`, and that only in a `toolchain` instance that uses | 
|  | this `_toolchain` rule that the rule is associated with a `toolchain_type`. | 
|  |  | 
|  | For our running example, here's a definition for a `bar_toolchain` rule. Our | 
|  | example has only a compiler, but other tools such as a linker could also be | 
|  | grouped underneath it. | 
|  |  | 
|  | ```python | 
|  | def _bar_toolchain_impl(ctx): | 
|  | toolchain_info = platform_common.ToolchainInfo( | 
|  | barcinfo = BarcInfo( | 
|  | compiler_path = ctx.attr.compiler_path, | 
|  | system_lib = ctx.attr.system_lib, | 
|  | arch_flags = ctx.attr.arch_flags, | 
|  | ), | 
|  | ) | 
|  | return [toolchain_info] | 
|  |  | 
|  | bar_toolchain = rule( | 
|  | implementation = _bar_toolchain_impl, | 
|  | attrs = { | 
|  | "compiler_path": attr.string(), | 
|  | "system_lib": attr.string(), | 
|  | "arch_flags": attr.string_list(), | 
|  | }, | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | The rule must return a `ToolchainInfo` provider, which becomes the object that | 
|  | the consuming rule retrieves using `ctx.toolchains` and the label of the | 
|  | toolchain type. `ToolchainInfo`, like `struct`, can hold arbitrary field-value | 
|  | pairs. The specification of exactly what fields are added to the `ToolchainInfo` | 
|  | should be clearly documented at the toolchain type. In this example, the values | 
|  | return wrapped in a `BarcInfo` object to reuse the schema defined above; this | 
|  | style may be useful for validation and code reuse. | 
|  |  | 
|  | Now you can define targets for specific `barc` compilers. | 
|  |  | 
|  | ```python | 
|  | bar_toolchain( | 
|  | name = "barc_linux", | 
|  | arch_flags = [ | 
|  | "--arch=Linux", | 
|  | "--debug_everything", | 
|  | ], | 
|  | compiler_path = "/path/to/barc/on/linux", | 
|  | system_lib = "/usr/lib/libbarc.so", | 
|  | ) | 
|  |  | 
|  | bar_toolchain( | 
|  | name = "barc_windows", | 
|  | arch_flags = [ | 
|  | "--arch=Windows", | 
|  | # Different flags, no debug support on windows. | 
|  | ], | 
|  | compiler_path = "C:\\path\\on\\windows\\barc.exe", | 
|  | system_lib = "C:\\path\\on\\windows\\barclib.dll", | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | Finally, you create `toolchain` definitions for the two `bar_toolchain` targets. | 
|  | These definitions link the language-specific targets to the toolchain type and | 
|  | provide the constraint information that tells Bazel when the toolchain is | 
|  | appropriate for a given platform. | 
|  |  | 
|  | ```python | 
|  | toolchain( | 
|  | name = "barc_linux_toolchain", | 
|  | exec_compatible_with = [ | 
|  | "@platforms//os:linux", | 
|  | "@platforms//cpu:x86_64", | 
|  | ], | 
|  | target_compatible_with = [ | 
|  | "@platforms//os:linux", | 
|  | "@platforms//cpu:x86_64", | 
|  | ], | 
|  | toolchain = ":barc_linux", | 
|  | toolchain_type = ":toolchain_type", | 
|  | ) | 
|  |  | 
|  | toolchain( | 
|  | name = "barc_windows_toolchain", | 
|  | exec_compatible_with = [ | 
|  | "@platforms//os:windows", | 
|  | "@platforms//cpu:x86_64", | 
|  | ], | 
|  | target_compatible_with = [ | 
|  | "@platforms//os:windows", | 
|  | "@platforms//cpu:x86_64", | 
|  | ], | 
|  | toolchain = ":barc_windows", | 
|  | toolchain_type = ":toolchain_type", | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | The use of relative path syntax above suggests these definitions are all in the | 
|  | same package, but there's no reason the toolchain type, language-specific | 
|  | toolchain targets, and `toolchain` definition targets can't all be in separate | 
|  | packages. | 
|  |  | 
|  | See the [`go_toolchain`](https://github.com/bazelbuild/rules_go/blob/master/go/private/go_toolchain.bzl){: .external} | 
|  | for a real-world example. | 
|  |  | 
|  | ### Toolchains and configurations | 
|  |  | 
|  | An important question for rule authors is, when a `bar_toolchain` target is | 
|  | analyzed, what [configuration](/reference/glossary#configuration) does it see, and what transitions | 
|  | should be used for dependencies? The example above uses string attributes, but | 
|  | what would happen for a more complicated toolchain that depends on other targets | 
|  | in the Bazel repository? | 
|  |  | 
|  | Let's see a more complex version of `bar_toolchain`: | 
|  |  | 
|  | ```python | 
|  | def _bar_toolchain_impl(ctx): | 
|  | # The implementation is mostly the same as above, so skipping. | 
|  | pass | 
|  |  | 
|  | bar_toolchain = rule( | 
|  | implementation = _bar_toolchain_impl, | 
|  | attrs = { | 
|  | "compiler": attr.label( | 
|  | executable = True, | 
|  | mandatory = True, | 
|  | cfg = "exec", | 
|  | ), | 
|  | "system_lib": attr.label( | 
|  | mandatory = True, | 
|  | cfg = "target", | 
|  | ), | 
|  | "arch_flags": attr.string_list(), | 
|  | }, | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | The use of [`attr.label`](/rules/lib/toplevel/attr#label) is the same as for a standard rule, | 
|  | but the meaning of the `cfg` parameter is slightly different. | 
|  |  | 
|  | The dependency from a target (called the "parent") to a toolchain via toolchain | 
|  | resolution uses a special configuration transition called the "toolchain | 
|  | transition". The toolchain transition keeps the configuration the same, except | 
|  | that it forces the execution platform to be the same for the toolchain as for | 
|  | the parent (otherwise, toolchain resolution for the toolchain could pick any | 
|  | execution platform, and wouldn't necessarily be the same as for parent). This | 
|  | allows any `exec` dependencies of the toolchain to also be executable for the | 
|  | parent's build actions. Any of the toolchain's dependencies which use `cfg = | 
|  | "target"` (or which don't specify `cfg`, since "target" is the default) are | 
|  | built for the same target platform as the parent. This allows toolchain rules to | 
|  | contribute both libraries (the `system_lib` attribute above) and tools (the | 
|  | `compiler` attribute) to the build rules which need them. The system libraries | 
|  | are linked into the final artifact, and so need to be built for the same | 
|  | platform, whereas the compiler is a tool invoked during the build, and needs to | 
|  | be able to run on the execution platform. | 
|  |  | 
|  | ## Registering and building with toolchains {:#registering-building-toolchains} | 
|  |  | 
|  | At this point all the building blocks are assembled, and you just need to make | 
|  | the toolchains available to Bazel's resolution procedure. This is done by | 
|  | registering the toolchain, either in a `MODULE.bazel` file using | 
|  | `register_toolchains()`, or by passing the toolchains' labels on the command | 
|  | line using the `--extra_toolchains` flag. | 
|  |  | 
|  | ```python | 
|  | register_toolchains( | 
|  | "//bar_tools:barc_linux_toolchain", | 
|  | "//bar_tools:barc_windows_toolchain", | 
|  | # Target patterns are also permitted, so you could have also written: | 
|  | # "//bar_tools:all", | 
|  | # or even | 
|  | # "//bar_tools/...", | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | When using target patterns to register toolchains, the order in which the | 
|  | individual toolchains are registered is determined by the following rules: | 
|  |  | 
|  | * The toolchains defined in a subpackage of a package are registered before the | 
|  | toolchains defined in the package itself. | 
|  | * Within a package, toolchains are registered in the lexicographical order of | 
|  | their names. | 
|  |  | 
|  | Now when you build a target that depends on a toolchain type, an appropriate | 
|  | toolchain will be selected based on the target and execution platforms. | 
|  |  | 
|  | ```python | 
|  | # my_pkg/BUILD | 
|  |  | 
|  | platform( | 
|  | name = "my_target_platform", | 
|  | constraint_values = [ | 
|  | "@platforms//os:linux", | 
|  | ], | 
|  | ) | 
|  |  | 
|  | bar_binary( | 
|  | name = "my_bar_binary", | 
|  | ... | 
|  | ) | 
|  | ``` | 
|  |  | 
|  | ```sh | 
|  | bazel build //my_pkg:my_bar_binary --platforms=//my_pkg:my_target_platform | 
|  | ``` | 
|  |  | 
|  | Bazel will see that `//my_pkg:my_bar_binary` is being built with a platform that | 
|  | has `@platforms//os:linux` and therefore resolve the | 
|  | `//bar_tools:toolchain_type` reference to `//bar_tools:barc_linux_toolchain`. | 
|  | This will end up building `//bar_tools:barc_linux` but not | 
|  | `//bar_tools:barc_windows`. | 
|  |  | 
|  | ## Toolchain resolution {:#toolchain-resolution} | 
|  |  | 
|  | Note: [Some Bazel rules](/concepts/platforms#status) do not yet support | 
|  | toolchain resolution. | 
|  |  | 
|  | For each target that uses toolchains, Bazel's toolchain resolution procedure | 
|  | determines the target's concrete toolchain dependencies. The procedure takes as | 
|  | input a set of required toolchain types, the target platform, the list of | 
|  | available execution platforms, and the list of available toolchains. Its outputs | 
|  | are a selected toolchain for each toolchain type as well as a selected execution | 
|  | platform for the current target. | 
|  |  | 
|  | The available execution platforms and toolchains are gathered from the | 
|  | external dependency graph via | 
|  | [`register_execution_platforms`](/rules/lib/globals/module#register_execution_platforms) | 
|  | and | 
|  | [`register_toolchains`](/rules/lib/globals/module#register_toolchains) calls in | 
|  | `MODULE.bazel` files. | 
|  | Additional execution platforms and toolchains may also be specified on the | 
|  | command line via | 
|  | [`--extra_execution_platforms`](/reference/command-line-reference#flag--extra_execution_platforms) | 
|  | and | 
|  | [`--extra_toolchains`](/reference/command-line-reference#flag--extra_toolchains). | 
|  | The host platform is automatically included as an available execution platform. | 
|  | Available platforms and toolchains are tracked as ordered lists for determinism, | 
|  | with preference given to earlier items in the list. | 
|  |  | 
|  | The set of available toolchains, in priority order, is created from | 
|  | `--extra_toolchains` and `register_toolchains`: | 
|  |  | 
|  | 1. Toolchains registered using `--extra_toolchains` are added first. (Within | 
|  | these, the **last** toolchain has highest priority.) | 
|  | 2. Toolchains registered using `register_toolchains` in the transitive external | 
|  | dependency graph, in the following order: (Within these, the **first** | 
|  | mentioned toolchain has highest priority.) | 
|  | 1. Toolchains registered by the root module (as in, the `MODULE.bazel` at the | 
|  | workspace root); | 
|  | 2. Toolchains registered in the user's `WORKSPACE` file, including in any | 
|  | macros invoked from there; | 
|  | 3. Toolchains registered by non-root modules (as in, dependencies specified by | 
|  | the root module, and their dependencies, and so forth); | 
|  | 4. Toolchains registered in the "WORKSPACE suffix"; this is only used by | 
|  | certain native rules bundled with the Bazel installation. | 
|  |  | 
|  | **NOTE:** [Pseudo-targets like `:all`, `:*`, and | 
|  | `/...`](/run/build#specifying-build-targets) are ordered by Bazel's package | 
|  | loading mechanism, which uses a lexicographic ordering. | 
|  |  | 
|  | The resolution steps are as follows. | 
|  |  | 
|  | 1. A `target_compatible_with` or `exec_compatible_with` clause *matches* a | 
|  | platform if, for each `constraint_value` in its list, the platform also has | 
|  | that `constraint_value` (either explicitly or as a default). | 
|  |  | 
|  | If the platform has `constraint_value`s from `constraint_setting`s not | 
|  | referenced by the clause, these do not affect matching. | 
|  |  | 
|  | 1. If the target being built specifies the | 
|  | [`exec_compatible_with` attribute](/reference/be/common-definitions#common.exec_compatible_with) | 
|  | (or its rule definition specifies the | 
|  | [`exec_compatible_with` argument](/rules/lib/globals/bzl#rule.exec_compatible_with)), | 
|  | the list of available execution platforms is filtered to remove | 
|  | any that do not match the execution constraints. | 
|  |  | 
|  | 1. The list of available toolchains is filtered to remove any toolchains | 
|  | specifying `target_settings` that don't match the current configuration. | 
|  |  | 
|  | 1. For each available execution platform, you associate each toolchain type with | 
|  | the first available toolchain, if any, that is compatible with this execution | 
|  | platform and the target platform. | 
|  |  | 
|  | 1. Any execution platform that failed to find a compatible mandatory toolchain | 
|  | for one of its toolchain types is ruled out. Of the remaining platforms, the | 
|  | first one becomes the current target's execution platform, and its associated | 
|  | toolchains (if any) become dependencies of the target. | 
|  |  | 
|  | The chosen execution platform is used to run all actions that the target | 
|  | generates. | 
|  |  | 
|  | In cases where the same target can be built in multiple configurations (such as | 
|  | for different CPUs) within the same build, the resolution procedure is applied | 
|  | independently to each version of the target. | 
|  |  | 
|  | If the rule uses [execution groups](/extending/exec-groups), each execution | 
|  | group performs toolchain resolution separately, and each has its own execution | 
|  | platform and toolchains. | 
|  |  | 
|  | ## Debugging toolchains {:#debugging-toolchains} | 
|  |  | 
|  | If you are adding toolchain support to an existing rule, use the | 
|  | `--toolchain_resolution_debug=regex` flag. During toolchain resolution, the flag | 
|  | provides verbose output for toolchain types or target names that match the regex variable. You | 
|  | can use `.*` to output all information. Bazel will output names of toolchains it | 
|  | checks and skips during the resolution process. | 
|  |  | 
|  | If you'd like to see which [`cquery`](/query/cquery) dependencies are from toolchain | 
|  | resolution, use `cquery`'s [`--transitions`](/query/cquery#transitions) flag: | 
|  |  | 
|  | ``` | 
|  | # Find all direct dependencies of //cc:my_cc_lib. This includes explicitly | 
|  | # declared dependencies, implicit dependencies, and toolchain dependencies. | 
|  | $ bazel cquery 'deps(//cc:my_cc_lib, 1)' | 
|  | //cc:my_cc_lib (96d6638) | 
|  | @bazel_tools//tools/cpp:toolchain (96d6638) | 
|  | @bazel_tools//tools/def_parser:def_parser (HOST) | 
|  | //cc:my_cc_dep (96d6638) | 
|  | @local_config_platform//:host (96d6638) | 
|  | @bazel_tools//tools/cpp:toolchain_type (96d6638) | 
|  | //:default_host_platform (96d6638) | 
|  | @local_config_cc//:cc-compiler-k8 (HOST) | 
|  | //cc:my_cc_lib.cc (null) | 
|  | @bazel_tools//tools/cpp:grep-includes (HOST) | 
|  |  | 
|  | # Which of these are from toolchain resolution? | 
|  | $ bazel cquery 'deps(//cc:my_cc_lib, 1)' --transitions=lite | grep "toolchain dependency" | 
|  | [toolchain dependency]#@local_config_cc//:cc-compiler-k8#HostTransition -> b6df211 | 
|  | ``` |