The goal of the project is to make arm cross compilation toolchains readily available (and customizable) for bazel developers.
If this project was useful to you, give it a ⭐️ and I'll keep improving it!
You might also like another, similar, toolchain project for bazel
RISCV toolchains
- MODULE support
- WORKSPACE support
- Direct access to gcc tools
- Custom toolchain support
- Use a specific GCC version
- Link Map Generation
- Examples
- Remote execution support
- Linux, MacOS, Windows
And this to your .bazelrc
# .bazelrc
# Build using platforms by default
build --incompatible_enable_cc_toolchain_resolution
bazel_dep(name = "toolchains_arm_gnu", version = "<version>")
arm_toolchain = use_extension("@toolchains_arm_gnu//:extensions.bzl", "arm_toolchain")
arm_toolchain.arm_none_eabi()
use_repo(arm_toolchain, "arm_none_eabi")
register_toolchains("@arm_none_eabi//toolchain:all")
arm_toolchain.arm_none_linux_gnueabihf()
use_repo(arm_toolchain, "arm_none_linux_gnueabihf")
register_toolchains("@arm_none_linux_gnueabihf//toolchain:all")
arm_toolchain.aarch64_none_elf()
use_repo(arm_toolchain, "aarch64_none_elf")
register_toolchains("@aarch64_none_elf//toolchain:all")
arm_toolchain.aarch64_none_linux_gnu()
use_repo(arm_toolchain, "aarch64_none_linux_gnu")
register_toolchains("@aarch64_none_linux_gnu//toolchain:all")
Add this git repository to your WORKSPACE to use the compiler (NOTE: WORSKPACE setups will become obsolete soon, do not use for new projects)
WORKSPACE
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "rules_cc",
remote = "https://github.com/bazelbuild/rules_cc",
branch = "main",
)
git_repository(
name = "arm_none_eabi",
remote = "https://github.com/hexdae/toolchains_arm_gnu",
branch = "master",
)
load("@toolchains_arm_gnu//:deps.bzl", "arm_none_eabi_deps")
arm_none_eabi_deps()
register_toolchains("@arm_none_eabi//toolchain:all")
load("@toolchains_arm_gnu//:deps.bzl", "arm_none_linux_gnueabihf_deps")
arm_none_linux_gnueabihf_deps()
register_toolchains("@arm_none_linux_gnueabihf//toolchain:all")
load("@toolchains_arm_gnu//:deps.bzl", "aarch64_none_elf_deps")
aarch64_none_elf_deps()
register_toolchains("@aarch64_none_elf//toolchain:all")
load("@toolchains_arm_gnu//:deps.bzl", "aarch64_none_linux_gnu_deps")
aarch64_none_linux_gnu_deps()
register_toolchains("@aarch64_none_linux_gnu//toolchain:all")
If you want to bake certain compiler flags in to your toolchain, you can define a custom toolchain in your repo.
In a BUILD file:
# path/to/toolchains/BUILD
load("@arm_none_eabi//toolchain:toolchain.bzl", "arm_none_eabi_toolchain")
arm_none_eabi_toolchain(
name = "custom_toolchain",
target_compatible_with = [
"<your additional constraints>",
],
copts = [
"<your additional copts>",
],
linkopts = [
"<your additional linkopts>",
],
)
And in your WORKSPACE / MODULE file:
register_toolchains("@//path/to/toolchains:all")
Be careful about registering the default toolchains when using a custom one
If you need direct access to gcc
tools, they are available as @arm_none_eabi//:<tool>
. For example, the following genrules
could be used to produce .bin
and .hex
artifacts from a generic .out
target.
cc_binary(
name = "target.out"
srcs = [...],
deps = [...],
copts = [...],
...
)
genrule(
name = "bin",
srcs = [":target.out"],
outs = ["target.bin"],
cmd = "$(execpath @arm_none_eabi//:objcopy) -O binary $< $@",
tools = ["@arm_none_eabi//:objcopy"],
)
genrule(
name = "hex",
srcs = [":target.out"],
outs = ["target.hex"],
cmd = "$(execpath @arm_none_eabi//:objcopy) -O ihex $< $@",
tools = ["@arm_none_eabi//:objcopy"],
)
If you want to build a linkermap file, starting from bazel 7.2.0 it can be enabled through the generate_linkmap
and accessed though the linkmap
output group.
cc_binary(
name = "target.out"
srcs = [...],
deps = [...],
copts = [...],
...
features = ["generate_linkmap"],
)
filegroup(
name = "target.out.map",
srcs = [":target.out"],
output_group = "linkmap",
)
This toolchain is compatible with remote execution
The Windows maximum path length limitation may cause build failures with the
arm-none-linux-gnueabihf
toolchain. In some cases, it's enough to avoid this
by setting a shorter output directory. Add this to your .bazelrc
file:
startup --output_user_root=C:/tmp
See avoid long path issues for more information.