How to add a Buildroot package for a Cargo crate
Proper support for Rust and Cargo in Buildroot is available in the "feature/rust" branch of this (personal) Buildroot repository.
In this article, we will explain how to add a Buildroot package for a Cargo crate (namely "hello-rust"). A Cargo package infrastructure may be added in the future, to make the package development easier.
We will take the example of building a QEMU/Aarch64 system, which will include the crate.
Creation of the Package
As the package for the "hello-rust" is of no use for upstream Buildroot, the package will be added to a project-specific directory. This type of set-up is described in the section 9.2 of the Buildroot user manual.
First, create the project-specific directory, including the directory for the package:
Then, add a Makefile fragment to declare the new package:
echo 'include $(sort $(wildcard $(BR2_EXTERNAL)/package/*/*.mk))' \ > $HOME/src/br2-ext-rust/external.mk
Finally, add a file to declare a configuration entry for the new package:
Now is the time to create the package itself. Create a file named
$HOME/src/br2-ext-rust/package/hello-rust/Config.in
with the following
contents:
config BR2_PACKAGE_HELLO_RUST bool "hello-rust" depends on BR2_PACKAGE_HOST_CARGO help "Hello World!" program written in Rust
Next, create the file
$HOME/src/br2-ext-rust/package/hello-rust/hello-rust.mk
, with the following
contents:
################################################################################ # # hello-rust # ################################################################################ HELLO_RUST_VERSION = 0.1.1 HELLO_RUST_SITE = $(HOME)/src/hello-rust HELLO_RUST_SITE_METHOD = local HELLO_RUST_LICENSE = Public Domain HELLO_RUST_DEPENDENCIES = host-cargo HELLO_RUST_CARGO_ENV = \ CARGO_HOME=$(HOST_DIR)/usr/share/cargo \ RUST_TARGET_PATH=$(HOST_DIR)/etc/rustc HELLO_RUST_CARGO_OPTS = \ --target=$(GNU_TARGET_NAME) \ --manifest-path=$(@D)/Cargo.toml ifeq ($(BR2_ENABLE_DEBUG),y) HELLO_RUST_CARGO_MODE = debug else HELLO_RUST_CARGO_MODE = release endif HELLO_RUST_CARGO_OPTS += --$(HELLO_RUST_CARGO_MODE) define HELLO_RUST_BUILD_CMDS $(TARGET_MAKE_ENV) $(HELLO_RUST_CARGO_ENV) \ cargo build $(HELLO_RUST_CARGO_OPTS) endef define HELLO_RUST_INSTALL_TARGET_CMDS $(INSTALL) -D \ $(@D)/target/$(GNU_TARGET_NAME)/$(HELLO_RUST_CARGO_MODE)/hello-rust \ $(TARGET_DIR)/usr/bin/hello-rust endef $(eval $(generic-package))
Building the Firmware Image
First, clone the Buildroot repository with Rust support and checkout the branch:
git clone https://github.com/elebihan/buildroot cd buildroot git checkout --track origin/feature/rust
To create a firmware image for a QEMU/Aarch64 system, a custom defconfig file, with the proper configuration for building Cargo crates, will be used. Create the defconfig file as follow:
cat <<EOF > qemu_aarch64_virt_rust_defconfig BR2_aarch64=y BR2_TOOLCHAIN_EXTERNAL=y BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" BR2_SYSTEM_DHCP="eth0" BR2_LINUX_KERNEL=y BR2_LINUX_KERNEL_CUSTOM_VERSION=y BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.5" BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux-4.5.config" BR2_TARGET_ROOTFS_INITRAMFS=y # BR2_TARGET_ROOTFS_TAR is not set BR2_PACKAGE_HOST_CARGO=y BR2_PACKAGE_HOST_RUST=y EOF
Then, initialize the build environment, specifying the project-specific directory, as well as the custom defconfig:
make O=$HOME/build/demo-rust/qemu/aarch64 \ BR2_EXTERNAL=$HOME/src/br2-ext-rust \ BR2_DEFCONFIG=qemu_aarch64_virt_rust_defconfig \ defconfig
Edit the configuration to select the "hello-rust" package, available in the "User-provided options" menu.
Start the build:
When the build is finished, check the hello-rust program is available on the target:
Run Test Program from System
Now, you can start your system using QEMU:
qemu-system-aarch64 \ -nographic \ -M virt \ -cpu cortex-a57 \ -smp 1 \ -kernel $HOME/build/demo-rust/qemu/aarch64/images/Image \ -append "console=ttyAMA0" \ -netdev user,id=eth0 \ -device virtio-net-device,netdev=eth0 \ -serial mon:stdio
Log as "root" (no password) and execute the test program:
That's it!