Source: BUILD.bazel
The following toolchains are declared:
Default toolchains, named {target_os}_{target_cpu}_clang_toolchain
, are the fallback toolchains when a C toolchain is requested without any version information.
These toolchains are marked “target_compatible_with”:
@platforms//os:{target_os}
@platforms//cpu:{target_cpu}
These toolchains are marked “exec_compatible_with”:
@platforms//os:linux
@platforms//cpu:x86_64
These toolchains have cc_toolchain.compiler
set to CLANG_VERSION
from @kernel_toolchain_info//:dict.bzl
.
Versioned toolchains, named {version}_{target_os}_{target_cpu}_clang_toolchain
, are the toolchains bearing extra version information.
These toolchains are marked “target_compatible_with”:
@platforms//os:{target_os}
@platforms//cpu:{target_cpu}
//prebuilts/clang/host/linux-x86/kleaf:{version}
These toolchains are marked “exec_compatible_with”:
@platforms//os:linux
@platforms//cpu:x86_64
//prebuilts/clang/host/linux-x86/kleaf:{version}
These toolchains have cc_toolchain.compiler
set to the corresponding {version}
.
Source: user_clang_toolchain_repository.bzl
User toolchains, @kleaf_user_clang_toolchain//:user_{target_os}_{target_cpu}_clang_toolchain
, are the toolchains provided by the user from the command line.
These toolchains are marked “target_compatible_with”:
@platforms//os:{target_os}
@platforms//cpu:{target_cpu}
These toolchains are marked “exec_compatible_with”:
@platforms//os:linux
@platforms//cpu:x86_64
These toolchains have cc_toolchain.compiler
set to "kleaf_user_clang_toolchain_skip_version_check"
(an implementation detail).
Toolchains are registered in the following order:
--user_clang_toolchain
is set, the user toolchains are registered. Otherwise, fake user toolchains are registered. (source)The following assumes that the reader is familar with Bazel's toolchain resolution process.
Each toolchain registered through Bazel can specify a list of compatible constraint values with exec_compatible_with
and target_compatible_with
. A toolchain matches a platform when the toolchain’s constraint values are a SUBSET of the platform's constraint values.
To determine the toolchain for a build target, Bazel does the following.
exec
configuration (e.g. when building as one of the tools
of a genrule
, or as a dependency with cfg="exec"
, the platform of the build target is the execution platform, subject to transitions.For a build without any flags or transitions, the execution platform is @local_config_platform//:host
. For Kleaf, this usually contains two constraint values: (linux
, x86_64
).
For a build without any flags or transitions, Bazel uses “single-platform builds” by default, so the target platform is the same as the execution platform with two constraint values: (linux
, x86_64
).
In Kleaf, if a target is built with --config=android_{cpu}
, or is wrapped in an android_filegroup
with a given cpu
, the target platform has two constraint values (android
, {cpu}
).
For a build without any flags or transitions, the platform of the build target has two constrants: (linux
, x86_64
). The toolchains are looked up in the following order:
--user_clang_toolchain
is set, user_linux_x86_64_clang_toolchain
is returned because its constraint values (linux
, x86_64
) are a subset of the platform's constraint values (linux
, x86_64
). Otherwise, if --user_clang_toolchain
is not set, Bazel continues checking the following toolchains.{version}
, {target_os}
, {target_cpu}
) are not a subset of the platform's constraint values (linux
, x86_64
).linux_x86_64_clang_toolchain
is returned because its constraint values (linux
, x86_64
) are a subset of the platform's constraint values (linux
, x86_64
)If a cc_*
target is built with --config=android_arm64
, the platform of the build target has two constrants: (android
, arm64
). The toolchains are looked up in the following order:
--user_clang_toolchain
is set, user_android_arm64_clang_toolchain
is returned because its constraint values (android
, arm64
) are a subset of the platform's constraint values (android
, arm64
). Otherwise, if --user_clang_toolchain
is not set, Bazel continues checking the following toolchains.{version}
, {target_os}
, {target_cpu}
) are not a subset of the platform's constraint values (android
, arm64
).android_arm64_clang_toolchain
is returned because its constraint values (android
, arm64
) are a subset of the platform's constraint values (android
, arm64
)If a cc_*
target is wrapped in an android_filegroup
target with cpu="arm64"
, when the android_filegroup
target is built, a transition is applied on the cc_*
target so its platform has constraint values (android
, arm64
). The toolchain resolution process is the same as with --config=android_arm64.
If a kernel_build
does not specify toolchain_version
:
linux
, x86_64
)android
, {target_cpu}
) where {target_cpu}
is specified in kernel_build.arch
.When kernel_toolchains
looks up the toolchains for the execution platform and the target platform, respectively, the process is similar to the one for cc_*
rules. That is:
--user_clang_toolchain
is set, the user toolchains are returned:user_linux_x86_64_clang_toolchain
is resolved for the execution platformuser_android_{target_cpu}_clang_toolchain
is resolved for the target platformlinux_x86_64_clang_toolchain
is resolved for the execution platformandroid_{target_cpu}_clang_toolchain
is resolved for the target platformThis is unusual. You are recommended to not set kernel_build.toolchain_version
to use the default toolchains.
If a kernel_build
does specify toolchain_version
:
linux
, x86_64
, {toolchain_version}
)android
, {target_cpu}
, {toolchain_version}
) where {target_cpu}
is specified in kernel_build.arch
.When kernel_toolchains
looks up the toolchains for the execution platform:
--user_clang_toolchain
is set, the user toolchain user_linux_x86_64_clang_toolchain
is returned because its constraint values (linux
, x86_64
) are a subset of the execution platform's constraint values (linux
, x86_64
, {toolchain_version}
). However, kernel_toolchains
rejects the user toolchain because the version "unknown"
does not match the declared value, kernel_build.toolchain_version
, resulting in a build error. You should delete kernel_build.toolchain_version
, and try again.--user_clang_toolchain
is not set, the matching versioned toolchain, {version}_linux_x86_64_clang_toolchain
is returned because its constraint values (linux
, x86_64
{toolchain_version}
) are a subset of the execution platform's constraint values (linux
, x86_64
, {toolchain_version}
).kernel_toolchains
rejects the default toolchain because the version does not match the declared value, kernel_build.toolchain_version
, resulting in a build error as expected.The same goes for the target platform:
--user_clang_toolchain
is set, the user toolchain user_android_{target_cpu}_clang_toolchain
is returned because its constraint values (android
, {target_cpu}
) are a subset of the target platform's constraint values (android
, {target_cpu}
, {toolchain_version}
). kernel_toolchains
accepts the user toolchain with a warning because the version of the user toolchain "kleaf_user_clang_toolchain_skip_version_check"
does not match the declared value, kernel_build.toolchain_version
.--user_clang_toolchain
is not set, the matching versioned toolchain, {version}_android_{target_cpu}_clang_toolchain
is returned because its constraint values (android
, {target_cpu}
{toolchain_version}
) are a subset of the target platform's constraint values (android
, {target_cpu}
, {toolchain_version}
).kernel_toolchains
rejects the default toolchain because the version does not match the declared value, kernel_build.toolchain_version
, resulting in a build error as expected.To use the user toolchains, the following is expected from the workspace:
KLEAF_USER_CLANG_TOOLCHAIN_PATH
, must be set to the path to the user clang toolchain. This is set by Kleaf's Bazel wrapper, bazel.py
, when --user_clang_toolchain
is set.