Merge "Replace libc++.so.1 with libc++.so" into main
diff --git a/kleaf/BUILD.bazel b/kleaf/BUILD.bazel
index bc6eca9..b17c850 100644
--- a/kleaf/BUILD.bazel
+++ b/kleaf/BUILD.bazel
@@ -17,18 +17,23 @@
"@kernel_toolchain_info//:dict.bzl",
"VARS",
)
-load(
- ":clang_toolchain.bzl",
- "android_arm64_clang_toolchain",
- "android_arm_clang_toolchain",
- "android_i386_clang_toolchain",
- "android_riscv64_clang_toolchain",
- "android_x86_64_clang_toolchain",
- "linux_x86_64_clang_toolchain",
-)
+load(":architecture_constants.bzl", "SUPPORTED_ARCHITECTURES")
+load(":clang_toolchain.bzl", "clang_toolchain")
load(":versions.bzl", "VERSIONS")
bzl_library(
+ name = "architecture_constants",
+ srcs = ["architecture_constants.bzl"],
+ visibility = ["//visibility:private"],
+)
+
+bzl_library(
+ name = "user_clang_toolchain_repository",
+ srcs = ["user_clang_toolchain_repository.bzl"],
+ visibility = ["//visibility:private"],
+)
+
+bzl_library(
name = "versions",
srcs = ["versions.bzl"],
visibility = ["//visibility:public"],
@@ -38,42 +43,24 @@
name = "register",
srcs = ["register.bzl"],
visibility = ["//visibility:public"],
- deps = [":versions"],
+ deps = [
+ ":architecture_constants",
+ ":user_clang_toolchain_repository",
+ ":versions",
+ ],
)
-# Default toolchain for cc_* rules.
+# Default toolchains.
-linux_x86_64_clang_toolchain(
- name = "linux_x86_64_clang_toolchain",
+[clang_toolchain(
+ name = "{}_{}_clang_toolchain".format(target_os, target_cpu),
+ clang_pkg = "//prebuilts/clang/host/linux-x86/clang-{}".format(VARS["CLANG_VERSION"]),
clang_version = VARS["CLANG_VERSION"],
-)
+ target_cpu = target_cpu,
+ target_os = target_os,
+) for target_os, target_cpu in SUPPORTED_ARCHITECTURES]
-android_arm64_clang_toolchain(
- name = "android_arm64_clang_toolchain",
- clang_version = VARS["CLANG_VERSION"],
-)
-
-android_arm_clang_toolchain(
- name = "android_arm_clang_toolchain",
- clang_version = VARS["CLANG_VERSION"],
-)
-
-android_i386_clang_toolchain(
- name = "android_i386_clang_toolchain",
- clang_version = VARS["CLANG_VERSION"],
-)
-
-android_x86_64_clang_toolchain(
- name = "android_x86_64_clang_toolchain",
- clang_version = VARS["CLANG_VERSION"],
-)
-
-android_riscv64_clang_toolchain(
- name = "android_riscv64_clang_toolchain",
- clang_version = VARS["CLANG_VERSION"],
-)
-
-# Extra toolchain for kernel_* rules
+# Versioned toolchains: extra toolchains when a certain version is requested.
constraint_setting(name = "clang_version")
@@ -83,38 +70,11 @@
visibility = ["//visibility:public"],
) for version in VERSIONS]
-[linux_x86_64_clang_toolchain(
- name = version + "_linux_x86_64_clang_toolchain",
+[clang_toolchain(
+ name = "{}_{}_{}_clang_toolchain".format(version, target_os, target_cpu),
+ clang_pkg = "//prebuilts/clang/host/linux-x86/clang-{}".format(version),
clang_version = version,
extra_compatible_with = [version],
-) for version in VERSIONS]
-
-[android_arm64_clang_toolchain(
- name = version + "_android_arm64_clang_toolchain",
- clang_version = version,
- extra_compatible_with = [version],
-) for version in VERSIONS]
-
-[android_arm_clang_toolchain(
- name = version + "_android_arm_clang_toolchain",
- clang_version = version,
- extra_compatible_with = [version],
-) for version in VERSIONS]
-
-[android_i386_clang_toolchain(
- name = version + "_android_i386_clang_toolchain",
- clang_version = version,
- extra_compatible_with = [version],
-) for version in VERSIONS]
-
-[android_x86_64_clang_toolchain(
- name = version + "_android_x86_64_clang_toolchain",
- clang_version = version,
- extra_compatible_with = [version],
-) for version in VERSIONS]
-
-[android_riscv64_clang_toolchain(
- name = version + "_android_riscv64_clang_toolchain",
- clang_version = version,
- extra_compatible_with = [version],
-) for version in VERSIONS]
+ target_cpu = target_cpu,
+ target_os = target_os,
+) for version in VERSIONS for target_os, target_cpu in SUPPORTED_ARCHITECTURES]
diff --git a/kleaf/README.md b/kleaf/README.md
new file mode 100644
index 0000000..62d3413
--- /dev/null
+++ b/kleaf/README.md
@@ -0,0 +1,244 @@
+# C Toolchain in Kleaf
+
+## Toolchain declaration
+
+Source: [BUILD.bazel](BUILD.bazel)
+
+The following toolchains are declared:
+
+* Default toolchains
+* Versioned toolchains
+* User toolchains, provided via command line flags
+
+### Default toolchains
+
+[Source: `BUILD.bazel`](BUILD.bazel)
+
+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":
+* the corresponding `@platforms//os:{target_os}`
+* the corresponding `@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
+
+[Source: `BUILD.bazel`](BUILD.bazel)
+
+Versioned toolchains, named
+`{version}_{target_os}_{target_cpu}_clang_toolchain`,
+are the toolchains bearing extra version information.
+
+These toolchains are marked "target_compatible_with":
+* the corresponding `@platforms//os:{target_os}`
+* the corresponding `@platforms//cpu:{target_cpu}`
+* the corresponding `//prebuilts/clang/host/linux-x86/kleaf:{version}`
+
+These toolchains are marked "exec_compatible_with":
+* `@platforms//os:linux`
+* `@platforms//cpu:x86_64`
+* the corresponding `//prebuilts/clang/host/linux-x86/kleaf:{version}`
+
+These toolchains have `cc_toolchain.compiler` set to the corresponding
+`{version}`.
+
+### User toolchains
+
+[Source: `user_clang_toolchain_repository.bzl`](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":
+* the corresponding `@platforms//os:{target_os}`
+* the corresponding `@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).
+
+## Toolchain registration
+
+Toolchains are registered in the following order:
+
+1. If `--user_clang_toolchain` is set, the user toolchains are registered.
+ Otherwise, fake user toolchains are registered.
+ ([source](register.bzl))
+2. The versioned toolchains ([source](register.bzl))
+3. The default toolchains ([source](register.bzl))
+
+## Toolchain resolution
+
+The following assumes that the reader is familar with
+[Bazel's toolchain resolution process](https://bazel.build/extending/toolchains#toolchain-resolution).
+
+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](https://bazel.build/extending/rules#target_instantiation),
+Bazel does the following.
+
+1. The platform of the build target is determined. By default, the platform of
+ of the build target is the
+ [target platform](https://bazel.build/extending/platforms), subject to
+ transitions. If the build target is built in an `exec` configuration (e.g.
+ when building as one of the
+ [`tools` of a `genrule`](https://bazel.build/reference/be/general#genrule.tools),
+ or as
+ [a dependency with `cfg="exec"`](https://bazel.build/extending/rules#configurations), the platform of the build target is the
+ [execution platform](https://bazel.build/extending/platforms), subject to
+ transitions.
+2. Bazel looks for a toolchain such that the toolchain's constraint values
+ are a **SUBSET** of the constraint values of the platform of the build
+ target.
+
+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"](https://bazel.build/extending/platforms)
+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}`).
+
+### Example: cc\_* rules
+
+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:
+
+1. If `--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.
+2. The versioned toolchains are skipped because their constraint values
+ (`{version}`, `{target_os}`, `{target_cpu}`) are not a subset of
+ the platform's constraint values (`linux`, `x86_64`).
+3. The default toolchain `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:
+
+1. If `--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.
+2. The versioned toolchains are skipped because their constraint values
+ (`{version}`, `{target_os}`, `{target_cpu}`) are not a subset of
+ the platform's constraint values (`android`, `arm64`).
+3. The default toolchain `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.`
+
+### Example: kernel\_* rules without toolchain\_version
+
+If a `kernel_build` does not specify `toolchain_version`:
+
+* Its execution platform has constraint values (`linux`, `x86_64`)
+* Its target platform has constraint values (`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](#example-cc_-rules). That is:
+
+* If `--user_clang_toolchain` is set, the user toolchains are returned:
+ * `user_linux_x86_64_clang_toolchain` is resolved for the
+ execution platform
+ * `user_android_{target_cpu}_clang_toolchain` is resolved for the
+ target platform
+* Otherwise, the default toolchains are returned:
+ * `linux_x86_64_clang_toolchain` is resolved for the
+ execution platform
+ * `android_{target_cpu}_clang_toolchain` is resolved for the
+ target platform
+
+### Example: kernel\_* rules with toolchain\_version
+
+This 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`:
+
+* Its execution platform has constraint values
+ (`linux`, `x86_64`, `{toolchain_version}`)
+* Its target platform has constraint values
+ (`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:
+
+* If `--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.
+* If `--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}`).
+* If no matching versioned toolchain is found, the default toolchain is
+ returned. However, `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:
+
+* If `--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`.
+* If `--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}`).
+* If no matching versioned toolchain is found, the default toolchain is
+ returned. However, `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.
+
+## Caveats
+
+To use the user toolchains, the following is expected from the workspace:
+
+* An environment variable, `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.
diff --git a/kleaf/architecture_constants.bzl b/kleaf/architecture_constants.bzl
new file mode 100644
index 0000000..400be31
--- /dev/null
+++ b/kleaf/architecture_constants.bzl
@@ -0,0 +1,24 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""List of supported architectures by Kleaf."""
+
+SUPPORTED_ARCHITECTURES = [
+ ("linux", "x86_64"),
+ ("android", "arm64"),
+ ("android", "arm"),
+ ("android", "x86_64"),
+ ("android", "i386"),
+ ("android", "riscv64"),
+]
diff --git a/kleaf/clang_toolchain.bzl b/kleaf/clang_toolchain.bzl
index 50073f7..a77dace 100644
--- a/kleaf/clang_toolchain.bzl
+++ b/kleaf/clang_toolchain.bzl
@@ -19,13 +19,15 @@
"@kernel_toolchain_info//:dict.bzl",
"VARS",
)
+load(":architecture_constants.bzl", "SUPPORTED_ARCHITECTURES")
load(":clang_config.bzl", "clang_config")
-def clang_toolchain(
+def _clang_toolchain_internal(
name,
clang_version,
target_cpu,
target_os,
+ clang_pkg,
linker_files = None,
sysroot_label = None,
sysroot_path = None,
@@ -38,6 +40,10 @@
clang_version: value of `CLANG_VERSION`, e.g. `r475365b`.
target_cpu: CPU that the toolchain cross-compiles to
target_os: OS that the toolchain cross-compiles to
+ clang_pkg: Label to any target in the clang toolchain package.
+
+ This is used as an anchor to locate other targets in the package.
+ Name of the label is ignored.
linker_files: Additional dependencies to the linker
sysroot_label: Label to a list of files from sysroot
sysroot_path: Path to sysroot
@@ -58,13 +64,13 @@
if extra_compatible_with == None:
extra_compatible_with = []
- clang_pkg = "//prebuilts/clang/host/linux-x86/clang-{}".format(clang_version)
- clang_includes = Label("{}:includes".format(clang_pkg))
+ clang_pkg = native.package_relative_label(clang_pkg)
+ clang_includes = clang_pkg.relative(":includes")
# Technically we can split the binaries into those for compiler, linker
# etc., but since these binaries are usually updated together, it is okay
# to use a superset here.
- clang_all_binaries = Label("{}:binaries".format(clang_pkg))
+ clang_all_binaries = clang_pkg.relative(":binaries")
# Individual binaries
# From _setup_env.sh
@@ -82,12 +88,12 @@
#
# Note: ld.lld does not recognize --target etc. from android.bzl,
# so just use clang directly
- clang = Label("{}:bin/clang".format(clang_pkg))
- clang_plus_plus = Label("{}:bin/clang++".format(clang_pkg))
+ clang = clang_pkg.relative(":bin/clang")
+ clang_plus_plus = clang_pkg.relative(":bin/clang++")
ld = clang
- strip = Label("{}:bin/llvm-strip".format(clang_pkg))
- ar = Label("{}:bin/llvm-ar".format(clang_pkg))
- objcopy = Label("{}:bin/llvm-objcopy".format(clang_pkg))
+ strip = clang_pkg.relative(":bin/llvm-strip")
+ ar = clang_pkg.relative(":bin/llvm-ar")
+ objcopy = clang_pkg.relative(":bin/llvm-objcopy")
# cc_* rules doesn't seem to need nm, obj-dump, size, and readelf
native.filegroup(
@@ -156,20 +162,48 @@
toolchain_type = CPP_TOOLCHAIN_TYPE,
)
-def linux_x86_64_clang_toolchain(
+def clang_toolchain(
name,
clang_version,
+ clang_pkg,
+ target_cpu,
+ target_os,
extra_compatible_with = None):
- """Declare an linux_x86_64 toolchain.
+ """Declare a clang toolchain for the given OS-architecture.
+
+ The toolchain should be under `prebuilts/clang/host/linux-x86`.
Args:
- name: name prefix
- clang_version: `CLANG_VERSION`
- extra_compatible_with: extra `exec_compatible_with` and `target_compatible_with`
+ name: name of the toolchain
+ clang_version: nonconfigurable. version of the toolchain
+ clang_pkg: Label to any target in the clang toolchain package.
+
+ This is used as an anchor to locate other targets in the package.
+ Name of the label is ignored.
+ target_cpu: nonconfigurable. CPU of the toolchain
+ target_os: nonconfigurable. OS of the toolchain
+ extra_compatible_with: nonconfigurable. extra `exec_compatible_with` and `target_compatible_with`
"""
- clang_toolchain(
+
+ if sorted(ARCH_CONFIG.keys()) != sorted(SUPPORTED_ARCHITECTURES):
+ fail("FATAL: ARCH_CONFIG is not up-to-date with SUPPORTED_ARCHITECTURES!")
+
+ extra_kwargs = ARCH_CONFIG[(target_os, target_cpu)]
+
+ _clang_toolchain_internal(
name = name,
clang_version = clang_version,
+ target_os = target_os,
+ target_cpu = target_cpu,
+ clang_pkg = clang_pkg,
+ extra_compatible_with = extra_compatible_with,
+ **extra_kwargs
+ )
+
+# Keys: (target_os, target_cpu)
+# Values: arguments to clang_toolchain()
+ARCH_CONFIG = {
+ ("linux", "x86_64"): dict(
linker_files = [
# From _setup_env.sh, HOSTLDFLAGS
Label("//prebuilts/kernel-build-tools:linux-x86-libs"),
@@ -178,124 +212,37 @@
# sysroot_flags+="--sysroot=${ROOT_DIR}/build/kernel/build-tools/sysroot "
sysroot_label = Label("//build/kernel:sysroot"),
sysroot_path = "build/kernel/build-tools/sysroot",
- target_cpu = "x86_64",
- target_os = "linux",
- extra_compatible_with = extra_compatible_with,
- )
-
-def android_arm64_clang_toolchain(
- name,
- clang_version,
- extra_compatible_with = None):
- """Declare an android_arm64 toolchain.
-
- Args:
- name: name prefix
- clang_version: `CLANG_VERSION`
- extra_compatible_with: extra `exec_compatible_with` and `target_compatible_with`
- """
- clang_toolchain(
- name = name,
- clang_version = clang_version,
+ ),
+ ("android", "arm64"): dict(
ndk_triple = VARS.get("AARCH64_NDK_TRIPLE"),
# From _setup_env.sh: when NDK triple is set,
# --sysroot=${NDK_DIR}/toolchains/llvm/prebuilt/linux-x86_64/sysroot
sysroot_label = "@prebuilt_ndk//:sysroot" if "AARCH64_NDK_TRIPLE" in VARS else None,
sysroot_path = "external/prebuilt_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" if "AARCH64_NDK_TRIPLE" in VARS else None,
- target_cpu = "arm64",
- target_os = "android",
- extra_compatible_with = extra_compatible_with,
- )
-
-def android_arm_clang_toolchain(
- name,
- clang_version,
- extra_compatible_with = None):
- """Declare an android_arm (32-bit) toolchain.
-
- Args:
- name: name prefix
- clang_version: `CLANG_VERSION`
- extra_compatible_with: extra `exec_compatible_with` and `target_compatible_with`
- """
- clang_toolchain(
- name = name,
- clang_version = clang_version,
+ ),
+ ("android", "arm"): dict(
ndk_triple = VARS.get("ARM_NDK_TRIPLE"),
# From _setup_env.sh: when NDK triple is set,
# --sysroot=${NDK_DIR}/toolchains/llvm/prebuilt/linux-x86_64/sysroot
sysroot_label = "@prebuilt_ndk//:sysroot" if "ARM_NDK_TRIPLE" in VARS else None,
sysroot_path = "external/prebuilt_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" if "AARCH64_NDK_TRIPLE" in VARS else None,
- target_cpu = "arm",
- target_os = "android",
- extra_compatible_with = extra_compatible_with,
- )
-
-def android_x86_64_clang_toolchain(
- name,
- clang_version,
- extra_compatible_with = None):
- """Declare an android_x86_64 toolchain.
-
- Args:
- name: name prefix
- clang_version: `CLANG_VERSION`
- extra_compatible_with: extra `exec_compatible_with` and `target_compatible_with`
- """
- clang_toolchain(
- name = name,
- clang_version = clang_version,
+ ),
+ ("android", "x86_64"): dict(
ndk_triple = VARS.get("X86_64_NDK_TRIPLE"),
# From _setup_env.sh: when NDK triple is set,
# --sysroot=${NDK_DIR}/toolchains/llvm/prebuilt/linux-x86_64/sysroot
sysroot_label = "@prebuilt_ndk//:sysroot" if "X86_64_NDK_TRIPLE" in VARS else None,
sysroot_path = "external/prebuilt_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" if "X86_64_NDK_TRIPLE" in VARS else None,
- target_cpu = "x86_64",
- target_os = "android",
- extra_compatible_with = extra_compatible_with,
- )
-
-def android_i386_clang_toolchain(
- name,
- clang_version,
- extra_compatible_with = None):
- """Declare an android_i386 toolchain.
-
- Args:
- name: name prefix
- clang_version: `CLANG_VERSION`
- extra_compatible_with: extra `exec_compatible_with` and `target_compatible_with`
- """
- clang_toolchain(
- name = name,
- clang_version = clang_version,
+ ),
+ ("android", "i386"): dict(
# i386 uses the same NDK_TRIPLE as x86_64
ndk_triple = VARS.get("X86_64_NDK_TRIPLE"),
# From _setup_env.sh: when NDK triple is set,
# --sysroot=${NDK_DIR}/toolchains/llvm/prebuilt/linux-x86_64/sysroot
sysroot_label = "@prebuilt_ndk//:sysroot" if "X86_64_NDK_TRIPLE" in VARS else None,
sysroot_path = "external/prebuilt_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" if "X86_64_NDK_TRIPLE" in VARS else None,
- target_cpu = "i386",
- target_os = "android",
- extra_compatible_with = extra_compatible_with,
- )
-
-def android_riscv64_clang_toolchain(
- name,
- clang_version,
- extra_compatible_with = None):
- """Declare an android_riscv toolchain.
-
- Args:
- name: name prefix
- clang_version: `CLANG_VERSION`
- extra_compatible_with: extra `exec_compatible_with` and `target_compatible_with`
- """
- clang_toolchain(
- name = name,
- clang_version = clang_version,
- target_cpu = "riscv64",
- target_os = "android",
- extra_compatible_with = extra_compatible_with,
+ ),
+ ("android", "riscv64"): dict(
# TODO(b/271919464): We need NDK_TRIPLE for riscv
- )
+ ),
+}
diff --git a/kleaf/empty_toolchain.bzl b/kleaf/empty_toolchain.bzl
new file mode 100644
index 0000000..49b01a6
--- /dev/null
+++ b/kleaf/empty_toolchain.bzl
@@ -0,0 +1,50 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""An empty toolchain that does nothing."""
+
+def _empty_toolchain_impl(_ctx):
+ return platform_common.ToolchainInfo()
+
+_empty_toolchain = rule(
+ implementation = _empty_toolchain_impl,
+)
+
+def empty_toolchain(
+ name,
+ toolchain_type,
+ **kwargs):
+ """Defines an empty toolchain.
+
+ Args:
+ name: name of the toolchain
+ toolchain_type: type of the toolchain
+ **kwargs: additional kwargs passed to the toolchain target
+ """
+
+ private_kwargs = kwargs | dict(
+ visibility = ["//visibility:private"],
+ )
+
+ _empty_toolchain(
+ name = name + "_internal",
+ **private_kwargs
+ )
+
+ native.toolchain(
+ name = name,
+ toolchain = name + "_internal",
+ toolchain_type = toolchain_type,
+ **kwargs
+ )
diff --git a/kleaf/register.bzl b/kleaf/register.bzl
index 43ed6a4..a886838 100644
--- a/kleaf/register.bzl
+++ b/kleaf/register.bzl
@@ -14,26 +14,37 @@
"""Registers all clang toolchains defined in this package."""
+load(":architecture_constants.bzl", "SUPPORTED_ARCHITECTURES")
+load(":user_clang_toolchain_repository.bzl", "user_clang_toolchain_repository")
load(":versions.bzl", "VERSIONS")
# buildifier: disable=unnamed-macro
def register_clang_toolchains():
- """Registers all clang toolchains defined in this package."""
- for version in VERSIONS:
+ """Registers all clang toolchains defined in this package.
+
+ The user clang toolchain is expected from the path defined in the
+ `KLEAF_USER_CLANG_TOOLCHAIN_PATH` environment variable, if set.
+ """
+
+ user_clang_toolchain_repository(
+ name = "kleaf_user_clang_toolchain",
+ )
+
+ for target_os, target_cpu in SUPPORTED_ARCHITECTURES:
native.register_toolchains(
- "//prebuilts/clang/host/linux-x86/kleaf:{}_android_arm64_clang_toolchain".format(version),
- "//prebuilts/clang/host/linux-x86/kleaf:{}_android_arm_clang_toolchain".format(version),
- "//prebuilts/clang/host/linux-x86/kleaf:{}_android_i386_clang_toolchain".format(version),
- "//prebuilts/clang/host/linux-x86/kleaf:{}_android_riscv64_clang_toolchain".format(version),
- "//prebuilts/clang/host/linux-x86/kleaf:{}_android_x86_64_clang_toolchain".format(version),
- "//prebuilts/clang/host/linux-x86/kleaf:{}_linux_x86_64_clang_toolchain".format(version),
+ "@kleaf_user_clang_toolchain//:user_{}_{}_clang_toolchain".format(
+ target_os,
+ target_cpu,
+ ),
)
- native.register_toolchains(
- "//prebuilts/clang/host/linux-x86/kleaf:android_arm64_clang_toolchain",
- "//prebuilts/clang/host/linux-x86/kleaf:android_arm_clang_toolchain",
- "//prebuilts/clang/host/linux-x86/kleaf:android_i386_clang_toolchain",
- "//prebuilts/clang/host/linux-x86/kleaf:android_riscv64_clang_toolchain",
- "//prebuilts/clang/host/linux-x86/kleaf:android_x86_64_clang_toolchain",
- "//prebuilts/clang/host/linux-x86/kleaf:linux_x86_64_clang_toolchain",
- )
+ for version in VERSIONS:
+ for target_os, target_cpu in SUPPORTED_ARCHITECTURES:
+ native.register_toolchains(
+ "//prebuilts/clang/host/linux-x86/kleaf:{}_{}_{}_clang_toolchain".format(version, target_os, target_cpu),
+ )
+
+ for target_os, target_cpu in SUPPORTED_ARCHITECTURES:
+ native.register_toolchains(
+ "//prebuilts/clang/host/linux-x86/kleaf:{}_{}_clang_toolchain".format(target_os, target_cpu),
+ )
diff --git a/kleaf/user_clang_toolchain_repository.bzl b/kleaf/user_clang_toolchain_repository.bzl
new file mode 100644
index 0000000..6922d8f
--- /dev/null
+++ b/kleaf/user_clang_toolchain_repository.bzl
@@ -0,0 +1,123 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Defines a repository that provides a clang version at a user defined path."""
+
+def _user_clang_toolchain_repository_impl(repository_ctx):
+ repository_ctx.file("WORKSPACE.bazel", """\
+workspace(name = "{}")
+""".format(repository_ctx.attr.name))
+
+ if "KLEAF_USER_CLANG_TOOLCHAIN_PATH" not in repository_ctx.os.environ:
+ _empty_user_clang_toolchain_repository_impl(repository_ctx)
+ else:
+ _real_user_clang_toolchain_repository_impl(repository_ctx)
+
+def _empty_user_clang_toolchain_repository_impl(repository_ctx):
+ build_file_content = '''\
+"""Fake user C toolchains.
+
+These toolchains are not registered with the C toolchain type.
+"""
+
+load("{architecture_constants}", "SUPPORTED_ARCHITECTURES")
+load("{empty_toolchain}", "empty_toolchain")
+
+toolchain_type(
+ name = "empty_toolchain_type",
+ visibility = ["//visibility:private"],
+)
+
+[empty_toolchain(
+ name = "user_{{}}_{{}}_clang_toolchain".format(target_os, target_cpu),
+ toolchain_type = ":empty_toolchain_type",
+ visibility = ["//visibility:private"],
+) for target_os, target_cpu in SUPPORTED_ARCHITECTURES]
+'''.format(
+ architecture_constants = Label(":architecture_constants.bzl"),
+ empty_toolchain = Label(":empty_toolchain.bzl"),
+ )
+ repository_ctx.file("BUILD.bazel", build_file_content)
+
+def _real_user_clang_toolchain_repository_impl(repository_ctx):
+ user_clang_toolchain_path = repository_ctx.os.environ["KLEAF_USER_CLANG_TOOLCHAIN_PATH"]
+ user_clang_toolchain_path = repository_ctx.path(user_clang_toolchain_path)
+
+ # Symlink contents of user_clang_toolchain_path to the top of the repository
+ for subpath in user_clang_toolchain_path.readdir():
+ if subpath.basename in ("BUILD.bazel", "BUILD", "WORKSPACE.bazel", "WORKSPACE"):
+ continue
+
+ subpath_s = str(subpath)
+ user_clang_toolchain_path_s = str(user_clang_toolchain_path)
+ if not subpath_s.startswith(user_clang_toolchain_path_s + "/"):
+ fail("FATAL: {} does not start with {}/".format(
+ subpath_s,
+ user_clang_toolchain_path_s,
+ ))
+
+ repository_ctx.symlink(
+ subpath,
+ subpath_s.removeprefix(user_clang_toolchain_path_s + "/"),
+ )
+
+ build_file_content = '''\
+"""User C toolchains specified via command line flags."""
+
+load("{architecture_constants}", "SUPPORTED_ARCHITECTURES")
+load("{clang_toolchain}", "clang_toolchain")
+
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+ name = "binaries",
+ srcs = glob([
+ "bin/*",
+ "lib/*",
+ ]),
+)
+
+filegroup(
+ name = "includes",
+ srcs = glob([
+ "lib/clang/*/include/**",
+ ]),
+)
+
+[clang_toolchain(
+ name = "user_{{}}_{{}}_clang_toolchain".format(target_os, target_cpu),
+ target_cpu = target_cpu,
+ target_os = target_os,
+ clang_pkg = ":fake_anchor_target",
+ clang_version = "kleaf_user_clang_toolchain_skip_version_check",
+) for target_os, target_cpu in SUPPORTED_ARCHITECTURES]
+'''.format(
+ architecture_constants = Label(":architecture_constants.bzl"),
+ clang_toolchain = Label(":clang_toolchain.bzl"),
+ )
+
+ repository_ctx.file("BUILD.bazel", build_file_content)
+
+user_clang_toolchain_repository = repository_rule(
+ doc = """Defines a repository that provides a clang version at a user defined path.
+
+The user clang toolchain is expected from the path defined in the
+`KLEAF_USER_CLANG_TOOLCHAIN_PATH` environment variable, if set.
+""",
+ implementation = _user_clang_toolchain_repository_impl,
+ environ = [
+ "KLEAF_USER_CLANG_TOOLCHAIN_PATH",
+ ],
+ local = True,
+)