Arm 32bit 環境で Julia を動かす

# 本日は

- 2020 年 Julia アドベントカレンダー 5日目でございます.
- 今回は Julia を ラズパイで動かす方法を紹介します.

# 背景

- Windows向け で作られたアプリは(特殊なことをしない限りという意味で)そのままでは macOS, Linux で動作しません. これはソフトウェアに詳しくない人でも直感的に理解できると思います．Julia の開発陣は各プラットフォームに向けたバイナリーをプラットフォーム毎にビルドして提供しています. 
- 具体的にどの環境をサポートしているのかは [Currently supported platforms
](https://julialang.org/downloads/#currently_supported_platforms) で公開されています．皆さんのメインとして用いている PC は(マニアックな環境じゃない限り・・・) Tier1 のはずです.

> Julia is guaranteed to build from source and pass all tests on these platforms when built with the default options. Official binaries are always available and CI is run on every commit to ensure support is actively maintained.

つまり Tier1 としてサポートされているプラットフォームでは Julia は

- ソースからビルドがができる
- ソフトウェアのテストが通る
- 公式ページからバイナリーを入手できる
- PR などでコミットされるたびにCIが実行されている

## ラズパイは？

`ARMv7 (32bit)` の項目を見ると `Tier 3` となっています

> Tier 3: Julia may or may not build. If it does, it is unlikely to pass tests. Binaries may be available in some cases. When they are, they should be considered experimental. Ongoing support is dependent on community efforts.

つまりソースからビルドできるかもしれんしできへんかもしれん, まぁできても全てのテストが通るとは限らないし(意図しない動作をする可能性がある), バイナリはたまに提供されるけど，あくまでも試験的であり, 継続的にサポートされるかはコミュニティ次第

ってことです．

現状は Julia v1.0.x, v1.3.1 が提供されてます [oldreleases](https://julialang.org/downloads/oldreleases/) というページから入手することができます．ですが，ソフトウェアは常に進化するものなのでいつまでもこれに甘えてるわけにはいきません. 

Julia 1.5.3 を動かしたい場合はどうすればいいのでしょう？

簡単です（吐血）．自分で（吐血）ソースからビルドすればいいのです（吐血）

# ビルドする

Julia をビルドする方法は基本的に 色々頑張って `make` すること 以上です．簡単ですね（吐血）

https://github.com/JuliaLang/julia/blob/master/doc/build/arm.md

を読んでビルドしてみましょう．（多分こけます．色々頑張る必要があります）

## 少し楽をする

実は [jlcross](https://github.com/Julia-Embedded/jlcross) というリポジトリがあります．これは Docker イメージをビルドする時にArmv7向けのバイナリーを生成できることを利用しています．ビルドされたイメージからコンテナを一時的に生成しコンテナ内のデータをホスト環境（自分の環境）に持ってくることでラズパイで動作する Julia を得ることができます．

適当な Dockerfile を入手してイメージをビルドすればOKです．

```console
$ git clone https://github.com/Julia-Embedded/jlcross.git
$ cd jlcross/rpi3
$ docker build -t jl4rpi3 -f Dockerfile-v1.5.3 .
```

このコマンドはラズパイの上で動かす必要がなくコアがそれなりについている mac や Linux 環境で行うことができます．ビルドには依存関係も含め一からビルドされるのでとても時間がかかります．半日ほど待ちましょう．

## もうちょっと楽をする

Discord のインストラクションを参考にしましょう. 

https://discourse.julialang.org/t/have-a-try-julia-v1-5-1-for-arm32bit/45558

```console
yourmainPC $ ssh pi@raspberrypi.local # Assume You are going to login to your Pi via SSH
pi@raspberrypi $ curl -fsSL get.docker.com -o get-docker.sh && sh get-docker.sh
pi@raspberrypi $ sudo gpasswd -a $USER docker # if you like to skip `sudo`
pi@raspberrypi $ exit
yourmainPC $ ssh pi@raspberrypi.local # login again
pi@raspberrypi $ JL_VERSION=v1.5.3
pi@raspberrypi $ IMAGE_NAME=terasakisatoshi/jlcross:rpi3-${JL_VERSION}
pi@raspberrypi $ CONTAINER_NAME=jltmp_${JL_VERSION}
pi@raspberrypi $ docker run --name ${CONTAINER_NAME} $IMAGE_NAME /bin/bash
pi@raspberrypi $ docker cp ${CONTAINER_NAME}:/home/pi/julia-${JL_VERSION} .
pi@raspberrypi $ docker rm ${CONTAINER_NAME}
pi@raspberrypi $ ls 
julia-v1.5.3 # <---- this is it
pi@raspberrypi $ cd julia-v1.5.3/bin
pi@raspberrypi $ ./julia # tada!!!
```

#### Remark

上記の方法は ラズパイ3,4 など `armv7l` の物です. ラズパイゼロで動かしたい人は

上の `IMAGE_NAME` を 

```console
IMAGE_NAME=terasakisatoshi/jlcross:rpizero-${JL_VERSION}
```
 
のように変更します．さらに

```console
pi@raspberrypi $ sudo apt-get update && \
    sudo apt-get install -y build-essential libatomic1 python gfortran perl wget m4 cmake pkg-config \
    libopenblas-dev \
    liblapack-dev \
    libgmp3-dev \
    libmpfr-dev
```

のようにします. これは(ビルドを頑張って通すために)依存関係としてシステムのものを使うようにしているためです.

```
# Make.user のなかみ
override USE_SYSTEM_BLAS=1
override USE_SYSTEM_LAPACK=1
override USE_SYSTEM_LIBM=1
override USE_SYSTEM_GMP=1
override USE_SYSTEM_MPFR=1
```

さて，ラズパイ４の上で動かしたスクリーンショットがこちらです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135978/0610f27f-c19c-a19c-fb7f-b090f9eb1d11.png)

やったね，たえちゃん動いたよ．

# 動くアプリあるの？

Tier3 なのにまともに動くパッケージあるの？あるよ(ラズパイ３，４であれば)！！！

Plots.jl 動くよ！ 最近は SpecialFunctions_jll も整備されて SymPy.jl もうごくよ．つまり PyCall.jl もうごくよ！ PackageCompiler.jl もうごくから　JITコンパイルコストを減らすためにあらかじめ Julia のコードをビルドさせられるよ！ IJulia もうごくし，なんだったら Pluto.jl も動かすことができるよ！Dash.jlもうごくよ！


## Have a try!


- https://github.com/terasakisatoshi/HelloX.jl
- https://github.com/terasakisatoshi/CameraApp.jl
- https://github.com/terasakisatoshi/VideoCaptureWrap.jl

よかったら試してみてね．

#### Appendix 

実は https://interface.cqpub.co.jp/magazine/202006/ で昔書いたんだ(´・ω・｀).

いいJuliaの良い入門書だと思うからよかったらぜひ・・・