背景
Rustとはコンパイルして実行可能ファイルを作成できるプログラミング言語の1つです。Rustにはクロスコンパイルの仕組みがあるので、IntelのCPUで動かしている64bitのUbuntuでARM v6(A, B, A+, B+, Zero)かv7(2B, 3B, 3B+)で動いているRaspbian用の実行ファイルをビルドしてみました。
備忘録としてまとめつつ、やったことを共有します。
使ったもの
Ubuntu18.04にRustをインストールしたPC
利用したrustupとcargoのバージョンはこちらです。$ rustup --version rustup 1.16.0 (beab5ac2b 2018-12-06) $ cargo --version cargo 1.32.0 (8610973aa 2019-01-02)
Raspberry Pi + Raspbian
Raspberry Pi の Zero(ARM v6) と 3B+(ARM v7) を 2018.11リリース版Stretchで動かして動作確認しました。Cargoプロジェクト
今回はironというwebフレームワークを利用したwebアプリを例としてビルド方法を説明します。(前回の記事で取り組んだものです。)下記のように~/gitprojects/rustの中に配置した前提で話を進めます。
sudo apt install git mkdir -p ~/gitprojects/rust cd ~/gitprojects/rust git clone https://github.com/asukiaaa/rust_iron_template_sample.git
UbuntuでARM向けのビルド環境を構築
ARM v6
ARM v6向けのgccをUbuntuにインストールします。sudo apt install gcc-arm-linux-gnueabi
rustupにARM v6向けのターゲットを追加します。
rustup target add arm-unknown-linux-gnueabi
Cargoのconfigファイル(無ければ新規作成)に、先ほどインストールしたgccをARM v6のビルドで利用することを記述します。
~/.cargo/config
[target.arm-unknown-linux-gnueabi] linker = "arm-linux-gnueabi-gcc"
これでCargoでARM v6向けのビルドができるようになりました。
ARM v7
ARM v7向けのgccをUbuntuにインストールします。sudo apt install gcc-arm-linux-gnueabihf
rustupにARM v7向けのターゲットを追加します。
rustup target add armv7-unknown-linux-gnueabihf
Cargoのconfigファイル(無ければ新規作成)に、先ほどインストールしたgccをARM v7のビルドで利用することを記述します。
~/.cargo/config
[target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc"
これでCargoでARM v7向けのビルドができるようになりました。
ARM向けにビルド
ARM v6
Cargoプロジェクトのディレクトリに移動します。cd ~/gitprojects/rust/rust_iron_template_sample
下記のコマンドでARM向けにビルドできます。
cargo build --target arm-unknown-linux-gnueabi
ビルドしたファイルは下記のパスにあります。
ls target/arm-unknown-linux-gnueabi/debug/rust_iron_template_sample -la -rwxr-xr-x 2 asuki asuki 42230084 2月 23 22:14 target/arm-unknown-linux-gnueabi/debug/rust_iron_template_sample
--releaseを付けると、ビルドの時間は長くなりますがサイズが小さくて処理が早いファイルを生成してくれます。
cargo build --target arm-unknown-linux-gnueabi --release
ls target/arm-unknown-linux-gnueabi/release/rust_iron_template_sample -la -rwxr-xr-x 2 asuki asuki 6240404 2月 21 19:42 target/arm-unknown-linux-gnueabi/release/rust_iron_template_sample
ARM v7
Cargoプロジェクトのディレクトリに移動します。cd ~/gitprojects/rust/rust_iron_template_sample
下記のコマンドでARM向けにビルドできます。
cargo build --target armv7-unknown-linux-gnueabihf
ビルドしたファイルは下記のパスにあります。
ls target/armv7-unknown-linux-gnueabihf/debug/rust_iron_template_sample -la -rwxr-xr-x 2 asuki asuki 41570772 2月 19 07:12 target/armv7-unknown-linux-gnueabihf/debug/rust_iron_template_sample
--releaseを付けると、ビルドの時間は長くなりますがサイズが小さくて処理が早いファイルを生成してくれます。
cargo build --target armv7-unknown-linux-gnueabihf --release
ls target/armv7-unknown-linux-gnueabihf/release/rust_iron_template_sample -la -rwxr-xr-x 2 asuki asuki 6198612 2月 19 07:16 target/armv7-unknown-linux-gnueabihf/release/rust_iron_template_sample
関連ファイルをzipで固めてRaspbianに配置
実行ファイルだけで動くプロジェクトなら、ARM v6向けはZeroなどに、ARM v7向けは3Bなどにファイル(先ほどの手順でlsで確認したもの)を配置して実行できます。しかし、今回ビルドしたプロジェクトはhandlebars-ironというテンプレートファイルを利用するライブラリ使っているため、Cargoで生成した実行ファイルに加えて、htmlを描画するためのテンプレートファイル一式(templatesディレクトリ)が必要です。
さらに、(サンプルプロジェクトには無いですけど)ironで扱う静的ファイルもビルドには含まれないため、publicディレクトリも一緒に扱う必要があります。
ということで、今回はそれらを下記のようなコマンドでzipに固めます。
ARM v6向け
mkdir -p releases/armv6 cp target/arm-unknown-linux-gnueabi/release/rust_iron_practice releases/armv6/ cp -r public releases/armv6/ cp -r templates releases/armv6/ cd releases zip -r armv6.zip armv6 cd ../
ARM v7向け
mkdir -p releases/armv7 cp target/armv7-unknown-linux-gnueabihf/release/rust_iron_practice releases/armv7/ cp -r public releases/armv7/ cp -r templates releases/armv7/ cd releases zip -r armv7.zip armv7 cd ../
作成したzipファイルは、scpで転送したり、SDカードをPCに接続してコピーしたりして、Raspbianに配置してください。
Raspbianで動作確認
ここからのコマンドはRaspberry Pi上で実行します。Raspberry PiのIpを調べておきます。
ip a show | grep 192
ファイルを展開してからプログラムを実行します。
ARM v6向け
unzip arm6.zip cd arm6 ./rust_iron_template_sample
ARM v7向け
unzip arm7.zip cd arm7 ./rust_iron_template_sample
Raspberry Piと同じWiFiに接続しているPCから。Raspberry PiのIPのRustのプログラムが管理しているポート(このプロジェクトの場合は3000番)にブラウザでアクセスすると、Raspberry Piが配信する内容を確認できます。
Rustで書いたWebアプリがRaspbianで動いていることを確認できました。
余談: rusqliteを使うプロジェクトもbundleオプションを付ければビルド可能
rusqliteとはsqlite3というデータベースを利用するライブラリです。このライブラリを利用するプロジェクトをコンパイルする場合、以前は関連するlinuxパッケージをPCにインストールする必要があったようです。
しかし、自分が試したときは、Cargo.tmolのbundleオプションを有効にすれば、ビルドできました。
Cargo.toml
[dependencies] rusqlite = { version = "0.16", features = ["bundled"] }
ライブラリの更新によって上記の設定だけでビルドできるようになったのかもしれません。
まとめ
UbuntuでビルドしたファイルをRaspbianで動かせました。また、sqliteを利用するライブラリも難なくビルド出来ることが分かりました。
何かの参考になれば嬉しいです。
参考
Cross Compiling Rust for the Raspberry Pi on LinuxRust でクロスコンパイルして Raspberry Pi Zero W で動かす
0 件のコメント :
コメントを投稿