Home

Awesome

<p align="center"> <a href="https://github.com/hexdae/toolchains_arm_gnu/blob/master/LICENSE"> <img alt="GitHub license" src="https://img.shields.io/github/license/hexdae/toolchains_arm_gnu?color=success"> </a> <a href="https://github.com/hexdae/toolchains_arm_gnu/stargazers"> <img alt="GitHub stars" src="https://img.shields.io/github/stars/hexdae/toolchains_arm_gnu?color=success"> </a> <a href="https://github.com/hexdae/toolchains_arm_gnu/issues"> <img alt="GitHub issues" src="https://img.shields.io/github/issues/hexdae/toolchains_arm_gnu"> </a> <a href="https://github.com/hexdae/toolchains_arm_gnu/actions"> <img alt="CI" src="https://github.com/hexdae/toolchains_arm_gnu/actions/workflows/ci.yml/badge.svg"> </a> </p> <p align="center"> <img src="https://asnaghi.me/images/bazel-arm.png" width="400px"/> </p>

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

Features

Use the toolchain from this repo

.bazelrc

And this to your .bazelrc

# .bazelrc

# Build using platforms by default
build --incompatible_enable_cc_toolchain_resolution

Bzlmod

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")

WORKSPACE

Add this git repository to your WORKSPACE to use the compiler (NOTE: WORSKPACE setups will become obsolete soon, do not use for new projects)

<details> <summary> WORKSPACE </summary>
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")
</details>

Custom toolchain

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

Direct access to gcc tools

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"],
)

Build linkermap file

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",
)

Remote execution

This toolchain is compatible with remote execution

Building with the ARM Linux toolchain on Windows

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.