1.はじめに
プログラム言語 Elixir を普段使いする機会が増えてきたので、頻繁に行う内容を覚え書きしてます。(随時追記)
- 1.はじめに
- 2.インストール・アップデート
- 2.プロジェクト
- 3.Livebook
- 4.Nerves
- 11.記述
- 12.こんなときは
(実行環境)
$ uname -a
2.インストール・アップデート
(1)ビルドに必要なパッケージをインストール
Ubuntu Linux
ビルドに必要なツール、ライブラリをaptでインストールしておきます。
asdfに必要なもの
$ sudo apt install git curl make automake autoconf gcc g++ automake autoconf -y
asdfでElixirをビルドするのに必要なもの
$ sudo apt install libssl-dev libncurses5-dev libwxgtk3.2-dev libwxgtk-webview3.2-dev libxml2-utils unixodbc-dev xsltproc -y
java関連ライブラリのインストールが伴うもの
aptパッケージ | 入れてないときのerlangビルドの際のメッセージ |
---|---|
$ sudo apt install fop |
DOCUMENTATION INFORMATION fop is missing.Using fakefop to generate placeholder PDF files. |
$ sudo apt install erlang-jinterface |
APPLICATIONS DISABLED No Java compiler found |
crypto |
APPLICATIONS INFORMATION Using OpenSSL 3.0 is not yet recommended for production code. |
nervesに必要なもの
$ sudo apt install pkg-config -y # fwup $ wget https://github.com/fwup-home/fwup/releases/download/v1.9.1/fwup_1.9.1_amd64.deb $ sudo dpkg -i fwup_1.9.1_amd64.deb
scenicに必要なもの
$ sudo apt install libglfw3 libglfw3-dev libglew-dev -y
macOS
# 最低限必要 % brew update % brew install fwup squashfs coreutils xz pkg-config # GUI用・observerなど % brew install wxWidgets
(2.0)asdf
開発ツールのインストールと、動的なバージョン管理支援
Ubuntu Linux
# クローンしてくる。ブランチは、その時点の新しいバージョンを選ぶこと $ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0 # asdfのバージョン確認 $ ~/.asdf/bin/asdf --version v0.10.2-7e7a1fa # パスを通す $ echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc $ echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
macOS
# インストール % brew install asdf # パスを通す % echo -e "\n. $(brew --prefix asdf)/asdf.sh" >> ~/.zshrc
Elixir関連プラグインの追加
$ asdf plugin-add erlang $ asdf plugin-add elixir
ターゲットのバージョン一覧を確認
$ asdf list-all erlang | tail … 25.3.2.6 26.0-rc1 26.0-rc2 26.0-rc3 26.0 26.0.1 26.0.2 $ asdf list-all elixir | grep -v ma | tail … 1.15.3-otp-25 1.15.3-otp-26 1.15.4 1.15.4-otp-24 1.15.4-otp-25 1.15.4-otp-26 1.15.5 1.15.5-otp-24 1.15.5-otp-25 1.15.5-otp-26
Nerves Systemとの連携をする場合
ErlangとElixirのバージョンが指定されているので、下記を確認して、あまり最新のバージョンをインストールしないこと。
ビルド・インストール
まずは、erlangをインストール
$ asdf install erlang 25.3.2.7 Extracting source code Building Erlang/OTP 25.3.2.6 (asdf_25.3.2.6), please wait... APPLICATIONS DISABLED (See: /home/user/.asdf/plugins/erlang/kerl-home/builds/asdf_25.3.2.6/otp_build_25.3.2.6.log) * jinterface : No Java compiler found DOCUMENTATION INFORMATION (See: /home/user/.asdf/plugins/erlang/kerl-home/builds/asdf_25.3.2.6/otp_build_25.3.2.6.log) * documentation : * fop is missing. * Using fakefop to generate placeholder PDF files. Erlang/OTP 25.3.2.6 (asdf_25.3.2.6) has been successfully built Cleaning up compilation products for Cleaned up compilation products for under /home/user/.asdf/plugins/erlang/kerl-home/builds
erlangを有効化
$ asdf local erlang 25.3.2.7
次に、Elixirをインストール
$ asdf install elixir 1.15.5-otp-25 ==> Checking whether specified Elixir release exists... ==> Downloading 1.15.5-otp-25 to /home/user/.asdf/downloads/elixir/1.15.5-otp-25/elixir-precompiled-1.15.5-otp-25.zip % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 6715k 100 6715k 0 0 2159k 0 0:00:03 0:00:03 --:--:-- 2160k ==> Copying release into place
Elixirを有効化
$ asdf local elixir 1.15.5-otp-25
現在有効なバージョンの確認
$ asdf current erlang erlang 25.3.2.6 /home/user/.tool-versions $ asdf current elixir elixir 1.15.5-otp-25 /home/user/.tool-versions $ elixir -v Erlang/OTP 25 [erts-13.2.2.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns] Elixir 1.15.5 (compiled with Erlang/OTP 25)
一気にインストールしたい場合は、下記のようにコマンドを組み立てる。 (timeコマンドは、ビルドに要した時間を計るために使用)
$ time asdf install erlang 25.0.4 && asdf local erlang 25.0.4 && time asdf install elixir 1.14.0 && asdf local elixir 1.14.0 $ export KERL_BUILD_DOCS=yes && export ERL=25.0.4 && export EXR=1.13.4-otp-25 && time asdf install erlang ${ERL} && asdf local erlang ${ERL} && time asdf install elixir ${EXR} && asdf local elixir ${EXR}
(2.1)mise
Rustベースのバージョン管理ツール。高速。
(3)パッケージマネージャhexのインストール
$ mix local.hex
~/.asdf/installs/elixir/<version>/.mix/archives/
に展開されます。
(4)アップデート
現在インストール済みのバージョンを確認
$ asdf list elixir 1.14.2 erlang 24.3.3
現在有効なバージョンの確認
$ asdf current elixir elixir 1.14.2 /home/user/.tool-versions $ asdf current erlang erlang 24.3.3 /home/user/.tool-versions
新たなバージョンをインストール、有効化
$ asdf install erlang 25.3.2.6 $ asdf local erlang 25.3.2.6 $ asdf install elixir 1.15.5-otp-25 $ asdf local elixir 1.15.5-otp-25
不要になったバージョンをアンインストール
$ asdf uninstall elixir 1.14.2 $ asdf uninstall erlang 24.3.3 asdf_24.3.3 /home/user/.asdf/installs/erlang/24.3.3 The asdf_24.3.3 build has been deleted The installation "/home/user/.asdf/installs/erlang/24.3.3" has been deleted
現在有効なバージョンの確認
$ elixir -v Erlang/OTP 25 [erts-13.2.2.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns] Elixir 1.15.5 (compiled with Erlang/OTP 25)
(5)VSCode OTP compiled without EEP48 documentation chunks
対策
参考資料
2.プロジェクト
(0)コマンド履歴の有効化
iex
シェルのコマンド履歴を使えるようにします。
# https://stackoverflow.com/questions/45405070/how-do-i-save-iex-history $ export ERL_AFLAGS="-kernel shell_history enabled"
(1)プロジェクトの作成
作成コマンド | ディレクトリ構成 |
---|---|
$ mix new newapp | |
$ mix new newmod --module MyModule | |
$ mix new newsup --sup | |
$ mix new newumb --umbrella |
(2)依存関係の処理
$ mix deps.get
(3)ビルドと実行
#対話シェルで実行 $ iex -S mix #そのまま実行 #https://qiita.com/pojiro/items/8955f78cfeb2e959c983 $ mix release $ mix run --no-halt #escriptで単体実行化 #https://asquera.de/blog/2015-04-10/writing-a-commandline-app-in-elixir/ $ mix escript.build
※スクリプトexsの場合
https://blog1.mammb.com/entry/2015/08/04/004748
#ビルド $ elixirc hello_world.exs $ ls Elixir.Hello.beam hello.exs #実行 $ elixir -e Hello.hello
(4)デバッグ用
mix.iex
にモジュールを追加
def application do [ # 修正前 # extra_applications: [:logger] # 修正後 extra_applications: [:logger, :observer, :wx, :runtime_tools] ] end
起動
iex()> :observer.start()
(9)iex その他
3.Livebook
(1)インストール
$ git clone https://github.com/livebook-dev/livebook.git $ cd livebook $ mix deps.get #設定変更 $ nano config/prod.exs
必要に応じて、待機ポート、受信IPを変えておく
import Config # Default bind and port for production config :livebook, LivebookWeb.Endpoint, http: [ip: {0, 0, 0, 0}, port: 8079], server: true config :livebook, :iframe_port, 8078 # Set log level to warning by default to reduce output config :logger, level: :warning
とりあえず起動する
$ MIX_ENV=prod mix phx.server Compiling 151 files (.ex) Generated livebook app [Livebook] Application running at http://localhost:8079/?token=4jtc34krphaxbgnyiazoly5q3ykahgk2
起動時に表示されたURL http://localhost:8079/?token=4jtc34krphaxbgnyiazoly5q3ykahgk2
で、ブラウザでアクセス
ひとしきり楽しんだら、[Ctrl-C]
で止める。
アドバンスド
#escriptでビルドして起動 $ mix escript.install hex livebook $ livebook server --help #localhost以外からも接続OKにする起動コマンド $ livebook server --port 8082 --ip 0.0.0.0
起動スクリプトサンプル
ディレクトリ構成
~/gitwork/elixir ~/gitwork/elixir/livebook ~/gitwork/elixir/var
#!/bin/bash #-------------------------------------- SCRIPTDIR="${HOME}/gitwork/elixir" LOGDIR="${SCRIPTDIR}/var" cd `dirname $0` CMDNAME=`basename $0` #ビルド済みのlivebookをフルパス指定 /home/tailway/.asdf/installs/elixir/1.13.1-otp-24/.mix/escripts/livebook server \ --port 8082 \ --ip 0.0.0.0 \ --home ${SCRIPTDIR} \ --no-token \ >> ${LOGDIR}/${CMDNAME}.log 2>&1 & PIDLB=$! echo "livebook PID: ${PIDLB}" echo "livebook PID: ${PIDLB}" >> ${LOGDIR}/${CMDNAME}.log 2>&1 exit 0
(2)nxと画像でひとしきり楽しむ
Mix.install([ {:nx, "~> 0.1.0-dev", github: "elixir-nx/nx", branch: "main", sparse: "nx"}, {:kino, "~> 0.3.1"}, {:download, "~> 0.0.4"}, {:pixels, "~> 0.2.1"}, {:pngex, "~> 0.1.1"} ])
4.Nerves
(1)mix deps.getのエラー
$ mix deps.get ** (Mix) Archive "nerves_bootstrap" could not be found. Please make sure the archive is installed locally.
nerves_bootstrapがインストールできていません。
$ mix archive.install hex nerves_bootstrap Resolving Hex dependencies... Resolution completed in 0.026s New: nerves_bootstrap 1.13.1 * Getting nerves_bootstrap (Hex package) ・・・
(2)mix firmwareのエラー
$ export MIX_TARGET=rpi0 && mix firmware ==> nerves ==> hellonerves ** (Mix) The following Nerves packages need to be built: nerves_system_rpi0 The build process for each of these can take a significant amount of time so the maintainers have listed URLs for downloading pre-built packages. If you have not modified these packages, please try running `mix deps.get` or `mix deps.update` to download the precompiled versions. If you have limited network access and are able to obtain the files via other means, copy them to `~/.nerves/dl` or the location specified by `$NERVES_DL_DIR`. If you are making modifications to one of the packages or want to force local compilation, add `nerves: [compile: true]` to the dependency. For example: {:nerves_system_rpi0, "~> 1.26.0", nerves: [compile: true]} If the package is a dependency of a dependency, you will need to override it on the parent project with `override: true`.
上記の例は、Raspberry Pi Zero 用のビルドツールのインストール忘れです。
mix deps.get
して、ビルドツールをインストールしておきます。
$ export MIX_TARGET=rpi0 && mix deps.get && mix firmware
(3)mix burnのエラー
ターミナルから下記実行する際に、SDカードへの書き込みにroot権限を要求されます。
$ MIX_TARGET=bbb mix burn ==> nerves ==> hellonerves Nerves environment MIX_TARGET: bbb MIX_ENV: dev Use 7.29 GiB memory card found at /dev/sdb? [Yn] y sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
ところが、このエラーを受けてsudo
しても、下記エラーで進みません。
$ sudo -S mix firmware.burn
sudo: mix: コマンドが見つかりません
この場合は、以下二つの方法があります。
# ↓TARGET ↓プロジェクト名.fw $ sudo fwup ./_build/bbb_dev/nerves/images/hellonerves.fw Use 7.82 GB memory card found at /dev/sdb? [y/N] y 100% [====================================] 20.90 MB in / 24.31 MB out Success! Elapsed time: 11.178 s
(4)Nerves専用のキーを作るとき
キーの作成(パスワード””の場合)
$ ssh-keygen -t ed25519 -f ~/.ssh/id_nerves_key_m -N ""
config/host.exs
ファームウェアをビルド、転送
書き込み後、ログインするとき
$ ssh <hostname or ip> -I ./.ssh/id_nerves_key_m
11.記述
Introduction
- Pre-Bootcamp introduction to Elixir | PPT | Free Download
- Search Results for gumi TECH Blog elixir - DEV Community
- Elixir - 日本語
- エリクサーチ |> Elixir始め方ガイド
- Learn Elixir and Phoenix | Alchemist Camp
Tips
Cheat Sheet
Supervisor
No | Title | URL |
---|---|---|
0 | GenServer | https://hexdocs.pm/elixir/GenServer.html |
1 | 並行性 | https://elixirschool.com/ja/lessons/intermediate/concurrency |
2 | OTPの並行性 | https://elixirschool.com/ja/lessons/advanced/otp_concurrency |
3 | OTPスーパバイザ | https://elixirschool.com/ja/lessons/advanced/otp_supervisors |
4 | OTPディストリビューション | https://elixirschool.com/ja/lessons/advanced/otp_distribution |
9 | GenServer - a cheat sheet | https://elixir-lang.org/downloads/cheatsheets/gen-server.pdf |
Nerves
- Elixir/Nerves/rpi0でLチカする +α #Elixir - Qiita
- Elixir/Nerves: GenServerでブレットボード上のLEDを点滅させる #RaspberryPi - Qiita
デバッグ
12.こんなときは
asdfのエラー
$ asdf install erlang 25.3.2.7 asdf_25.3.2.7 is not a kerl-managed Erlang/OTP installation No build named asdf_25.3.2.7 ・・・
Erlangのversion管理ツールkerl
に依存していないバージョンであることを警告していますが、実際のインストールには影響はありません。
Scienicのエラー
$ mix do deps.get, scenic.run ・・・ No package 'glew' found c_src/device/glfw.c:17:10: fatal error: GL/glew.h: No such file or directory 17 | #include <GL/glew.h> | ^~~~~~~~~~~ compilation terminated. ・・・ ** (Mix) Could not compile with "make" (exit status: 2). You need to have gcc and make installed. If you are using Ubuntu or any other Debian-based system, install the packages "build-essential". Also install "erlang-dev" package if not included in your Erlang/OTP version. If you're on Fedora, run "dnf group install 'Development Tools'".
openGL関連のライブラリが不足しています。 前述に戻って、必要なaptをインストールしてください。
$ mix do deps.get, scenic.run ・・・ 09:52:27.830 [info] Scenic.Driver.Local: start: [name: :local, key_map: Scenic.KeyMap.USEnglish, cursor: false, position: [orientation: :normal, centered: false, scaled: false], calibration: [], antialias: true, debug: false, opacity: 255, layer: 0, limit_ms: 29, window: [resizeable: false, title: "my_app"], on_close: :stop_system], pid: #PID<0.401.0> scenic_driver_local error: "Unable to initialize GLFW" scenic_driver_local puts: "Failed to initilize the device" 09:52:27.841 [error] scenic_driver_local: "Unable to initialize GLFW" 09:52:27.841 [info] scenic_driver_local: "Failed to initilize the device" 09:52:27.841 [error] Scenic.Driver.Local dirty close 09:52:27.862 [error] GenServer :local terminating ** (ArgumentError) argument error ・・・
リモートのターミナルから起動したときにXの画面の出力先が決まっていないエラーです。
ビルド前に、下記を実行しておくと、本体側のディスプレイにウィンドウが表示されます。
export DISPLAY=:0