ARM embedded toolchains for Bazel
141
stars
156
commits
Starlark
primary language
Jul 30, 2026
updated
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
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)
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.
Starlark
92.4%
Python
5.3%
C++
1.8%
ARM embedded toolchains for Bazel
141
stars
156
commits
Starlark
primary language
Jul 30, 2026
updated
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
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)
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.
Starlark
92.4%
Python
5.3%
C++
1.8%