tomato·bazeldocs v0 · latest
Docs/Reference/Modules/rules_cc_cross

rules_cc_cross

Hermetic ARM/RISC-V/x86 cross-compiler toolchains for embedded Bazel builds (seL4, microkit, bare-metal).

Latest0.1.0
Versions1
CategoryBazel rules
MaintainersMatt Marshall
Registryhttps://registry.tbzl.dev/modules/rules_cc_cross/
Sourcegithub.com/tomato-bazel/rules_cc_cross
MODULE.bazelstarlark
bazel_dep(name = "rules_cc_cross", version = "0.1.0")

View source & releases on GitHub ↗

Hermetic ARM/RISC-V/x86 cross-compiler toolchains for embedded Bazel builds (seL4, microkit, bare-metal).

Status: v0.1.0

Implemented:

  • aarch64-none-elf via the ARM GNU Toolchain (release 14.2.rel1).
  • Hosts: macOS arm64, macOS x86_64, Linux x86_64, Linux aarch64.
  • All tarballs verified against arm.com’s published sha256s.
  • cc_toolchain_config with -ffreestanding -nostdlib defaults suitable for seL4 / microkit protection domains.
  • One smoke example: examples/aarch64_hello.

Roadmap:

  • 0.2.0 — riscv64-elf target (riscv-gnu-toolchain).
  • 0.3.0 — x86_64-elf target.
  • 0.4.0 — newlib-nano / picolibc selectors as feature toggles.

Install

.bazelrc:

common --registry=https://registry.fastverk.com/
common --registry=https://bcr.bazel.build/

MODULE.bazel:

bazel_dep(name = "rules_cc_cross", version = "0.1.0")

cc_cross = use_extension("@rules_cc_cross//cc_cross:extensions.bzl", "cc_cross")
cc_cross.toolchain(target = "aarch64-none-elf", version = "14.2.rel1")
use_repo(cc_cross, "arm_gnu_aarch64_none_elf")

register_toolchains("@arm_gnu_aarch64_none_elf//:all")

Use

Cross-compile any cc_binary for bare-metal aarch64:

platform(
    name = "aarch64_none_elf",
    constraint_values = [
        "@platforms//cpu:aarch64",
        "@platforms//os:none",
    ],
)

cc_binary(
    name = "my_pd",
    srcs = ["pd.c"],
    target_compatible_with = [
        "@platforms//cpu:aarch64",
        "@platforms//os:none",
    ],
)
bazel build //:my_pd --platforms=//:aarch64_none_elf

Layout

cc_cross/
├── extensions.bzl              # `cc_cross` module extension
├── defs.bzl                    # public rule re-exports
└── private/
    ├── arm_gnu_toolchain.bzl   # repo rule (download + materialize)
    ├── cc_toolchain_config.bzl # cc_toolchain_config rule
    ├── known_versions.bzl      # (version, host) -> sha256 map
    └── arm_gnu.BUILD.tpl       # BUILD.bazel template

Usage#

Real usage, taken from the module’s examples/.

examples/aarch64_hello/BUILD.bazel

"""Smoke test: cross-compile a bare-metal aarch64 hello.

`bazel build //examples/aarch64_hello:hello --platforms=:aarch64_none_elf`
should produce an ELF that:

    file bazel-bin/examples/aarch64_hello/hello

reports as `ELF 64-bit LSB executable, ARM aarch64`.
"""

load("@platforms//host:constraints.bzl", "HOST_CONSTRAINTS")

package(default_visibility = ["//visibility:public"])

platform(
    name = "aarch64_none_elf",
    constraint_values = [
        "@platforms//cpu:aarch64",
        "@platforms//os:none",
    ],
)

cc_binary(
    name = "hello",
    srcs = ["hello.c"],
    # seL4-style: leave allocation, entry point, and the linker
    # script to the caller. This binary won't run on a real OS;
    # it's the cross-compile smoke test.
    linkopts = [
        "-Wl,--entry=_start",
        "-Wl,--no-warn-rwx-segments",
    ],
    target_compatible_with = [
        "@platforms//cpu:aarch64",
        "@platforms//os:none",
    ],
)

Conformance#

1 finding across 1 invariant. 8 contested atoms. See how gating works or the full report.

D2 a non-dev register_toolchains propagates to every transitive consumer why this matters ↗
versiontoolchain
0.1.0@arm_gnu_aarch64_none_elf//:all

Contested atoms

Third-party modules where this module resolves a different version than others do. Not a violation of anything this module did — it is the actionable form of a registry-level convergence finding, and the sentence a maintainer can act on.

AtomResolved hereElsewhere
apple_support 1.24.2 2.2.0 ×1
bazel_skylib 1.8.2 1.9.0 ×2
nlohmann_json 3.6.1 3.12.0.bcr.1 ×1
protobuf 33.4 34.0.bcr.1 ×2
rules_jvm_external 6.7 6.8 ×4
rules_python 1.7.0 2.0.1 ×1
rules_swift 3.1.2 3.6.1 ×1
upb 0.0.0-20220923-a547704 0.0.0-20230516-61a97ef ×1

Dependencies#

rules_cc_cross in the registry graph — what it depends on (left) and what depends on it (right).

Depends on

platforms1.0.0bazel_skylib1.8.2rules_cc0.2.17rules_shell0.6.1devstardoc0.7.2dev

Versions#

1 published version, newest first. Each resolves to an immutable, integrity-checked archive.

VersionIntegrity (sha256)Source archive
0.1.0 latest sG57wc6T5+nCkNbT… tag archive ↗

Changelog#

All notable changes to rules_cc_cross. The format is loosely Keep a Changelog — version headers mirror the published bazel-registry entries.

0.1.0 — pinned checksums

  • All four (host, target) ARM GNU Toolchain tarballs now verified against arm.com’s published sha256s (no more unsigned downloads).

0.0.1 — first cut

  • cc_cross module extension with one tag class: toolchain(target, version).
  • arm_gnu_toolchain repo rule fetching the ARM GNU Toolchain (aarch64-none-elf) from developer.arm.com, multi-host (macOS arm64/x86_64, Linux x86_64/aarch64).
  • cross_cc_toolchain_config cc_toolchain_config with -ffreestanding, -fno-builtin, -nostdlib, -Wl,--build-id=none defaults.
  • Smoke example: //examples/aarch64_hello:hello.
  • Known limitations: tarballs unsigned (sha256s empty); only aarch64-none-elf wired up; no riscv / x86 yet.

← All modules