ElixirでIoT#4.1：Nerves開発環境の準備（2020年11月版）

この記事は[#NervesJP Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nervesjp)の1日目です．れっつじょいなす！

# はじめに

どうもこんにちわ
[Nerves](https://nerves-project.org/)とは，関数型言語ElixirにてIoTシステム開発を実現するフレームワークです．
『ElixirでIoT』の世界に革新をもたらします！

詳細な解説は[IoT ALGYANで実施したWebinar](https://algyan.connpass.com/event/180192/)のこちらの資料もご笑覧ください．

- [ElixirでIoT！？ ナウでヤングでcoolなNervesフレームワーク](https://www.slideshare.net/takasehideki/elixiriotcoolnerves-236780506)

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240349/57a28065-32cf-9219-c9e4-a5b614f033d2.png)](https://www.slideshare.net/takasehideki/elixiriotcoolnerves-236780506)



**さぁ皆さん！今すぐにでもNervesやりたくなってきたでしょ！？？**


Nervesを使うには，まずは環境構築だっ！となるわけですが，幾つか注意点（a.k.a ハマりどころ）があったりします．[2019年には全国各地でNerves Trainingを開催しました](https://qiita.com/takasehideki/items/8f43f1853ce88cbbe82e#%E8%A3%9C%E8%B6%B3)が，その折に皆さんにも準備いただいた際に多くのTIPSが溜まってきました．

ということで本記事は，これらのTIPSの集約も兼ねて，Nervesの開発環境の準備方法を紹介します．
なお本記事は，[#NervesJP Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nervesjp)の記念すべき1日目！の記事でもあります．

Nervesの開発は日進月歩でアップデートが続いています．なるべく最新版に合うように本記事を随時更新していますが，[公式のInstallation Docs](https://hexdocs.pm/nerves/installation.html)ページも参照してください．



# OS環境ごとの準備

まずは開発母艦となるPCを用意します．
要件としてはroot権限，ssh接続機能，USBポート１口，microSD/SDポート（別付でもOK）が必要です．

使用されるOS環境ごとに異なる準備内容を示します．
なおNervesの開発チーム的にはmacOSを基本としているようです．Linuxの場合はどのDistributionでもいけるそうですが，Ubuntuが推奨らしいです．
~~なおWindowsは(ry~~
→ この状況，なんとかしたいですねぇ,,, WSL2でどうにかなるでしょうか？
→ [どうにかなりました！コチラどうぞ！！](https://qiita.com/takasehideki/items/b8ea8b3455c70398178a)

また，クロスコンパイラを使う兼ね合いから，ホストPCはx64のものを用意してください．arm64は対応していません．
~~つまりラズパイでラズパイ開発しようぜっ！ってのは（ry~~
→ Nerves co-authorのJustin曰く，できるよっ！と言っていました．Raspberry Pi 3でexperimentalに整えているようです．機会を伺って詳細を調べてみます．

## macOSの場合

筆者はmacOS Catalina (10.14.6)で試行しています．

まずはXcode command-line toolsをインストールします．
~~Catalinaの場合，Erlang 22.2系との兼ね合いで注意が必要なことがあります．[こちらの記事](https://qiita.com/takasehideki/items/2edacb7811521f71a9e7)にまとめてありますので，合わせてご一読ください．~~ → 22.3系がサポートされるようになったので大丈夫です！

```bash
$ xcode-select --install
```

パッケージやライブラリのインストールには[HomeBrew](https://brew.sh/index_ja)を使います．下記で導入してください．

```bash
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

Nervesのためのパッケージを入れていきます．

```bash
$ brew install squashfs coreutils xz pkg-config
```

Nervesファームウェア書き込みのツールである[fwup](https://github.com/fhunleth/fwup)をインストールします．

```bash
$ brew install fwup
```

**[NT]** 後述しますが，Erlangビルドに`asdf`を使うことを推奨しています．
Erlangのソースビルド中でOpenJDK等のJava Compilerを使用します（これが無くても`jinterface : No Java compiler found`の警告が表示されるだけでビルドは可能です）
これを導入されていない方は，手っ取り早くbrewで下記にてインストールします．

```bash
$ brew cask install adoptopenjdk
```

さらにErlangビルドのための様々なパッケージを入れていきます．各種オプションや追加モジュールのためなので，Erlangの標準機能のインストールだけであれば無くても構いません．

```bash
$ brew install automake autoconf openssl \
libyaml readline libtool wxmac glfw3 glew unixodbc fop
```

## Linuxの場合

Ubuntuの例となります．他Distributionは適宜で読み替えてください．

Nervesのためのパッケージを入れていきます．

```bash
$ sudo apt install build-essential automake autoconf \
git squashfs-tools ssh-askpass pkg-config curl
```

**[NT]** Erlangビルドのための`asdf`やScenicのために，様々なパッケージを入れていきます．
（Ubuntu18環境では`curl`がデフォルトで入っていないそうです． @piacerex さんに多謝！
（Ubuntu16環境では，libglew2.0がないので`libglew1.13`で代用して問題ありません．@bleach31さんに多謝！）


```bash
$ sudo apt install git libssl-dev libncurses5-dev \
bc m4 make unzip cmake python autoconf \
libwxgtk3.0-dev libgl1-mesa-dev libglu1-mesa-dev \
libglfw3 libglfw3-dev libglew2.0 libglew-dev
```

Ubuntu18環境でのErlang on asdfビルド時に出力される ` * jinterface     : No Java compiler found` および ` * odbc : ODBC library - link check failed` のそれぞれの警告メッセージを回避するには， `default-jdk` および `unixodbc-dev` もインストールする必要があります（警告なので無くてもErlangビルドは完了できます）


```bash
$ sudo apt install default-jdk unixodbc-dev
```


Ubuntu18環境では下記もインストールしておくと，asdfを用いたErlang導入時に，javaのインタフェース部分の作成とドキュメント生成に失敗しないようになるようです（[@ykominami](https://twitter.com/ykominami)さんに多謝！

```bash
$ sudo apt install fop xsltproc libxml2-utils
```


Nervesファームウェア書き込みのツールである[fwup](https://github.com/fhunleth/fwup)をインストールします．
apt pkgとしては登録されていませんが，GitHubにて各distribution用のパッケージが配布されていますので，それを使ってインストールします．

- [fwup Installing](https://github.com/fhunleth/fwup#installing)

### ArchベースのLinuxの場合

ArchLinuxなどの場合は，下記のコマンドでビルド環境を用意できるそうです．
筆者は手持ちの環境が無いので，お試しされた方がいましたらお知らせください！！

```bash
$ yay -S base-devel ncurses5-compat-libs openssh-askpass git squashfs-tools curl
$ yay -S wxgtk2 fop jdk-openjdk unzip
```


## Windowsの場合

~~ゴメンナサイWindowsはWSL込みで非推奨なのです，，，~~
~~SDカード書込みやデバイス接続など，いろいろ乗り越えるべき問題があります．
国内では[@nabinnoさん](https://twitter.com/nabinno)がWSL対応にトライされていますので，成果を待ちたいところです^^;~~

~~ということでここはおとなしく，[VirtualBoxでUbuntu 18.04をインストール](https://unofficialtokyo.com/2018/12/virtualbox-ubuntu1804-on-windows/)してくださいm(_ _)m~~

[WindowsユーザでもWSL 2でNerves開発](https://qiita.com/takasehideki/items/b8ea8b3455c70398178a)ができるようになりました！！（2020年5月時点）
WSL 2でUbuntu 18.04を用意いただき，Windowsネイティブと両方で`fwup`をインストールしてやります．

あるいは，Docker&VSCode連携でモダンに開発環境を整えることもできます！
@matsujirushi さんの素敵な記事を参照！

- [WindowsでNervesやるならWSL2+Docker+VSCode](https://qiita.com/matsujirushi/items/f0bde41400e45e309df2)

# Erlang & Elixirのインストール

いよいよErlangとElixirをインストールします．
Nerves公式には`asdf`でのツールバージョン管理を推奨しています．
asdfでの管理方法についてはKochi.exな@nishiuchikazumaの[こちらの記事](https://qiita.com/nishiuchikazuma/items/b9d319732ddb540fd990)も参考になります．

## TIPS


[ShozFさん](https://twitter.com/ShozF/status/1151996770685050880)のご指摘を反映して，`.asdf`の設定先を`.bashrc`に変更しました！Ubuntuでは.bash_profileが無視されます．

Anaconda3がインストールされているとerlangビルドがうまくいかないそうです．# clangのパスは`/usr/bin/clang`であること必要がありますが，Anacond3のclangが呼び出されてしまうためです．
Anaconda3をパスから外してからビルドを実行してください（[@ykominami](https://twitter.com/ykominami)さんに多謝！


```bash
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.0

# The following steps are for bash. If you’re using something else, do the
# equivalent for your shell.
$ echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
$ echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc # optional
$ source ~/.bashrc

$ asdf plugin-add erlang
$ asdf plugin-add elixir

# Note #1:
# If on Debian or Ubuntu, you'll want to install wx before running the next
# line: sudo apt install libwxgtk3.0-dev
# for arch based systems run the next line:
# yay -S wxgtk2 fop jdk-openjdk unzip

# Note #2:
# It's possible to use different Erlang and Elixir versions with Nerves. The
# latest official Nerves systems are compatible with the versions below. In
# general, differences in patch releases are harmless. Nerves detects
# configurations that might not work at compile time.
$ asdf install erlang 23.1.4
$ asdf install elixir 1.11.2-otp-23
$ asdf global erlang 23.1.4
$ asdf global elixir 1.12.2-otp-23
```

きちんとインストールされているかは，下記で確認できます．

```bash
$ iex 
Erlang/OTP 23 [erts-11.0.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :observer.start 
:ok
```

## うまくいかないときは？

arm64環境だと`asdf`がうまく動かないことがあるようです（詳細未調査）
その場合はソースビルドになります．@u3pakaさんの[こちらの記事](https://qiita.com/u3paka/items/1c1dc574fc8510c186e9)が参考になります！（ただしこのままやるとOTP 22になってしまうので注意してください）
→ただしarm64だとそもそもNervesのホスト環境として対応していないのでご注意を！

**07/10追記：**
`asdf`ではソースビルドをすることになりますが，特にWindowsのVirtualBox環境ではメモリ不足でコケることがあるそうです．そうなるとパッケージビルドの方法が良いのですが，普通にやるとOTP 22系がインストールされています．
パッケージからElixir 1.8.1 / OTP 21をインストールする方法については[myasuさん](twitter.com/etcinitd)がまとめてくださった下記の記事（Nerves Training in fukuoka.exの参加談）をご参照ください．多謝！！


<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">先日の「Nervesトレーニング in福岡」<br><br>Erlangのコンパイルが出来ず、やむを得ずパッケージで入れ直したり、VirtualBoxからNervesデバイスが見え無かったり・・・等、当日ハマったところの処置についてまとめてみました。<a href="https://t.co/4yAmS7xMqB">https://t.co/4yAmS7xMqB</a></p>&mdash; myasu🍊8/12 C96[月-南リ08b] (@etcinitd) <a href="https://twitter.com/etcinitd/status/1148587762435575808?ref_src=twsrc%5Etfw">2019年7月9日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# Hexライブラリ・アーカイブのインストール

Elixirのライブラリやアーカイブをインストールしていきます．
すでにAlchemistな方も，最新版にアップデートするために下記コマンドを実行しておいてください．

## hex, rebar

HexはElixir/Erlangのパッケージ管理ツール，rebarはErlangのビルドツールです．

```bash
$ mix local.hex
$ mix local.rebar
```

とうとうNerves開発環境をインストールします！！


## Nerves archive

```bash
$ mix archive.install hex nerves_bootstrap
```


# SSH公開鍵の作成

```bash
$ ls ~/.ssh
$ ls ~/.ssh/id_rsa
```
として`No such file or directory`と言われる場合は，下記を実行しておきましょう．

```bash
$ mkdir ~/.ssh
$ ssh-keygen -t rsa -f ~/.ssh/id_rsa 
```

# 構築完了！

正しく環境構築できていれば，下記のようになっているはずです．
（それぞれのアップデートに応じてバージョン番号は異なるかもしれません）

```bash
$ ls ~/.asdf/installs/elixir/1.10.4-otp-23/.mix/*
/Users/takase/.asdf/installs/elixir/1.10.4-otp-23/.mix/rebar*
/Users/takase/.asdf/installs/elixir/1.10.4-otp-23/.mix/rebar3*

/Users/takase/.asdf/installs/elixir/1.10.4-otp-23/.mix/archives:
hex-0.20.5/		nerves_bootstrap-1.9.0/

```

# おわりに

本記事ではNervesの開発環境の準備方法を解説しました．
はてさてじゃあ使ってみよう！！は，また後日に執筆したいと思います^^;


## 主な編集履歴

- 2020/11/30:
    - Elixir 1.11.2-otp-23に対応！
- 2020/10/13:
    - Nerves 1.7.0 Released! に対応．
    - この欄が長くなってきたので，末尾に移動^^;
- 2020/09/25:
    - Nerves 1.6.5 Released! に対応．特にLinuxのArch based systemについて追記しました．
- 2020/07/10:
    - [本家のInstallation.mdの更新](https://github.com/nerves-project/nerves/commit/50ef2a6933eeae4ca05254f88677badc70cc5c28#diff-045d5d7186acf52b74848a7dfbdde200)に合わせてErlang/OTP 23にアップデート
    - @matsujirushi さんのWSL2+Docker+VSCodeな記事をリンク！
    - `picocom`等のシリアル通信を使うシチュエーションが無くなってきた（ssh通信が安定してきた！）ので，インストール手順から削除．
- 2020/05/06:
    - 朗報！[WindowsユーザでもWSL 2でNerves開発](https://qiita.com/takasehideki/items/b8ea8b3455c70398178a)がネイティブにできるようになりました！！
- 2020/05/05:
    - Linux向けのErlangインストール時の警告表示 ` * odbc : ODBC library - link check failed` の抑止のために `sudo apt install unixodbc-dev` を追加
- 2020/04/28: 
    - 公式の[Nerves Installation](https://hexdocs.pm/nerves/installation.html)にに合わせてErlang/ OTP 22.3.2にアップデート
- 2020/04/20: 
    - [Nerves 1.6 Released!](https://elixirforum.com/t/nerves-1-6-released/29982)に対応
    - Nerves 1.6.1に合わせてElixir 1.10.2 / Erlang/OTP 22.2.8にアップデート
- 2020/02/23:
    - Ubuntu18の環境準備に `default-jdk` を追加
- 2020/02/04:
    - macOSの試行バージョン（Mojave）を明記
    - macOS向けのErlangインストール時の警告表示をなるべく除去できるようにした
        - `jinterface : No Java compiler found`のために`brew cask install adoptopenjdk` を追加
        - `* odbc : ODBC library - header check failed` のために `brew install odbc` を追加
        - `fop is missing`のために`brew install fop`を追加
    - Catalinaでの注意点と @torifukukaiou さんへの記事リンクを追加
- 2019/12/01:
    - [#NervesJP Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nervesjp)向けに編集
- 2019/09/03: 
    - Anaconda3導入時のTIPS追加（[@ykominami](https://twitter.com/ykominami)さんに多謝！）
    - Ubuntu16でのTIPS追加（[@ykominami](https://twitter.com/ykominami)さんと@bleach31さんに多謝！）
- 2019/08/27: Nerves 1.5.1のリリースに合わせてElixir 1.9.1 / OTP 22にアップデート
- 2019/07/19: `asdf`の設定先を.bashrcに変更（[ShozFさん](https://twitter.com/ShozF)に多謝！
- 2019/07/18: [Nerves 1.5.0 Released!](https://elixirforum.com/t/nerves-1-5-0-released/23909)に対応
    - Elixir 1.9.0 / OTP 22にサポートしています！
- 2019/07/10: [fukuoka.ex](https://fukuokaex.connpass.com/event/133408/)に[myasuさん](twitter.com/etcinitd)のTIPS共有なブログ記事を掲載（深々と多謝！
- 2019/06/16: `asdf`がうまく動かずソースビルドな時の方法を紹介（@u3pakaさんに多謝！