LLVM Toolchain

Overview

ChromeOS provides a baremetal LLVM toolchain that can be used to build both EC and Zephyr. The EC and Zephyr-based fingerprint firmware use the LLVM toolchain by default. This document provides details on how the toolchain is configured and built.

Supported Baremetal Toolchains

  • RISC-V: riscv32-cros-elf
  • ARMv7-M: armv7m-cros-eabi
  • ARMv6-M: arm-none-eabi

cros_setup_toolchains

cros_setup_toolchains is the script used to build the various ChromeOS toolchains. It‘s a wrapper around Gentoo’s crossdev, which is a script to configure and build the necessary components for a cross-compiler toolchain. One area where cros_setup_toolchains diverges from crossdev is in its handling of LLVM-based toolchains. crossdev has LLVM toolchain support, but cros_setup_toolchains does not use it. Instead, cros_setup_toolchains adds extra LLVM packages to the crossdev commandline.

Ultimately, cros_setup_toolchains invokes crossdev with a set of flags. You can see the exact crossdev command invoked in the output:

(chroot) sudo `which cros_setup_toolchains` -t riscv32-cros-elf --nousepkg
16:29:01.241: INFO: run: crossdev --stable --show-fail-log --env 'FEATURES=splitdebug' -P --oneshot --overlays '/mnt/host/source/src/third_party/chromiumos-overlay /mnt/host/source/src/third_party/eclass-overlay /mnt/host/source/src/third_party/portage-stable' --ov-output /usr/local/portage/crossdev -t riscv32-cros-elf --ex-pkg sys-libs/compiler-rt --ex-pkg sys-libs/llvm-libunwind --ex-pkg sys-libs/libcxx --binutils '[stable]' --gcc '[stable]' --libc '[stable]' --ex-gdb

Toolchain Overlay

The packages that make up the toolchain are defined in the toolchain overlay. crossdev searches for ebuilds in the directory cross-<target-triple>, where <target-triple> has this definition.

As an example, if you want to build a toolchain with the triple riscv32-cros-elf, you would run:

(chroot) sudo `which cros_setup_toolchains` -t riscv32-cros-elf --nousepkg

which will ultimately result in a call to crossdev, which will search for ebuilds in chromiumos/overlays/toolchains/cross-riscv32-elf. That directory simply contains symlinks to the canonical ChromeOS ebuild for the package. See https://crrev.com/c/6349977 for an example.

Components

In the toolchain overlay for our baremetal toolchains, you'll see the following components:

Once you‘ve successfully built a toolchain with cros_setup_toolchains or you’re using a chroot that has an SDK with a prebuilt toolchain, you can use emerge to rebuild the individual components as you make changes to the associated ebuild.

If you are making changes to a -9999 ebuild, you‘ll need to use cros-workon --host. In addition, for the ebuilds that use the LLVM source, you’ll need to sync the LLVM source by adding the toolchain group, since it's marked as notdefault in the repo manifest:

(outside) repo init -g toolchain,default

For example, if you change some compiler flags in the compiler-rt ebuild, and want to rebuild it for RISC-V, you would do:

(chroot) cros-workon --host start cross-riscv32-cros-elf/compiler-rt
(chroot) emerge cross-riscv32-cros-elf/compiler-rt

The standard Portage equery commands work on these packages as well, so you can do things like:

List the files in a package:

(chroot)$ equery files <package>
(chroot) equery files cross-riscv32-cros-elf/compiler-rt
 * Searching for compiler-rt in cross-riscv32-cros-elf ...
 * Contents of cross-riscv32-cros-elf/compiler-rt-20.0_pre547379-r48:
/usr
/usr/lib64
/usr/lib64/clang
/usr/lib64/clang/20
/usr/lib64/clang/20/lib
/usr/lib64/clang/20/lib/baremetal
/usr/lib64/clang/20/lib/baremetal/libclang_rt.builtins-riscv32.a

Find the package that provides a file:

(chroot) equery belongs /path/to/file
(chroot) equery belongs /usr/lib64/clang/20/lib/baremetal/libclang_rt.builtins-riscv32.a
cross-riscv32-cros-elf/compiler-rt-20.0_pre547379-r48 (/usr/lib64/clang/20/lib/baremetal/libclang_rt.builtins-riscv32.a)

Testing Toolchain Changes

When modifying an ebuild for a component in the baremetal toolchain, you'll want to make sure that the EC and Zephyr builds succeed, in addition to the Renode tests passing. You can do that by adding the following to the commit message:

Cq-Include-Trybots: chromeos/cq:firmware-ec-cq,firmware-zephyr-cq,firmware-ec-renode-cq

Automating this is tracked in http://b/406868085.

Adding a new baremetal toolchain

If you want to add a baremetal toolchain for a new target triple, see the CLs created for creating the RISC-V toolchain.

The general flow is: