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.
To get started with the arm none eabi embedded toolchain, copy the appropriate WORKSPACE
setup
from the releases page.
Using a stable commit from the repo is also an option,for example:
# WORKSPACE
#---------------------------------------------------------------------
# ARM none eabi GCC
#---------------------------------------------------------------------
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")
arm_none_eabi_deps()
#---------------------------------------------------------------------
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
If for you are using Bazel rules that do not support platforms, you can also use this instead
# .bazelrc
# Use the legacy crosstool-top config
build:legacy --crosstool_top=@arm_none_eabi//toolchain
build:legacy --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
Now Bazel will automatically use arm-none-eabi-gcc
as a compiler
By default, this repo defines the arm-none-eabi-generic
platform as:
platform(
name = "arm_none_generic",
constraint_values = [
"@platforms//os:none",
"@platforms//cpu:arm",
],
)
If you want to further differentiate your project's platforms (for example to support a certain board/cpu) you can extend it using this template:
platform(
name = "your_custom_platform",
constraint_values = [
"<your additional constraints>",
],
parents = [
"@arm_none_eabi//platforms:arm_none_generic"
],
)
If you want to select some build attributes based on their compatibility with the arm-none-eabi-gcc toolchain, you can use the config_settings
available at @arm_none_eabi//config:arm_none_compatible
, defined as:
config_setting(
name = "arm_none_compatible",
constraint_values = [
"@platforms//cpu:arm",
"@platforms//os:none",
],
)
You can always add onto this config_setting
by creating your own config_setting_group
that inherits from this one:
load("@bazel_skylib//lib:selects.bzl", "selects")
config_setting()
name = "your_config_setting",
...
)
selects.config_setting_group(
name = "your_config_setting_group",
match_all = [
"@arm_none_eabi//config:arm_none_compatible",
":your_config_setting"
],
)
and then use these definitions to select
in rules
filegroup(
name = "arm_none_srcs",
srcs = [...],
)
cc_binary(
name = "your_binary",
srcs = select({
"@arm_none_eabi//config:arm_none_compatible": [":arm_none_srcs"],
...
})
)
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"],
)
Follow these steps if you want to test this repo before using it to integrate the toolchain into your local project.
Install Bazel for your platform. Installing with a package manager is recommended, especially on windows where additional runtime components are needed.
- Ubuntu Linux:
sudo apt install bazel
- macOS:
brew install bazel
- Windows:
choco install bazel
bazelisk
is a user-friendly launcher for bazel
. Follow the install instructions in the Bazelisk repo
Use bazelisk
as you would use bazel
, this takes care of using the correct Bazel version for each project by using the .bazelversion file contained in each project.
git clone https://github.com/d-asnaghi/bazel-arm-none-eabi.git
Use this command to build any target (a mock target examples
is provided).
# build the examples
bazelisk build examples
This will take care of downloading the appropriate toolchain for your OS and compile all the source files specified by the target.
├── WORKSPACE
│
├── examples
│ ├── BUILD.bazel
│ └── /* SOURCE CODE */
│
└── toolchain
├── BUILD.bazel
├── compiler.BUILD
├── config.bzl
└── arm-none-eabi
├── darwin_x86_64
│ └── /* DARWIN TOOLCHAIN */
├── linux_x86_64
│ └── /* LINUX TOOLCHAIN */
├── windows_x86_32
│ └── /* WINDOWS TOOLCHAIN */
└── ...
└── /* OTHER TOOLCHAINS */