mrubyの初手
環境構築からmrubyを実行するCのコードをビルドするまで。
環境構築
$ mkdir hello-mruby
$ cd hello-mruby
$ vi Dockerfile
+FROM ruby:1.9
+RUN apt update && \
+ apt install -y bison --no-install-recommends && \
+ git clone https://github.com/mruby/mruby && \
+ cd mruby && \
+ ./minirake
+ENV PATH /mruby/bin:$PATH
+CMD ["bash"]
- ドキュメントを読むと、mrubyのビルドにはRuby 1.8か1.9、gcc、ar、bisonが必要とのことだった。
ruby:1.9
のイメージをベースにして、入ってなかったbisonだけインストールした。 ./minirake
でmrubyがビルドされる。bin/
以下にmrbcなどがあるのでPATH
に追加しておく。
$ docker build . -t naoty/hello-mruby
$ docker run -it --rm naoty/hello-mruby
% mirb
mirb - Embeddable Interactive Ruby Shell
> MRUBY_VERSION
=> "2.0.1"
> exit
% exit
- Dockerでmrubyをビルドできたことを確認した。
サンプルコードを追加する
$ vi Dockerfile
FROM ruby:1.9
RUN apt update && \
apt install -y bison --no-install-recommends && \
git clone https://github.com/mruby/mruby && \
cd mruby && \
./minirake
ENV PATH /mruby/bin:$PATH
+WORKDIR /hello-mruby
+COPY . /hello-mruby/
CMD ["bash"]
- サンプルコードを用意していくので
WORKDIR
を用意する。
$ vi hello.rb
+puts "Hello, mruby!"
$ docker build . -t naoty/hello-mruby
- サンプルコードを追加してDockerイメージに追加する。
$ docker run -it --rm -v $(pwd):/hello-mruby naoty/hello-mruby
% mrbc hello.rb
% exit
- カレントディレクトリをマウントしてイメージを起動する。
- mrbcで
hello.rb
からhello.mrb
を生成する。マウントしているので、ホストにもhello.mrb
が追加されている。
Cからmrubyを実行する
$ vi hello.c
+#include <mruby.h>
+#include <mruby/dump.h>
+#include <stdio.h>
+
+int main() {
+ mrb_state *mrb = mrb_open();
+
+ FILE *fd = fopen("hello.mrb", "r");
+ mrb_load_irep_file(mrb, fd);
+
+ mrb_close(mrb);
+
+ return 0;
+}
- 生成した
hello.mrb
を実行するCのコードを書く。 - Cのコードは雰囲気で書いてるけど、
mrb_open
とmrb_close
はお約束みたいで、mrb_load_irep_file
によってmrbファイルをload
するっぽい。
$ docker run -it --rm -v $(pwd):/hello-mruby naoty/hello-mruby
% gcc hello.c -I/mruby/include -L/mruby/build/host/lib -lmruby -lm -o hello
% ./hello
Hello, mruby!
- 書いたCのコードをビルドするため、もう一度Dockerイメージを起動する。
hello.c
をgcc
でビルドするには、まずヘッダーファイルmruby.h
のパスを指定する必要がある。mrubyのヘッダーファイルは/mruby/include/
以下にあるので、-I
オプションで指定している。- 次に、mruby本体のソースコードとともに
hello.c
をビルドする必要がある。mrubyのライブラリは/mruby/build/host/lib/libmruby.a
なので、-L
オプションにパスを指定し、-l
オプションでmruby
を指定している。 - また、ビルドすると
/mruby/src/numeric.c:321: undefined reference to 'round'
のようなエラーが出てしまう。Mathのライブラリが足りなさそうなので、-lm
オプションをつけてlibm.so
をリンクしている。 - 無事にビルドできた実行可能ファイルを実行してみると、
hello.rb
で書いたコードが実行された。
追記
Rubyは最新で問題ないです!問題があれば直すべきなので1.9はやめましょう… / 1件のコメント https://t.co/uu6C7Y3g0k “mrubyの初手” (1 user) https://t.co/2bFP5uPQAu
— Uchio KONDO 🔫 (@udzura) August 7, 2019
ドキュメント(docs/guides/compile.md) を「2.0 or later」にアップデートします
— Yukihiro Matsumoto (@yukihiro_matz) August 7, 2019
とのことなので、ベースイメージをruby:2.6
にしてみたけど問題なく上記の手順ができた。