rules_qemu provides Bazel rules and toolchains for running target binaries
with hermetic QEMU binaries.
The goal of this project is to provide fully hermetic QEMU toolchains and
supporting calling rules for the QEMU family, including qemu-user,
qemu-system, and qemu-img. Today, only qemu-user is supported.
The current qemu-user toolchains are backed by static Linux prebuilts from
hermeticbuild/qemu-user-prebuilt,
which publishes static qemu-user binaries for many QEMU versions.
Host execution platforms:
- Linux amd64 (
@platforms//os:linux,@platforms//cpu:x86_64) - Linux arm64 (
@platforms//os:linux,@platforms//cpu:aarch64)
Emulated Linux target CPUs:
aarch64armi386mips64ppcppc64leriscv32riscv64s390xx86_32x86_64
Current limitations:
- Only Linux
qemu-usertoolchains are registered. qemu-systemandqemu-imgrules/toolchains are planned but not implemented.- The default module extension currently downloads QEMU
11.0.0prebuilts.
Add rules_qemu to your MODULE.bazel and register the generated QEMU user
toolchains:
bazel_dep(name = "rules_qemu", version = "...")
qemu = use_extension("@rules_qemu//qemu/extension:qemu.bzl", "qemu")
use_repo(qemu, "qemu_user_toolchains")
register_toolchains("@qemu_user_toolchains//:all")Use qemu_binary to build an executable wrapper that runs a target-platform
binary through the matching QEMU user-mode emulator.
load("@rules_qemu//qemu:qemu_binary.bzl", "qemu_binary")
cc_binary(
name = "hello",
srcs = ["hello.c"],
)
qemu_binary(
name = "hello_riscv64",
binary = ":hello",
target_platform = "//platforms:linux_riscv64_musl",
)Then run it like any other Bazel executable:
bazel run //:hello_riscv64qemu_binary applies a platform transition to binary, selects the QEMU
toolchain for that target platform, and emits a hermetic launcher containing
the target binary and emulator in its runfiles.
The module extension creates one qemu-user toolchain per supported host and
target CPU pair. Bazel selects the toolchain from:
- the execution platform, such as Linux x86_64 or Linux aarch64
- the requested target platform passed to
qemu_binary
For example, on a Linux x86_64 executor, a target_platform with
@platforms//cpu:riscv64 selects the static qemu-riscv64 prebuilt for a
Linux amd64 host.
This repository includes an external-consumer smoke test in e2e/smoke.
cd e2e/smoke
bazel test //...The smoke workspace registers rules_qemu, builds simple C binaries for
multiple target platforms with the published LLVM toolchain, and runs them
through qemu_binary.
The intended scope is broader than user-mode emulation. Future work should add:
- hermetic
qemu-systemtoolchains and calling rules - hermetic
qemu-imgtoolchains and calling rules - version selection for prebuilts exposed through the module extension
- additional host platforms when static prebuilts are available