The goal of the project is to illustrate how to use a custom arm-none-eabi embedded toolchain with Bazel.
If this project was useful to you, give it a ⭐️ and I'll keep improving it!
You can follow the post Bazel for ARM embedded toolchains to get more details about this code.
- Simple integration with WORKSPACE / MODULE [experimental]
- Direct access to gcc tools
- Custom toolchain support
- Remote execution support
And this to your .bazelrc
# .bazelrc
# Build using platforms by default
build --incompatible_enable_cc_toolchain_resolution
build --platforms=@arm_none_eabi//platforms:arm_none_generic
Add this git repository to your WORKSPACE to use the compiler
# WORKSPACE.bazel
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "arm_none_eabi",
commit = "<commit>",
remote = "https://github.com/hexdae/bazel-arm-none-eabi",
shallow_since = "<value>",
)
load("@arm_none_eabi//:deps.bzl", "arm_none_eabi_deps", "register_default_arm_none_eabi_toolchains")
arm_none_eabi_deps()
register_default_arm_none_eabi_toolchains()
To reuse this Bazel module, one would have to create a local git submodule first, then add bazel_dep
with
a local_path_override
for MODULE.bazel file to recognize and use it.
git submodule add https://github.com/hexdae/bazel-arm-none-eabi <path_to_submodule>
# MODULE.bazel
bazel_dep(name = "arm_none_eabi", version = "1.0.0")
local_path_override(
module_name = "arm_none_eabi",
path = "<path_to_submodule>",
)
register_toolchains("@arm_none_eabi//toolchain:all")
arm_none_eabi_ext = use_extension("@arm_none_eabi//:extensions.bzl", "arm_none_eabi_extension")
arm_none_eabi_ext.toolchain(version = "9.2.1")
use_repo(
arm_none_eabi_ext,
"arm_none_eabi_darwin_x86_64",
"arm_none_eabi_linux_aarch64",
"arm_none_eabi_linux_x86_64",
"arm_none_eabi_windows_x86_64",
)
Now Bazel will automatically use arm-none-eabi-gcc
as a compiler.
If you want to bake certain compiler flags in to your toolchain, you can define a custom arm-none-eabi
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:
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"],
)
This toolchain is compatible with remote execution, see remote.yml