Help us understand the problem. What is going on with this article?

ラズパイに向けてRustをクロスコンパイル!

想定読者

  • Rustが好きだ!Rustが使いたいんだ!でも、ラズパイに向けたクロスコンパイル方法がわからない!
  • クロスコンパイルのやり方は知らなくても、どんなのかは知っている
  • Dockerにアレルギー反応を起こさない
  • アーキテクチャの名前にアナフィラキシー・ショックを起こさない
  • ツールチェイン、リンカという言葉に拒絶反応を起こさない

という人向けの、初心者による初心者のための記事です。
(というか私の備忘録です。)

環境

開発環境
OS:Ubuntu 20.04 LTS
アーキテクチャ:x86_64

実行環境
ハードウェア:RaspberryPi4 typeB 4GB
OS:Raspbian(Version: May 2020)
アーキテクチャ:ARMv7

目標

rust-pushordを用いたRust製GUIアプリケーションをRaspberryPi用にクロスコンパイルして、Raspbian上でも動かすこと。

流れ

  1. rustの公式Dockerイメージを使って開発環境を整える
  2. コンテナ内に「Hello World」を用意する。
  3. CargoへARMv7向けにコンパイルするように設定する
  4. ツールチェインとリンカを用意する
  5. コンパイルの確認
  6. rust-pushordの依存ライブラリを用意する(SDL2)
  7. rust-pushordのexampleをコンパイルする
  8. RaspberryPi上で実行する
  9. 喜びの舞を踊る(option

1. rustの公式Dockerイメージを使って開発環境を整える

Dockerのインストール等は割愛させていただきます。

インストールが終わったら早速、Rustの公式イメージゲットだぜ!

bash
docker container run -v ホスト:コンテナ -it --rm rust:latest /bin/bash

(注:もしかしたらsudoがいるかもね。)

将来的なことを考えるとDockerfileを用意したほうがいい気がするけど、ここでは「初心者による初心者のための」ということで作りません。

2. コンテナ内に「Hello World」を用意する。

初めに、コンテナ内で「Hello World」のコードを作り、確認のため普通(開発環境アーキテクチャ向け)に実行します。

bash
root@abcd12345:/# export USER=root
root@abcd12345:~# cd
root@abcd12345:~# cargo new hello
root@abcd12345:~# cd hello
root@abcd12345:~/hello# cargo run

これで「Hello World」が帰ってきたらOK。

3. CargoへARMv7向けにコンパイルするように設定する

次に「.cargo/config」を作成しクロスコンパイルをするための設定を記述します。

bash
root@abcd12345:~/hello# mkdir .cargo
root@abcd12345:~/hello# cat <<EOF > .cargo/config
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
EOF

これは
「cargoでtargetにarmv7-unknown-linux-gnueabihfが指定されたら、リンカにarm-linux-gnueabihf-gccを使ってね!」
とcargoにお願いするためのものです。

4. ツールチェインとリンカを用意する

さて、次に用意しないと行けないのが「ARMv7用の、ツールチェインとリンカ」です。

bash
# ツールチェインの追加
rustup target add armv7-unknown-linux-gnueabihf

# 備考:用意されているツールチェインは次のコマンドで表示できます
# rustup target list

# リンカの用意
apt install gcc-arm-linux-gnueabihf

5. コンパイルの確認

さぁ、準備ができたので、コンパイルがちゃんと通るか確かめて見ましょう!

bash
root@abcd12345:~/hello# cargo build --target=armv7-unknown-linux-gnueabihf

実際にARMv7上で動くかは、RaspbianのDockerイメージを使ってみたり、実機でテストしてください。

6. rust-pushordの依存ライブラリを用意する(SDL2)

CUIだと寂しいのでGUIアプリをコンパイルしてみましょう!

クロスプラットフォームでさくっとできるのにrust-pushordというのがあるので、これを使います。

任意の場所にGitHubからクローンして、コンパイルの設定を行い、exampleをコンパイルしましょう。
(2020/07/03追記)

bash
root@abcd12345:~# git clone https://github.com/KenSuenobu/rust-pushrod.git
root@abcd12345:~# cd rust-pushrod
root@abcd12345:~/rust-pushrod# mkdir .cargo 
root@abcd12345:~/rust-pushrod# cat <<EOF > .cargo/config
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
EOF
root@abcd12345:~/rust-pushrod# cargo build --target=armv7-unknown-linux-gnueabihf --example timer

残念なことに、失敗しますね。。かなしみ。

... "-ldl" "-lutil"
  = note: /usr/lib/gcc-cross/arm-linux-gnueabihf/8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lSDL2
          /usr/lib/gcc-cross/arm-linux-gnueabihf/8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lSDL2_image
          /usr/lib/gcc-cross/arm-linux-gnueabihf/8/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lSDL2_ttf
          collect2: error: ld returned 1 exit status


error: aborting due to previous error

error: could not compile `rust-pushrod`.

To learn more, run the command again with --verbose.

どうやらrust-pushordに必要なSDL2が足りていないようです。

では「依存関係を解決するためにapt install libsdl2-devすればいいのか」というと、そうは問屋がおろしません。

なぜなら、必要としているSDL2は「ARMv7向け」だからです。

ということで、次のようにしないといけません。

bash
# マルチアーキテクチャでarmhfを有効にする。
# また有効にしたあと、updateが必要です。(2020/07/03追記)
dpkg --add-architecture armhf
apt update

# 本当は、armhf向けのパッケージが必要とする必須の
# 基本的なarmhf向けのアプリをインストールする必要があります。
# しかし、Rustの公式Dockerイメージには、もうすでに入ってるのでスキップします。
# apt install crossbuild-essential-armhf

# 必要なSDL2のライブラリをインストール
apt install libsdl2-dev:armhf libsdl2-image-dev:armhf libsdl2-ttf-dev:armhf

これで依存ライブラリも揃いました。もう一度コンパイルして、うまく行くことを確認してみてください。

bash
root@abcd12345:~/rust-pushrod# cargo build --target=armv7-unknown-linux-gnueabihf --example timer

8. RaspberryPi上で実行する

コンパイルしてできたものを共有フォルダに移し、ホスト側に取り出し、RaspberryPiに持っていってください。

そして実行ししっかりと動くか確認してみましょう。
ついに、RustがRaspberryPi上で動くはずです。

(画像は明日くらいに載せます。(現在:2020/6/30))
(2020/07/03追記)
Screenshot from 2020-07-03 17-11-04.png

9. 喜びの舞を踊る(option

♪(((^-^)八(^∇^)))♪

お疲れ様でした。今回、私自身が「Rustで組み込み!初クロスコンパイル!」ということで、情報を漁るも、簡単には見つからなかったため、記事にさせていただきました。(特にライブラリの依存関係を解消するあたり)

誰かの参考になれば幸いです。

mutuya
♪(((^-^)八(^∇^)))♪
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした