LoginSignup
33
20

More than 5 years have passed since last update.

Rustをcross compileしてRaspberry Pi3で動かすぞ!

Last updated at Posted at 2017-03-02

手元の良いマシンでRustのコンパイルして,それをRaspberry Pi3へ持っていって実行したい...

だけど,手元のマシンは x86_64 で,Raspberry Pi3は aarch64(ARM) だから持っていくだけでは実行できない...
ということで,Rustでクロスコンパイルをしてx86_64上でaarch64向けのバイナリを作りましょう!

環境

  • ビルド環境
    • Ubuntu 16.04.2 LTS 64bit
    • x86_64
  • Raspberry Pi3
    • ArchLinux ARM
    • aarch64

前提

Rust周りの開発環境は整っていることとします.(cargo buildで自分のアーキテクチャ向けのコンパイルは出来る.)

サマリ

別のアーキテクチャ向けにコンパイルできればよいので,cargo build --target <another architecture>ができるのがゴール.

RaspberryPi3はaarch64だったので,aarch64-unknown-linux-gnuに向けてコンパイル出来るようにする.

  1. rustupaarch64向けのtoolchainをインストール
    • rustup install nightly-aarch64-unknown-linux-gnu
    • ここではnightlyを使ってますが,お好みに合わせてどうぞ
  2. aarch64向けのリンカが必要なので,aarch64向けのgccをインストール
    • sudo apt install gcc-aarch64-linux-gnu
  3. デフォルトでaarch64向けにビルドするようにプロジェクト配下の.cargo/configに次のものを追加

    .cargo/config
    [build]
    target="aarch64-unknown-linux-gnu"
    
    [target.aarch64-unknown-linux-gnu]
    linker = "aarch64-linux-gnu-gcc"
    
  4. cargo build すると,aarch64向けのバイナリが生成されます

Raspberry Pi3に持っていって実行しましょう!!!

説明

rustupaarch64向けのtoolchainをインストール

通常だと,以下のようにその環境向け(例えばx86_64)のtoolchainしかインストールされていません.

$ rustup toolchain list
stable-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu (default)

がしかし,RaspberryPi3上でuname -mを叩くとaarch64と表示されるので,aarch64向けのtoolchainが必要そうです.

これを探すために$rustup target list | grep aarch64と叩くと以下のようになります.

$ rustup target list | grep aarch64
aarch64-apple-ios
aarch64-linux-android
aarch64-unknown-linux-gnu

linux向けのaarch64-unknown-linux-gnuが見つかりました!これを使うこととしますのでインストールします.

stableの場合
$ rustup install stable-aarch64-unknown-linux-gnu
nightlyの場合
$ rustup install nightly-aarch64-unknown-linux-gnu

これで一旦整ったと思い,おもむろに

$ cargo build --target=aarch64-unknown-linux-gnu

と叩くと,ld周りでエラーが出て,リンカがおかしいみたいだということがわかります.

aarch64向けのリンカが必要なので,aarch64向けのgccをインストール

ここ(https://github.com/japaric/ruststrap/blob/master/1-how-to-cross-compile.md) を見ていると,どうやら rustc がリンクを行うときにシステムのアーキテクチャのリンカをデフォルトで使ってしまうようで,指定してあげなければならないとのこと.

そこでまず,aarch64向けのリンカをインストールするためにgccごと入れちゃいます

$ sudo apt install gcc-aarch64-linux-gnu

デフォルトで aarch64 向けにビルドするようにプロジェクト配下の .cargo/config に次のものを追加

先の作業でリンカが手に入ったのでcargoに使うリンカを教えてあげましょう.

そのためにプロジェクト配下の.cargo/configを以下のように書き換えます.

.cargo/config
[build]
target="aarch64-unknown-linux-gnu"

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

このようにすることで,cargo buildの際のデフォルトtargetaarch64-unknown-linux-gnuになり一々指定しなくて良くなります.

また,targetaarch64-unknown-linux-gnuの時のlinkerを指定してあげることでaarch64向けのビルドの際にはaarch64向けのリンカを使ってくれる様になります.

結論

Write once in Rust, run anywhere!
(極めて言い過ぎ

33
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
20