みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

YoctoProject langdaleのRust事情

はじめに

以前にyoctoでもRustで、YoctoProjectで作成したLinuxにRustのプログラムを組み込む方法を紹介した。当時はmeta-rustを使用する必要があり、かつSDKでRustのプログラムをビルドすることもできなかった。

この記事が2019年で、あれから数年経ちhonister(3.4)でRustはpokyに組み込まれた。 langdale(4.1)の環境でRustはどうなったのか見てみる。

ちなみに筆者は2019年と変わらずRust入門前である。する予定はない。

環境構築

実機のほうが楽しいのでラズベリーパイ4向けの環境で試す。

作業環境

$ mkdir -p ~/yocto/rpi-langdale
$ cd ~/yocto/rpi-langdale

pokyの取得

$ git clone -b langdale git://git.yoctoproject.org/poky.git

環境変数の設定

$ source poky/oe-init-build-env

レイヤの取得

$ bitbake-layers layerindex-fetch meta-raspberrypi

local.confを編集

conf/local.confに下記の部分を追加

MACHINE = "raspberrypi4-64"
DL_DIR = "${TOPDIR}/../downloads"

# systemd
DISTRO_FEATURES:append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""

# enable uart
ENABLE_UART = "1"

# License flag for wireless firmware.
LICENSE_FLAGS_ACCEPTED = "synaptics-killswitch"

# SSH server
EXTRA_IMAGE_FEATURES += "ssh-server-openssh"

# Rust helloworld
IMAGE_INSTALL:append = " rust-hello-world"

ビルド

core-image-baseを作成する。

$ bitbake core-image-base

実行結果

イメージをマイクロSDに書き込み、ラズベリーパイ4でrust-hello-worldコマンドを実行してみる。

# rust-hello-world
Hello, world!

SDKの作成

SDKを作成してみる。

$ bitbake core-image-base -c populate_sdk

インストールして、rustcやcargoがあるか見てみる。

$ pushd ./tmp/deploy/sdk
$ ./poky-glibc-x86_64-core-image-base-cortexa72-raspberrypi4-64-toolchain-4.1.sh
$ sudo find /opt/poky/4.1 -name 'rustc'
$ sudo find /opt/poky/4.1 -name 'cargo'
$ popd

どちらも見当たらない。

SDK_TOOLCHAIN_LANGS

SDK_TOOLCHAIN_LANGSによると

Specifies programming languages to support in the SDK, as a space-separated list. Currently supported items are rust and go.

SDKでサポートされるプログラミング言語を設定する(ただしrustとgoに限る)。とある。この変数はlangdaleから使えるようになったらしい。

local.confに下記を追加してみる。

SDK_TOOLCHAIN_LANGS:append = " rust"

再度、作成&インストール、検索

$ bitbake core-image-base -c populate_sdk
$ pushd ./tmp/deploy/sdk
$ ./poky-glibc-x86_64-core-image-base-cortexa72-raspberrypi4-64-toolchain-4.1.sh
$ sudo find /opt/poky/4.1 -name 'rustc'
/opt/poky/4.1/sysroots/x86_64-pokysdk-linux/usr/bin/rustc
$ sudo find /opt/poky/4.1 -name 'cargo'
sudo find /opt/poky/4.1 -name 'cargo'
$ popd

こんどは見つかった。

Rustプログラムのビルド

The Rust Programming Language 日本語版Hello, Cargo!の手順でプログラムを作成してみる。

SDK環境変数の設定

SDKのツールやクロスコンパイルの環境を設定するために

bitbakeを実行したものとは別の端末を開いて、下記のコマンドを実行する。

$ . /opt/poky/4.1/environment-setup-cortexa72-poky-linux

こちらでも良い

$ source /opt/poky/4.1/environment-setup-cortexa72-poky-linux

これでrustcやcargoが使える

rustc

$ which rustc
/opt/poky/4.1/sysroots/x86_64-pokysdk-linux/usr/bin/rustc
$ rustc --version
rustc 1.63.0

cargo

$ which cargo
/opt/poky/4.1/sysroots/x86_64-pokysdk-linux/usr/bin/cargo
mickey@strawberry:~$ cargo --version
cargo 1.63.0

数年前試したときから進化していることがわかる。

プログラムの作成

手順に沿ってCargoプロジェクトを作成する。

$ cargo new hello_cargo
$ cd hello_cargo

ビルド。

$ cargo build

ビルドされた生成物。

$ tree ./target/
./target/
├── CACHEDIR.TAG
├── aarch64-poky-linux-gnu
│   ├── CACHEDIR.TAG
│   └── debug
│       ├── build
│       ├── deps
│       │   ├── hello_cargo-65bf9bff47909b38
│       │   └── hello_cargo-65bf9bff47909b38.d
│       ├── examples
│       ├── hello_cargo
│       ├── hello_cargo.d
│       └── incremental
│           └── hello_cargo-25efxll36h9y8
│               ├── s-ggddk5xlfe-1vy0jcl-l5dttugncxvm
│               │   ├── 1ic4wft24p16s9n1.o
│               │   ├── 1kifghi4qd2733gz.o
│               │   ├── 1wxvrj2sbzov2l74.o
│               │   ├── 49ixtbxqou4rnkyl.o
│               │   ├── 4pssy91efjuqygdf.o
│               │   ├── 53t2ya8toy7chqy6.o
│               │   ├── 5ake8hymu295aas8.o
│               │   ├── 5dwbnxw6sj6cm5mi.o
│               │   ├── dep-graph.bin
│               │   ├── query-cache.bin
│               │   └── work-products.bin
│               └── s-ggddk5xlfe-1vy0jcl.lock
└── debug
    ├── build
    ├── deps
    ├── examples
    └── incremental

13 directories, 18 files

ラズベリーパイ向けとなるARM aarch64のバイナリがビルドされている。

$ file ./target/aarch64-poky-linux-gnu/debug/hello_cargo
./target/aarch64-poky-linux-gnu/debug/hello_cargo: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=bf0c892f05640e6e0ee44745bd8edb6532df45be, for GNU/Linux 3.14.0, with debug_info, not stripped

動作確認

ラズベリーパイに送りつけてみる。

$ scp ./target/aarch64-poky-linux-gnu/debug/hello_cargo root@raspberrypi4-64.local:/home/root

実機で下記を実行する。

# cd
# ./hello_cargo
Hello, world!

まとめ

YoctoProjectでのRust事情を確認してみた。 honisterでmeta-rustが不要になり、langdaleではSDK_TOOLCHAIN_LANGSを設定することで、SDKでもRustが使用可能になった。

数年前と比較すると格段に進歩しているようだ。