はじめに
最近流行りのRust。meta-rustを使えばyocto環境でもRustアプリケーションを使えるようにできる。
meta-rustネタとしてはこちらに先を越されたが、試したブランチがsumo、rockoと古めなのと観点がRust開発者よりなので、本記事ではすこしyocto的に見てみる。
ちなみに筆者はRust初心者未満なのでRustの解説はリンク先の方を参照してください。
ターゲット環境はラズベリーパイ3。
環境構築
いつもの。
ソース取得
ラズベリーパイ環境のビルドのためのレイヤをダウンロードする。
$ mkdir -p rpi-thud/layers $ cd rpi-thud/layers $ git clone git://git.yoctoproject.org/poky.git -b thud $ git clone git://git.yoctoproject.org/meta-raspberrypi -b thud $ git clone git://git.openembedded.org/meta-openembedded -b thud
rustのパッケージを含んでいるmeta-rust
はsumo(2.5)以降ブランチを切っていない。
masterブランチのLAYERSERIES_COMPAT
を確認すると次のようになっているので、thud
、warrior
を使用したい場合はmasterブランチを使用することになる。
LAYERSERIES_COMPAT_rust-layer = "rocko sumo thud warrior"
次のコマンドでソースを取得する。
$ git clone https://github.com/meta-rust/meta-rust.git $ cd ../
環境変数の設定
$ source layers/poky/oe-init-build-env build_rust
コマンド実行後はビルドディレクトリに自動的に移動される。
ここではbuild_rust
としている。
レイヤの追加
ビルド対象にレイヤを追加する。 依存関係があるので追加する順番は変更しないこと。
$ bitbake-layers add-layer ../layers/meta-openembedded/meta-oe $ bitbake-layers add-layer ../layers/meta-openembedded/meta-python $ bitbake-layers add-layer ../layers/meta-openembedded/meta-networking $ bitbake-layers add-layer ../layers/meta-raspberrypi $ bitbake-layers add-layer ../layers/meta-rust
local.confの修正
MACHINEをラズベリーパイ3にする。
INITはsystemdで。あとは細かい設定。
MACHINE = "raspberrypi3" DL_DIR ?= "${TOPDIR}/../downloads" # enable uart ENABLE_UART = "1" # systemd DISTRO_FEATURES_append = " systemd pam" VIRTUAL-RUNTIME_init_manager = "systemd" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" VIRTUAL-RUNTIME_initscripts = "" IMAGE_INSTALL_append = " rust-hello-world"
ビルド
Linuxイメージを生成する。
$ bitbake core-image-base
Rustバージョンの確認
Rustのバージョンを確認。
$ find ./tmp/work -maxdepth 2 -and -type d -and -name 'rust*' | xargs ls ./tmp/work/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi/rust-hello-world: git-r0 ./tmp/work/x86_64-linux/rust-cross-arm: 1.33.0-r0 ./tmp/work/x86_64-linux/rust-llvm-native: 1.33.0-r0 ./tmp/work/x86_64-linux/rust-native: 1.33.0-r0
最新のstableが1.34.1
みたいなので若干古い?。ここらへんは疎いので。
SDの作成
ddコマンドでマイクロSDにイメージを書き込む
$ sudo dd if=tmp/deploy/images/raspberrypi3/core-image-base-raspberrypi3.rpi-sdimg of=/dev/sdX bs=100M
/dev/sdX
はマイクロSDのデバイスなので適宜sdb
やsdc
などに書き換えること。
ddの代わりにEtcherを使用することもできる。
実行確認
作成したマイクロSDをラズベリーパイ3に挿入し電源をいれ、rust-hello-world
を実行してみる。
# rust-hello-world Hello, world!
問題なく動作した。
開発環境の確認
yoctoではbitbakeで作成したLinuxイメージ上で動くプログラムを開発するためのクロスコンパイル環境を作成することができる。 これは、作成したLinux上にインストールされているライブラリを使用するために必要な情報が全て含まれている。
基本的にはGCCのC/C++向け環境となっているので、Rustの開発環境はどのようになっているか確認する。
まず、次のコマンドでSDKを作成する。
$ bitbake core-image-base -c populate_sdk
tmp/deploy/sdk
にインストーラスクリプトが作成されるので、次のコマンドを実行しSDKをインストールする。
$ tmp/deploy/sdk/poky-glibc-x86_64-core-image-base-cortexa7t2hf-neon-vfpv4-toolchain-2.6.2.sh
インストール先は自由に設定できるが、デフォルトでは/opt/poky/2.6.2
にインストールされる。
$ source /opt/poky/2.6.2/environment-setup-cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi
環境変数CC
の値が次のようになっていればSDKが使用できる。
$ echo $CC arm-poky-linux-gnueabi-gcc -march=armv7ve -mthumb -mfpu=neon-vfpv4 -mfloat-abi=hard -mcpu=cortex-a7 --sysroot=/opt/rust/2.6.2/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi
最低でもrustc
が入っていなければRust向けの開発環境とは言えないので探してみる。
SDKでインストールされたファイルは/opt/poky/2.6.2/sysroot
以下にあるためそこの下をfindする。
$ cd /opt/poky/2.6.2/sysroot $ sudo find -iname 'rustc'
見つからない。
*rust*
や*cargo*
などで検索してもRustの開発に必要なコマンドやファイルが見つからないことがわかる。
まとめ
低レイヤ強くなりたい組込み屋さんのブログで次のように言っている。
どうしてもYoctoでビルドしてdistributionとして配布したい、という状況でなければ、わざわざYoctoでビルドするうまみはなさそうです。
こちらは開発環境の古さなどの観点からの言葉なので若干言いたいポイントは異なるのだろうとも思うが、 Rustでの開発の観点で言えば全面的に同意できる。
ただ、SDKにRustの開発環境が含まれないことからmeta-rust
ではyoctoで作成したLinuxの上で開発・デバッグを行うことは目的に含まれていない。そのため「Yoctoでの配布目的以外ではうまみがない」のではなく「使えない」で良いと思う。
個人的にyoctoのうまみは一度作った設定済みのLinuxイメージを量産できるところにあると思っている。meta-rust
もRustで書かれたアプリケーションをyoctoのイメージに取り込むのがこれを使用する目的であって、この観点ではmeta-rust
のスタンスも間違ってはいないし存在意義もあると思っている。
yocto環境でのRustの開発環境を期待しているとハズレ感はあると思う。
異論は認める!