ラズパイで動くバイナリプログラムをRustでクロスコンパイルするための基本手順
※ 当ページには【広告/PR】を含む場合があります。
2022/04/14

普段からラズパイを使う身としては、簡単なお役立ちツールをバイナリから動かしたい時が多々あります。
ただ、ラズパイはCPUアーキテクチャがARMv6~8で設計されているので、Linuxで動作していた自作のシェルコマンドを簡単に移植できるとは限りません。
ここでは、Rustのクロスコンパイルを使って、別の開発環境からビルドしたシェルプログラムを実際のラズパイ4で動かした際の手順を防備録的にまとめておきます。
開発機でラズパイ用バイナリプログラムをRustでビルドする
まずRustのビルドターゲットの設定についてですが、
ARMv6(ラズパイゼロ/1系):
rustup target add arm-unknown-linux-gnueabihf
ARMv7(2/3/4系):
rustup target add armv7-unknown-linux-gnueabihf
で使い分けます。
なお、出力させるバイナリをgnuではなくmusl版で仕上げることを所望する場合には、
ARMv6(ラズパイゼロ/1系):
rustup target add arm-unknown-linux-musleabihf
ARMv7(2/3/4系):
rustup target add armv7-unknown-linux-musleabihf
とするのが作法のようです。
ツールチェーンを準備する
次にARMアーキテクチャ向けのツールチェーンを確認しましょう。
ARMデベロッパーサイト公式から最新のGNUツールチェーンをダウンロードします。
今回は開発環境をLinuxOSで行うのでターゲットに合わせて、
ラズパイゼロ/1用:
AArch32 target with hard float (arm-linux-gnueabihf)
ラズパイ2/3/4用:
AArch32 target with hard float (arm-none-linux-gnueabihf)
を拾ってきます。
ファイルがダウンロードできたら、解凍後に中身を何処かに保管しておきます。
コンパイラが利用できるようにするため、PATH変数を通しておきましょう。
export PATH="$HOME/ツールチェーンを展開したフォルダ/bin:$PATH"
#例としてラズパイゼロ/1の場合:
#export PATH="$HOME/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin:$PATH"
#例としてラズパイ2/3/4の場合:
#export PATH="$HOME/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/bin:$PATH"
必要に応じて
.bashrc
なお、直接公式からツールチェーンをダウンロードして来なくとも、特定のOSではパッケージ版が提供されているので、場合によりそちらを使った方が楽にインストールできます。
例えばUbuntu/Debian系の場合、
$ sudo apt install gcc-arm-linux-gnueabihf
からダウンロードできます。
Debian系の場合には、
$ sudo apt install binutils-arm-linux-gnueabihf
が同様に利用できます。
また、MacOSからはhomebrewを使って、
$ brew install arm-linux-gnueabihf-binutils
からインストール可能です。
新規でRustプロジェクトを作成する
Cargoから簡単なプロジェクトを新規作成します。
ここでは
my_app
$ cargo new my_app
$ cd my_app && mkdir .cargo
$ touch .cargo/config.toml
ここで作った
.cargo/config.toml
[build]
#ラズパイゼロ/1のgnuリンカ
[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
#ラズパイ2/3/4のgnuリンカ
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-none-linux-gnueabihf-gcc"
もしもgnu(動的リンク)ではなくmusl(静的リンク)でリンカーを構成する際にはターゲットの方を、
#...以下を追記
[target.armv7-unknown-linux-musleabihf]
linker = "arm-linux-gnueabihf-ld"
[target.arm-unknown-linux-musleabihf]
linker = "arm-linux-gnueabihf-ld"
として追加してあげると良いでしょう。
プログラムのビルド
では先程のプロジェクト・
my-app
今回はラズパイ4でmuslターゲットでビルドするようにします。
#👇ラズパイゼロ/1でgnuの場合
#TARGET=arm-unknown-linux-gnueabihf
#👇ラズパイゼロ/1でmuslの場合
#TARGET=arm-unknown-linux-musleabihf
#👇ラズパイ2/3/4でgnuターゲット
#TARGET=armv7-unknown-linux-gnueabihf
#👇ラズパイ2/3/4でmuslターゲット
$ TARGET=armv7-unknown-linux-musleabihf
#バイナリをリリースビルド
$ cargo build --target $TARGET --release
これでバイナリが正常に生成されていればラズパイで動くバイナリが仕上がりました。
なお、出力されたバイナリはプロジェクトフォルダ内の
target/[ターゲット名]/release/my_app
デフォルトでは、プロジェクト名がそのままバイナリプログラム名になるのでご注意ください。
ラズパイ実機での動作確認
先程作ったバイナリがラズパイ4で動くかどうか確認してみます。
ラズパイ実機とは基本的にSSHで接続して利用することの方が多いと思いますので、scpで先程のバイナリを送ってみます。
とりあえずは例としてユーザー名を
pi
192.168.1.234
12345
$ scp -P 12345 -r ./target/$TARGET/release/my_app pi@192.168.1.234:/home/pi
後はSSHでインタラクティブでバイナリを実行してみます。
ターミナルからSSH接続を介し、
$ ssh pi@192.168.1.234 -p 12345 './my_app'
Hello, world!
と標準出力されたら正常に動作しています。
まとめ
今回はラズパイ用のバイナリプログラムを自作する際に、別環境でRustからクロスコンパイルを使って作成する方法を解説してみました。