使いたくなったときにサッと使えるようにメモ。Docker イメージを用意しておいて docker run すればコンパイルできる、という形にしたい。
プログラムが小さいうちはわざわざ事前コンパイルしなくても問題ないのですが、大きくなってくると事前コンパイルすることによる時間短縮が効いてきますし、source map ありでデバッガが使えて捗ります
まずは Dockerfile。Opal と DXOpal を含んだイメージを作ります。素の DXOpal ではなく、フォークして修正を加えたブランチを使っているのがポイント(後述)。
# Dockerfile
FROM ubuntu:22.04
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
git \
ruby \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN echo 'gem: --no-document' >> ~/.gemrc
RUN gem instal opal -v 1.2.0
WORKDIR /opt
RUN git clone \
--branch v1.5.2-no-opal-parser \
https://github.com/sonota88/dxopal.git
RUN mkdir /tmp/work
WORKDIR /tmp/work
適当なシェルスクリプト run.sh
。
#!/bin/bash
IMG_NAME=dxopal-builder:1
cmd_build_image() {
docker build -t $IMG_NAME .
}
cmd_compile() {
local rbfile="$1"; shift
local cmd=""
cmd="${cmd}docker run --rm -it "
cmd="${cmd} -v$(pwd):/tmp/work "
# コンテナ外の DXOpal を使う場合
# cmd="${cmd} -v/path/to/dxopal:/opt/dxopal "
cmd="${cmd} ${IMG_NAME} "
cmd="${cmd} opal --compile --no-opal --no-exit "
cmd="${cmd} --include /opt/dxopal/lib "
cmd="${cmd} --include . "
cmd="${cmd} $rbfile "
$cmd # 組み立てたコマンドを実行
}
cmd="$1"; shift
case $cmd in
build-image )
cmd_build_image
;; compile )
cmd_compile "$@"
;; * )
echo "unknown command (${cmd})" >&2
exit 1
;;
esac
イメージをビルド。
./run.sh build-image
イメージができたら、コンパイルしたいファイルを渡してコンパイルします。以下は DXOpal のサイトにあるサンプルコードを使った例。
$ cat my_app.rb
require 'dxopal'; include DXOpal
Window.width = 300
Window.height = 300
Window.bgcolor = C_WHITE
Window.load_resources do
x = rand(Window.width)
y = rand(Window.height)
dx = dy = 2
Window.loop do
Window.draw_circle_fill(x, y, 10, C_RED)
dx = -dx if x < 0 || x > Window.width
dy = -dy if y < 0 || y > Window.height
x += dx
y += dy
end
end
$ ./run.sh compile my_app.rb > my_app.js
JavaScript に変換できたら、 my_app.js
を HTML ファイルから読み込むようにして、ブラウザで開けばOK。
<!-- 最低限だとこんな感じ -->
<html>
<body>
<canvas id="dxopal-canvas"></canvas>
<div id="dxopal-errors"></div>
<script src="my_app.js"></script>
</body>
</html>
source map 付きでコンパイルされるので、ブラウザの開発者ツールで Ruby のソースをそのまま見ることができ、デバッガも利用できます。
参考: Opal::Builder を使ってコンパイルする際に source map も生成する
メモ
opal-parser の除外
事前コンパイルする場合は opal-parser を含めないようにするとよいので、除外するようにしたブランチを git clone しています(上記 Dockerfile 参照)。
参考: DxOpalのゲームをコンパクトにして公開する方法 - Qiita
DXOpal 本体に手を加えてコンパイルしたい
DXOpal 本体に手を加えないと実現できない機能がある場合や、DXOpal をいじってあれこれ実験したい場合があります。
その場合は、docker run でコンパイルする際に -v
オプションを使って DXOpal のディレクトリをマウントします。こうすることで、あらかじめイメージ内に入れておいた DXOpal の代わりに自分で修正した DXOpal が参照されるようになります。
docker run -v "{コンテナ外にあるDXOpalのディレクトリ}:/opt/dxopal" ...