For building ChromeOS with Bazel, use the following repo
command to check out with a few additional repositories.
$ mkdir ~/chromiumos $ cd ~/chromiumos # If you have access to the internal manifests: $ repo init -u https://chrome-internal.googlesource.com/chromeos/manifest-internal -g default,bazel -b snapshot # Otherwise: $ repo init -u https://chromium.googlesource.com/chromiumos/manifest -g default,bazel -b snapshot $ repo sync -c -j 16 $ cd src
-g default,bazel
is important to check out some additional repositories needed to build with Bazel.snapshot
branch rather than main
because Bazel‘s caching logic requires all inputs to match exactly, so you’re better off working from the snapshot
branch that was already built by the Snapshot/CQ builders rather than working from main
and picking up whatever commit happened to be at ToT at the time you ran repo sync
. You‘ll be at most 40 minutes behind ToT, and you’ll have the best chance of getting cache hits to speed your builds.repo init
command atop an existing checkout.Unless otherwise specified, examples in this doc assume that your current directory is ~/chromiumos/src
.
First, enter the CrOS SDK chroot with cros_sdk
command, which will create a new one if you haven't already. Then run the following command to create the amd64-host
sysroot.
(cr) $ /mnt/host/source/chromite/shell/create_sdk_board_root --board amd64-host --profile sdk/bootstrap
This will create /build/amd64-host
. This sysroot contains the Portage configuration that is used when building host tool packages. i.e., CBUILD.
You can then proceed to create the target board's sysroot:
(cr) $ setup_board --board amd64-generic --public
If you're attempting to build a public image while using an internal manifest, the --public
flag allows you to do that, which is useful when attempting to recreate a CQ/Snapshot failure for build targets that use public manifests on the CI bots, such as amd64-generic. Omit the flag if you do want to build internal packages.
cros build-packages
Now that you have configured your chroot, you can invoke a build with the standard cros build-packages
command, except that you need to pass the extra option --bazel
to build with Bazel.
To build a single Portage package, e.g. sys-apps/attr
:
$ cros build-packages --board=amd64-generic --bazel sys-apps/attr
To build all packages included in the ChromeOS test image:
$ cros build-packages --board=amd64-generic --bazel
Upon successful completion, packages are installed to the sysroot inside the CrOS SDK chroot, so you can use other commands expecting built packages to be in the sysroot, e.g. cros build-image
and cros deploy
.
You can alternatively run Bazel directly to build certain targets.
/mnt/host/source/chromite/bin/bazel
instead of /usr/bin/bazel
that is found first on the standard $PATH
.The syntax for specifying a Portage package is:
@portage//<host|target>/<category>/<package>`.
host
means the build host (CBUILD), and target
means the cross-compiled target (CHOST) specified by the BOARD
environment variable.
Now you're ready to start building. To build a single Portage package, e.g. sys-apps/attr
:
$ BOARD=amd64-generic /mnt/host/source/chromite/bin/bazel build @portage//target/sys-apps/attr
To build all packages included in the ChromeOS base image:
$ BOARD=amd64-generic /mnt/host/source/chromite/bin/bazel build @portage//target/virtual/target-os:package_set
A package_set
is a special target that also includes the target's PDEPENDs.
To build a package for the host, use the host
prefix:
$ BOARD=amd64-generic /mnt/host/source/chromite/bin/bazel build @portage//host/app-shells/bash
To build all packages included in the ChromeOS test image:
$ BOARD=amd64-generic /mnt/host/source/chromite/bin/bazel build @portage//target/virtual/target-os:package_set @portage//target/virtual/target-os-dev:package_set @portage//target/virtual/target-os-test:package_set
bazel build
, packages are not installed to the sysroot, which means that you can‘t use built packages with existing tools like cros deploy
. Use cros build-packages --bazel
instead if you want to install packages to the sysroot after they’re built by Bazel.You can simply run cros build-image
to build ChromeOS images if you use cros build-packages --bazel
to build ChromeOS packages included in ChromeOS images.
You can speed up the build by enabling remote Bazel caching with RBE. To do this, follow this instruction to authenticate.
After authentication, make sure that you restart the Bazel instance by running bazel shutdown
.
Building chromeos-base/chromeos-chrome
takes 2-3 hours, but you can use reclient to make it as fast as less than 1 hour.
To use reclient, please run gcloud auth application-default login
for authentication. If you're going to run bazel build
inside the chroot, please make sure that you run this outside the chroot after exiting the chroot in all existing windows.
After authentication, you can just run bazel build
with USE_REMOTEEXEC=true
to enable reclient.
$ USE_REMOTEEXEC=true BOARD=amd64-generic bazel build @portage//chromeos-base/chromeos-chrome
You can also run build_packages
with --run_remoteexec
to run it with reclient.
$ build_packages --bazel --board=amd64-generic --run_remoteexec
By default you can‘t tab complete the @portage//
repository. This is because bazel doesn’t provide support for tab completing external repositories. By setting export ENABLE_PORTAGE_TAB_COMPLETION=1
in your .bashrc
/.profile
, bazel
will create a @portage
symlink in the workspace root (i.e., ~/chromiumos/src
). This allows the bazel tab completion to work, but comes with one caveat. You can no longer run bazel build //...
because it will generate analysis errors. This is why this flag is not enabled by default.
The @portage
symlink has another added benefit, you can easily browse the generated BUILD.bazel
files.