Note: You may view the documentation for the following Bazel rules and macros on Android Continuous Integration:
Make the following changes to the kernel manifest to support Bazel build.
.source_date_epoch_dir
symlink to your ${KERNEL_DIR}
$SOURCE_DATE_EPOCH
. See SOURCE_DATE_EPOCH.tools/bazel
symlink to build/kleaf/build.sh
WORKSPACE
symlink to build/kleaf/bazel.WORKSPACE
Example for Pixel 2021:
Example for Android Common Kernel and Cloud Android kernel:
https://android.googlesource.com/kernel/manifest/+/refs/heads/common-android-mainline/default.xml
WARNING: It is recommended to use the common Android kernel under //common
(the so-called “mixed build”) instead of building a custom kernel.
You may define a kernel_build
target to build a custom kernel. The name of the kernel_build
target is usually the name of your device, e.g. tuna
.
The outs
attribute of the target should align with the FILES
variable in build.config. This may include DTB files and kernel images, e.g. vmlinux
.
The module_outs
attribute of the target includes the list of in-tree drivers that you are building. See section to build in-tree drivers (Step 1) below.
load("//build/kleaf:kernel.bzl","kernel_build") load("//build/kleaf:common_kernels.bzl", "arm64_outs") kernel_build( name = "tuna", srcs = glob( ["**"], exclude = [ "**/BUILD.bazel", "**/*.bzl", ".git/**", ], ), outs = arm64_outs, build_config = "build.config.tuna", )
If you have a separate kernel tree to build in-tree drivers, define a kernel_build
target to build these modules. The name of the kernel_build
target is usually the name of your device, e.g. tuna
.
If you also have external kernel modules to be built, be sure to set visibility accordingly, so that the targets to build external kernel modules can refer to this kernel_build
target.
If you are building a custom kernel, you may reuse the existing kernel_build
target, and keep kernel images in outs
. If you are building against GKI, set the base_kernel
attribute accordingly (e.g. to //common:kernel_aarch64
).
The build_config
attribute of the target should point to the main build.config
file. To use build.config
files generated on the fly, you may use the kernel_build_config
rule. See example for Pixel 2021 below.
The outs
attribute of the target should align with the FILES
variable in build.config. This may include DTB files.
The module_outs
attribute of the target includes the list of in-tree drivers that you are building.
Note: It is recommended that kernel modules are moved out of the kernel tree to be built as external kernel modules. This means keeping the list of module_outs
empty or as short as possible. See Step 2 for building external kernel modules.
Example for Pixel 2021 (see the kernel_build
target named slider
):
Define kernel_module
targets to build external kernel modules. You should create a kernel_module
target for each item in EXT_MODULES
variable in build.config
.
The kernel_build
attribute should be the target to the kernel_build
you have previously created in step 1, or //common:kernel_aarch64
if you did not do step 1.
Be sure to set visibility accordingly, so that these targets are visible to the kernel_modules_install
target that will be created in step 3.
If the module depends on other modules, set kernel_module_deps
accordingly. See the bms
and power/reset
module below for an example.
If the module depends on headers in other locations, add headers to a filegroup, then add the headers to srcs
. See the bms
and power/reset
module below for an example.
Minimal example for the edgetpu
driver of Pixel 2021:
Example for the bms
driver of Pixel 2021:
Example for the power/reset
driver of Pixel 2021:
depmod
Define a kernel_modules_install
target that includes all external kernel modules created in Step 2. This is equivalent to running make modules_install
, which runs depmod
.
The name of the target is usually the name of your device with _modules_install
appended to it, e.g. tuna_modules_install
.
See Step 2 to determine the kernel_build
attribute of the target.
Example for Pixel 2021 (see the kernel_modules_install
target named slider_modules_install
):
The kernel_images
macro produces partition images that are ready to be flashed and tested immediately on your device. It can build the initramfs
image, boot
image, vendor_boot
image, vendor_dlkm
image, system_dlkm
image, etc.
The name of the target is usually the name of your device with _images
appended to it, e.g. tuna_images
.
If you do not need to build any partition images, skip this step.
Example for Pixel 2021 (see the kernel_images
target named slider_images
):
Define a copy_to_dist_dir
target that includes the targets you want in the distribution directory. The name of this copy_to_dist_dir
target is usually the name of your device with _dist
appended to it, e.g. tuna_dist
.
Set flat = True
so the directory structure within $DIST_DIR
is flattened.
Add the following to the data
attribute of the copy_to_dist_dir
target so that the outputs are analogous to those produced by build/build.sh
:
kernel_build
you have created in Step 1, e.g. :tuna
. This adds all outs
and module_outs
to the distribution directory.kernel_modules_install
target you have created in Step 3. You may skip the kernel_modules
targets created in Step 2, because the kernel_modules_install
target includes all kernel_modules
targets. This copies all external kernel modules to the distribution directory.kernel_images
target you have created in Step 4. This copies all partition images to the distribution directory.Example for Pixel 2021 (see the copy_to_dist_dir
target named slider_dist
):
# Optional: prepare the device by flashing a base build. # During development, you may want to wipe, disable verity and disable verification. # fastboot update tuna-img.zip -w --disable-verity --disable-verification $ tools/bazel run //private/path/to/sources:tuna_dist -- --dist_dir=out/dist # Flash static partitions $ fastboot flash boot out/dist/boot.img $ fastboot flash system_dlkm out/dist/system_dlkm.img $ fastboot flash vendor_boot out/dist/vendor_boot.img $ fastboot flash dtbo out/dist/dtbo.img $ fastboot reboot fastboot # Flash dynamic partitions $ fastboot flash vendor_dlkm out/dist/vendor_dlkm.img $ fastboot reboot
See errors.md.
Warning: You may want to re-enable LTO in production.
Building with link-time optimization (LTO) may take a very long time that brings little benefit during development. You may disable LTO to shorten the build time for development purposes.
For example:
$ tools/bazel build --lto=none //private/path/to/sources:tuna_dist
The --lto
option is applied to the build, not the copy_to_dist_dir
step. Hence, put it before the --
delimiter when running a *_dist
target. For example:
$ tools/bazel run --lto=none //private/path/to/sources:tuna_dist -- --dist_dir=out/dist
You only need to do this once per workspace.
# Do this at workspace root next to the file WORKSPACE $ test -f WORKSPACE && echo 'build --//build/kleaf:lto=none' >> user.bazelrc # Future builds in this workspace always disables LTO. $ tools/bazel build //private/path/to/sources:tuna_dist
select()
See official Bazel documentation for select()
here: https://docs.bazel.build/versions/main/configurable-attributes.html
In general, inputs to a target are configurable, while declared outputs are not. One exception is that the kernel_build
rule provides limited support of select()
in outs
and module_outs
attributes. See documentations of kernel_build
for details.