#1.はじめに
https://gleam.run/
https://github.com/gleam-lang/gleam
昨年、2019年9月にVer.0.1がリリースされた非常に新しい言語で、Rustで書かれていてErlang VM上で動くコンパイラです。
最近ElixirとRustを勉強していて興味があったので、GleamでHello World
を表示するまで試してみました。
##Gleamのコード例
構文はRustですが、パイプを使って順次処理を流せるところが、Elixirっぽい感じですね~
#2.インストール
実行環境
- Raspberry Pi 4
- Raspbian Buster
$ uname -a
Linux raspi4 5.4.51-v7l+ #1333 SMP Mon Aug 10 16:51:40 BST 2020 armv7l GNU/Linux
##(1)Rust
RaspbianのaptでインストールできるRustでは、gleamがコンパイルできないので、最新版(1.47.0)をソースからビルドしました。(後述にエラーの詳細あり)
こちら1を参考にインストール。
$ cd gitwork/rust
$ curl https://sh.rustup.rs -sSf | sh
info: downloading installer
Welcome to Rust!
This will download and install the official compiler for the Rust
・・・(省略)・・・
Current installation options:
default host triple: armv7-unknown-linux-gnueabihf
default toolchain: stable (default)
profile: default
modify PATH variable: yes
1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1
info: profile set to 'default'
・・・(省略)・・・
$ source $HOME/.cargo/env
$ rustc --version
rustc 1.47.0 (18bf6b4f0 2020-10-07)
$ cargo --version
cargo 1.47.0 (f3c7e066a 2020-08-28)
$
$ sudo apt install -y libssl-dev
$
$ cargo install cargo-edit
Updating crates.io index
Downloaded cargo-edit v0.7.0
Downloaded 1 crate (57.6 KB) in 0.59s
Installing cargo-edit v0.7.0
・・・(省略)・・・
Finished release [optimized] target(s) in 15m 21s
Installing /home/pi/.cargo/bin/cargo-add
Installing /home/pi/.cargo/bin/cargo-rm
Installing /home/pi/.cargo/bin/cargo-upgrade
Installed package `cargo-edit v0.7.0` (executables `cargo-add`, `cargo-rm`, `cargo-upgrade`)
$
$ git clone https://github.com/sagiegurari/cargo-make.git
Cloning into 'cargo-make'...
remote: Enumerating objects: 559, done.
remote: Counting objects: 100% (559/559), done.
remote: Compressing objects: 100% (348/348), done.
remote: Total 13676 (delta 386), reused 332 (delta 195), pack-reused 13117
Receiving objects: 100% (13676/13676), 6.72 MiB | 3.07 MiB/s, done.
Resolving deltas: 100% (10889/10889), done.
$ cd cargo-make
$ cargo install --force cargo-make
Updating crates.io index
Downloaded cargo-make v0.32.7
Downloaded 1 crate (1.2 MB) in 1.69s
・・・(省略)・・・
Compiling cargo-make v0.32.7
Finished release [optimized] target(s) in 9m 41s
Installing /home/pi/.cargo/bin/cargo-make
Installing /home/pi/.cargo/bin/makers
Installed package `cargo-make v0.32.7` (executables `cargo-make`, `makers`)
$
$ rustup update
info: syncing channel updates for 'stable-armv7-unknown-linux-gnueabihf'
info: checking for self-updates
stable-armv7-unknown-linux-gnueabihf unchanged - rustc 1.47.0 (18bf6b4f0 2020-10-07)
info: cleaning up downloads & tmp directories
$
動作確認します。
$ cd gitwork/rust
$ mkdir ./hello
$ cd hello
$ nano main.rs
$ cat main.rs
ソースの中身
fn main() {
println!("Hello, world!");
}
コンパイルと実行
$ rustc main.rs
$ ./main
Hello, world!
$
rustの動作確認ができました。
##(2)Erlang
(記述中。基本的にはElixirのインストール時の手順に倣う)
$ erl
Erlang/OTP 22 [erts-10.5.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Eshell V10.5.4 (abort with ^G)
1>
##(3)gleam
公式マニュアル2に従ってインストール。
$ cd gitwork/rust
$ git clone https://github.com/gleam-lang/gleam.git --branch v0.11.0
Cloning into 'gleam'...
remote: Enumerating objects: 5, done.
・・・(省略)・・・
$ cd gleam
$ make
build Build the compiler
install Build the Gleam compiler and place it on PATH
test-watch Run compiler tests when files change
#ビルド
$ make build
cargo build --release
Downloaded arrayvec v0.5.1
Downloaded askama_derive v0.10.3
Downloaded nix v0.17.0
・・・(省略)・・・
Compiling askama v0.10.3
Compiling hyper-tls v0.4.3
Compiling reqwest v0.10.7
Compiling gleam v0.11.0 (/home/pi/gitwork/rust/gleam)
Finished release [optimized] target(s) in 23m 08s
#ビルド
$ make install
cargo install --path . --force --locked
Installing gleam v0.11.0 (/home/pi/gitwork/rust/gleam)
Updating crates.io index
Finished release [optimized] target(s) in 4.08s
Installing /home/pi/.cargo/bin/gleam
Installed package `gleam v0.11.0 (/home/pi/gitwork/rust/gleam)` (executable `gleam`)
$
gleamコマンドを実行したところ。
$ gleam
gleam 0.11.0
USAGE:
gleam <SUBCOMMAND>
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
SUBCOMMANDS:
build Compile a project
docs Render HTML documentation for a project
format Format source code
help Prints this message or the help of the given subcommand(s)
new Create a new project
$
##(4)rebar3
rebar3は、Erlangのビルドツールです。
公式マニュアル3に従ってインストール。
$ cd gitwork/
$ git clone https://github.com/erlang/rebar3.git
Cloning into 'rebar3'...
remote: Enumerating objects: 111, done.
remote: Counting objects: 100% (111/111), done.
remote: Compressing objects: 100% (84/84), done.
remote: Total 20765 (delta 57), reused 53 (delta 27), pack-reused 20654
Receiving objects: 100% (20765/20765), 6.23 MiB | 3.30 MiB/s, done.
Resolving deltas: 100% (14204/14204), done.
$ cd rebar3
$ ./bootstrap
===> Verifying dependencies...
===> Fetching bbmustache v1.10.0
===> Fetching cth_readable v1.4.8
・・・(省略)・・・
===> Compiling certifi
===> Analyzing applications...
===> Compiling rebar
===> Building escript for rebar...
$
インストールとコマンドの実行
$ ./rebar3 local install
===> Extracting rebar3 libs to /home/pi/.cache/rebar3/vsns/3.14.1+build.4800.ref38a3db0e/lib...
===> Writing rebar3 run script /home/pi/.cache/rebar3/bin/rebar3...
===> Add to $PATH for use: export PATH=/home/pi/.cache/rebar3/bin:$PATH
#とりあえずパスを通す
#常用するなら.bashrcに追記のこと
$ export PATH=/home/pi/.cache/rebar3/bin:$PATH
$ rebar3
Rebar3 is a tool for working with Erlang projects.
Usage: rebar3 [-h] [-v] [<task>]
-h, --help Print this help.
-v, --version Show version information.
<task> Task to run.
Set the environment variable DEBUG=1 for detailed output.
Several tasks are available:
・・・(省略)・・・
Run 'rebar3 help <TASK>' for details.
$
#3.簡単なプログラムを試す
##(1)空のプロジェクト
ドキュメント4に従って進めます。
$ cd gitwork/gleam
#プロジェクトを生成
$ gleam new hello
* creating hello/LICENSE
* creating hello/.gitignore
* creating hello/README.md
* creating hello/gleam.toml
* creating hello/test/hello_test.gleam
* creating hello/src/hello.gleam
* creating hello/.github/workflows/test.yml
* creating hello/rebar.config
* creating hello/src/hello.app.src
Your Gleam project "hello" has been successfully created.
The rebar3 program can be used to compile and test it.
cd hello
rebar3 eunit
#ビルド
$ cd hello/
$ rebar3 eunit
===> Fetching rebar_gleam v0.1.0
===> Analyzing applications...
===> Compiling rebar_gleam
===> Verifying dependencies...
===> Fetching gleam_stdlib v0.11.0
Compiling hello
・・・(省略)・・・
===> Performing EUnit tests...
.
Finished in 0.037 seconds
1 tests, 0 failures
続いて、ドキュメント5に従って進めます。
コマンドhello:hello_world().
を入力すると、関数を直接実行します。
[Ctrl-C]を二回入力すると、シェルが終了します。
$ rebar3 shell
===> Verifying dependencies...
Compiling hello
Compiling gleam/option
・・・(省略)・・・
Compiling gleam/uri
Done!
===> Analyzing applications...
===> Compiling hello
Erlang/OTP 22 [erts-10.5.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Eshell V10.5.4 (abort with ^G)
1> hello:hello_world().
<<"Hello, from hello!">>
2>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
^C
$
Hello, from hello!
が表示出来ました。
ソースファイルはこちらに生成されています。
hello/src/hello.gleam
##(2)Webサーバ
Gleamのトップページに紹介されているソースコード、Examples/A basic webserver を試します。
プロジェクトを作成します。
$ cd gitwork/
#プロジェクトを作成
$ gleam new basicwebserver
* creating basicwebserver/LICENSE
* creating basicwebserver/.gitignore
* creating basicwebserver/README.md
* creating basicwebserver/gleam.toml
* creating basicwebserver/test/basicwebserver_test.gleam
* creating basicwebserver/src/basicwebserver.gleam
* creating basicwebserver/.github/workflows/test.yml
* creating basicwebserver/rebar.config
* creating basicwebserver/src/basicwebserver.app.src
Your Gleam project "basicwebserver" has been successfully created.
The rebar3 program can be used to compile and test it.
cd basicwebserver
rebar3 eunit
$ cd basicwebserver/
ソースコードを追記します。
import gleam/http/elli
import gleam/http
import gleam/bit_builder
pub fn my_service(_req) {
let body = bit_builder.from_string("Hello, world!")
http.response(200)
|> http.set_resp_body(body)
}
pub fn start() {
elli.start(my_service, on_port: 3000)
}
// ↑ ここまで追記
// ↓ 自動的に生成されている箇所
pub fn hello_world() -> String {
"Hello, from basicwebserver!"
}
依存関係のあるライブラリを追記します。
Elixirでお馴染みのmix.exs
のような書き方ですね。
{erl_opts, [debug_info]}.
{src_dirs, ["src", "gen/src"]}.
{profiles, [
{test, [{src_dirs, ["src", "test", "gen/src", "gen/test"]}]}
]}.
{project_plugins, [rebar_gleam]}.
{deps, [
{gleam_stdlib, "~> 0.11"}, //追記
{gleam_http, "~> 1.1"}, //追記
{gleam_elli, "~> 0.1"}, //追記
elli
]}.
実行
$ rebar3 shell
===> Verifying dependencies...
Compiling gleam/otp/basic_supervisor
Compiling gleam/otp/supervisor
・・・(省略)・・・
===> Analyzing applications...
===> Compiling basicwebserver
Erlang/OTP 22 [erts-10.5.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Eshell V10.5.4 (abort with ^G)
1> basicwebserver:start().
{ok,<0.221.0>}
2>
シェルから実行した後、ブラウザでアクセスします。
##(3)マルチスレッド
引き続き、Examples/Multi-threaded hello world を試します。
※プロジェクトの設定が上手くいかずコンパイルできない・・・省略
代わりにこちらを試してみました。
Echo
#ソースをクローン
$ git clone https://github.com/gleam-lang/example-echo-server.git
$ cd example-echo-server/
#コンパイルと実行
$ rebar3 shell
・・・(省略)・・・
===> Analyzing applications...
===> Compiling echo
Erlang/OTP 22 [erts-10.5.4] [source] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]
Eshell V10.5.4 (abort with ^G)
1> ===> Booted echo
#4.まとめ
今回はとりあえず、サンプルのコンパイルまでを試してみました。
まだこれからという所ではあるようですが、今後の成長が楽しみな言語です。
(HexやElixirとの連携もできるようなので、引き続き試してみたいと思います)
#5.その他
細々とした覚え書き。
##(1)古いRustではGleamのビルドができない
Raspbian Busterのapt
でインストールできるRustのバージョンは、1.34
でした。
こちらのrustc
で、gleamをコンパイルしたとき、下記のメッセージが大量にでてしまいました。
・・・(省略)・・・
'futures_api': futures in libcore are unstable (see issue #50547)
・・・(省略)・・・
この辺、良く解らないので、Rustの最新版(執筆時点は1.47
)をソースからビルドし直しました。
これを使うと、Gleamのビルドが通りました。
##(2)VS Codeの拡張機能
Gleam Syntax
という拡張機能が、既に用意されてます。(すばらしい!
コードのハイライト状態
##(3)アップデート
最新版(例ではVer.0.14.0)にアップデートします。
$ cd gitwork/rust/gleam
#ブランチ名を指定してpull
~/gitwork/rust/gleam $ git pull origin v0.14.0
remote: Enumerating objects: 524, done.
remote: Counting objects: 100% (524/524), done.
remote: Total 1598 (delta 524), reused 524 (delta 524), pack-reused 1074
Receiving objects: 100% (1598/1598), 664.41 KiB | 3.10 MiB/s, done.
Resolving deltas: 100% (1131/1131), completed with 82 local objects.
From https://github.com/gleam-lang/gleam
* tag v0.14.0 -> FETCH_HEAD
Updating 374e199..3e044d4
Fast-forward
.gitattributes | 3 +
.github/workflows/ci.yaml | 46 +-
(・・・省略・・・)
#ビルド
$ make build && make install
cargo build --release
Updating crates.io index
(・・・省略・・・)
Finished release [optimized] target(s) in 34m 17s
#バージョン確認
~/gitwork/rust/gleam $ gleam
gleam 0.14.0
#参考資料