ElixirでIoT#1.1：IoTボードへのElixir環境の構築とEEloTツールキットの紹介

この記事は「[Elixir or Phoenix Advent Calendar 2017](https://qiita.com/advent-calendar/2017/elixir-or-phoenix)」の7日目です．
昨日は@zacky1972さんの「[ZEAM開発ログv0.1.0 Flow / GenStage による並列プログラミング入門](https://qiita.com/zacky1972/items/e843607881bbeca34b70)」でした．

# はじめに

Elixir歴2週間程度のまだまだ初心者です．
ハンドルネーム無いの？とよく聞かれますが，氏名の組合せが珍しいらしくどんなサービスでもフルネームでIDを取得できるのが気に入っています．

Elixirに出会ったのはZACKY先生からのご紹介です．[fukuoka.ex](https://fukuokaex.connpass.com/)というElixir/Phoenixでわいわいやっている福岡のコミュニティがあるよ？ということで先日の勉強会「[fukuoka.ex#8(福岡Elixir会)：2018年 春のElixir入学式](https://fukuokaex.connpass.com/event/85038/)」にお誘いいただき，気がついたら登壇することになっていました．

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">前々から <a href="https://twitter.com/zacky1972?ref_src=twsrc%5Etfw">@zacky1972</a> 先生にお誘いいただいていて，おーElixir面白そうぜひ参加します！どうせ遠路はるばる行くのならばLTネタも仕込んで臨まないと損ですね！みたいな雑談をしていたところ，すでに発表者で名前が入っていたでござる． <a href="https://t.co/6hMC7eD4v3">https://t.co/6hMC7eD4v3</a></p>&mdash; TAKASE hideki (@TAKASEhideki) <a href="https://twitter.com/TAKASEhideki/status/983912533999271936?ref_src=twsrc%5Etfw">2018年4月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



ということで，fukuoka.exにて発表した内容を加筆編集しながら，季節外れのAdvent Calendarにも参加することになりました．
巷を賑わせている新しめの関数型言語である**ElixirをIoTボードで動かしたらどうなんの？**という異色ネタにて，全４回の連載でお届けする予定です．

今回は，IoTボードへのElixir環境の構築方法と，お手軽に環境構築するためのツールキットを紹介します．

## IoTとは？

「Elixir」で引っ掛かってきた方向けへの説明です．

IoTとは，Internet of Thingsの略です．ネットワークインフラが爆発的に整備されてきた昨今，あらゆるモノやコトさらにはヒトまでインターネットに接続して情報処理したら素敵じゃない？という技術体系のことを指します．

IoTシステム系を構築する技術要素は，`デバイス`：外界環境の直近に位置して，センシング／アクチュエーションを行う，`エッジサーバ`：デバイスの近傍に位置して，収集したデータをクラウドサーバに中継する，`クラウド`：各デバイス／エッジサーバから収集されたビッグデータを捌いて解析する，の３つがあります．
つまり，様々なplayerが集結して大きなサービスシステムを構築していく必要があります．組込み屋さんからすると，サーバ屋さんやWeb屋さんとの“文化の壁”を乗り越えて協力していく時代になってきているわけです．

~~まぁ要するにバズワード~~，，，いやっなんでもないです^^;

## Elixirとは？

「IoT」で引っ掛かってきた方向けへの説明です．

Elixirは2012年に登場した新しい関数型言語です．ErlangのVM上で走ります．[次に来る大物Web言語](https://qiita.com/HirofumiTamori/items/0dfdbada30c7d8f183fd)と言われています．

Elixirには以下の特徴があります．

- 読み書きしやすく，生産性が高い．
- 並行処理（並列処理）のプログラミングが簡単に実現できる．
- 分散システム対応／スケールしやすい．
- 軽量で耐障害性が高い．

**あれっ？これってIoTでも使えるんじゃね！？？**

# Elixir環境の構築

ということで，今回の記事では，まず各種IoTボードにElixir/Phoenixが動く環境を整えていきたいと思います．なお，本連載におけるIoTボードの定義は
**「きびきびとLinuxが動いてさくっとネットに繋がるモノ」**
としています．異論は認めます．

## IoTボードの選定とLinux環境の準備

私の手元では3種類のIoTボードを用意しました．ラズパイは2種類のOSを試してみます．

* Raspberry Pi 3 Model B / Raspbian
* Raspberry Pi 3 Model B / Ubuntu MATE
* ODROID-XU3 / Ubuntu MATE
* ZYBO / Xillinux

配線まみれで汚い，，，
![IMG_9716-min.jpg](https://qiita-image-store.s3.amazonaws.com/0/240349/159b12a8-c27f-86c0-3423-9dde1339d1f0.jpeg)

ややマニアックなボードも使っていますが，ラズパイくらいならタンスの肥やしに転がっていませんか？ぜひ試してみてください．

Linux環境の準備は長くなりますので，導入編として別記事にしました．

- [ElixirでIoT#0：IoTボードへのLinux環境の準備](https://qiita.com/takasehideki/items/9e3db412a40659233384)


## コマンドでの導入

よーやくElixirの話しに入ります^^;
とはいっても，[Installing Elixir](https://elixir-lang.org/install.html)に従えば良いだけです．

まずは`apt`や`brew`などのパッケージ管理システムのコマンドを使用して導入する方法を試しました．各OSでの導入方法と結果を示します．

### Raspbianの場合

まずはラズパイに純正OSを導入してやってみた結果です．

```shell-session
$ uname -a 
Linux raspberrypi 4.9.80-v7+ #1098 SMP Fri Mar 9 19:11:42 GMT 2018 armv7l GNU/Linux
$ cat /etc/issue
Raspbian GNU/Linux 9 \n \l

$ echo "deb https://packages.erlang-solutions.com/debian stretch contrib" | sudo tee /etc/apt/sources.list.d/erlang-solutions.list
$ wget https://packages.erlang-solutions.com/debian/erlang_solutions.asc
$ sudo apt-key add erlang_solutions.asc
$ sudo apt update
$ sudo apt install elixir

$ elixir --version 
Erlang/OTP 19 [erts-8.2.1] [source] [smp:4:4] [async-threads:10] [kernel-poll:false]

Elixir 1.3.3
```

うーん許容できなくはないけど，ちょっと古くないですか？？

### Ubuntuの場合

ラズパイ3B/Ubuntuの例です．他のIoTボードでも同じバージョンが導入されました．

```shell-session
$ uname -a 
Linux piu-desktop 4.4.38-v7+ #938 SMP Thu Dec 15 15:22:21 GMT 2016 armv7l armv7l armv7l GNU/Linux
$ cat /etc/issue
Ubuntu 16.04.2 LTS \n \l

$ wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i erlang-solutions_1.0_all.deb
$ sudo apt-get update
$ sudo apt-get install esl-erlang
$ sudo apt-get install elixir

$ elixir --version 
Elixir 1.1.0-dev
```

いやいや古すぎでしょ，，，メンテナさん頑張って，，，

### (参考)macOSの場合

筆者の母艦PCであるMacbook Pro (13-inch, 2016) にも導入してみました．

```shell-session
$ brew install elixir
$ elixir --version
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.6.4 (compiled with OTP 20)
```

macOSの`brew`では最新バージョンが難なく入りますね．

## ソースからビルド

この通り~~メンテナンスをサボられてる~~OS/Distributionによっては，古いバージョンのElixirが導入されてしまいます．バージョンが古いと使えない機能やライブラリがあったりで，具合が悪くなることが多々あります．

ということで，**男は黙ってソースからビルド**することにしましょう．
Elixir単体のビルドでも構いませんが，Erlangが古いと`make test`が通らないことがありますので，一緒に最新版を入れてしまいましょう．

`$ sudo apt install git`などでgitクライアントは入っている前提です．

```shell-session
$ sudo apt-get install m4 libncurses5-dev libssl-dev
$ wget http://erlang.org/download/otp_src_20.3.tar.gz
$ tar xzvf otp_src_20.3.tar.gz
$ cd otp_src_20.3/
$ ./configure --enable-hipe
$ make
$ sudo make install
$ cd ../
$ git clone https://github.com/elixir-lang/elixir.git
$ cd elixir/
$ git checkout v1.6
$ make clean test
$ sudo make install
```

全て成功したら`/usr/local/bin/`にElixir環境がインストールされます．

インストール結果を確認してみましょう．

```shell-session
$ which elixir
/usr/local/bin/elixir

$ elixir --version 
Erlang/OTP 20 [erts-9.3] [source] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Elixir 1.6.4 (compiled with OTP 20)
```

無事に全てのIoTボードで執筆時点の最新版を導入することができました．

ソースからインストールすることで，導入するバージョンを自由に選べたり[HiPE(High Performance Erlang)](https://qiita.com/sile/items/d750019fcab961bbb0a7)を明示的に使えたりと，とっても有用でオススメです．ただし，ボードのスペックによっては時間が掛かるのがネックですかね（今回はZYBOで1時間くらい^^;

# ツールキットの紹介

いちいちコマンドを打ち込むのもメンドくないですか？なので，ツールキットとして整備することにしました．Elixir/Erlangを自動インストールするスクリプトと，次回で紹介するベンチマークのソースおよび環境設定用のスクリプトを用意しています．


- [EEloT: **E**valuation toolkit for **El**ixir on I<b>oT</b> board](https://github.com/takasehideki/EEloT)

上記のGitHubリポジトリで公開しています．**Starください！！**
なお，3文字目はIoTの大文字`I`ではなくElixirの小文字`l`です^^;

Elixir/Erlang環境構築のための使い方はとっても簡単です．スクリプト内の一部のコマンドはsudoで動作します．

- `$ ./install.sh`
    - パッケージ管理システムからElixir/Erlangを導入します．
    - OS/Distributionは自動検知します．現状ではRaspbian,Ubuntu,macOSに対応しています（要望があれば他のDistributionにも対応します）
- `$ ./install.sh　clean`
    - パッケージ管理システムから導入したElixir/Erlangを削除します．地味に便利です．
- `$ ./install.sh　source`
    - Elixir/Erlangをソースからビルドします．
    - 現状ではErlang OTP 20.3とElixir 1.6.4が`/usr/local/bin/`にインストールされるようにしています．

## これのなにが嬉しいの？

皆さんの住んでいる世界では，Elixir/Erlangは最初に1回だけインストールするだけか，メジャーバージョンがアップデートされたら再ビルドしようかな？くらいの作業量だと思います．

しかし，IoTのツラいところPart2として，Elixir/Erlangを動かしたいボードの台数が大量になったり，今回のように複数種のボードで動かしたい案件に遭遇することは多々あります．1台ずつちまちまコマンドを打ち込んでいくなんて面倒でやってられません．
そんな時に，このEEloTツールキットは有用になるかなと思ったりしています．

# まとめ

- ElixirってIoTでも使えるんじゃね！？？
- 男は黙ってソースビルド
- [EEloT](https://github.com/takasehideki/EEloT)を使えばIoTボードへのElixir環境構築もお手のもの

# あれ？Elixirはインストールしただけ！？

おっしゃる通り，今回はElixir成分がほとんど無くて恐縮です．
次回の記事ではいよいよElixirのソースコードが登場します．IoTボードの性能評価のために整備したElixirベンチマークアプリを紹介していきます．

明日のAdvent Calendarは@piacere_exさんによる
「[Excelから関数型言語マスター2回目：列の抽出とWeb表示](https://qiita.com/piacere/items/b7787580fce5f148242f)」
です．