OSXでjs_of_ocamlの動く環境を構築する

ocamlからjsを生成する。altjsの一種なんだろうけど、結構激しい。 前々からビルドが成功しなかったんだけど、今やっと成功したのでメモ置いとく。

ocamlあんまり詳しくないんだけど、昨日「プログラミングの基礎」を買ったので、それなりにモチベーションがある。

プログラミングの基礎 (Computer Science Library)

プログラミングの基礎 (Computer Science Library)

参考

環境は MacBookPro OSX 10.9

インストール

基本的にはこれの通りやったんだけど、少々変更する必要があった。

Shared Library Error on Ocsigen Platform | The Terminal

opam

opamはパッケージマネージャ。 上の記事を信用すると brewがまずいらしいので、opamをインストールスクリプトを使って入れる。

wget http://www.ocamlpro.com/pub/opam_installer.sh
sh ./opam_installer.sh /usr/local/bin

初期化

opam init --comp 4.01.0

元記事だと4.00.1で初期化していたが、OSX 10.9 だとclangのオプションがあわずocamlのビルドに失敗していた。ので 4.01.0でビルドしてみたら通った。

次に環境変数周りを整理。 ~/.zshrc に追記。

eval `opam config env`

これで通るらしいが、自分の環境だとopam経由のライブラリの実行パスに上手く通ってくれなかったので、代わりに次のを書いて直接通した。バージョンが変わるとハマるかもしれないので、忘れないようにしたい。

export PATH=$HOME/.opam/4.01.0/bin:$PATH

次に opamでocamlfindをインストール。環境変数周りをよしなにしてくれる。

opam install ocamlfind

which ocamlfind で通ってるパスがみえたらおk。見えない場合は環境変数周りを確認。

js_of_ocaml のインストール

最初、opamはnpmとかrubygems並に依存解決を行うものだと思っていたが、実は全然依存パッケージが整理されておらず(たぶんCI通したりする文化がない)、手作業である程度潰す必要があることに気づいた。

opam install ssl
opam install pcre-ocaml
opam install ocamlnet
opam install cryptokit
opam install ocaml-text
opam install calendar
opam install lwt
opam install deriving-ocsigen
opam install js_of_ocaml

なぜかはよくわからないけど、この順番で実行するとインストールに成功した。直接 opam install js_of_ocaml するとlwtのビルドに失敗する。依存が解決できてなさそう。

js_of_ocamljavascriptコンパイルしてみる

面倒な人はサンプルのリポジトリを作ったので、以下のリポチトリをcloneして ./build を叩く。 mizchi/simple_js_of_ocaml_project

コンパイルする

下手にハマりたくないので最小コードで試す。

hello.ml

open Js
let _ = Unsafe.eval_string "
console.log('hello js of ocaml!');
"

hello.cmoを作る。cmoが何かはよく知らないけど、たぶん何かの中間形式だろう。

ocamlfind ocamlc -package lwt,js_of_ocaml.syntax -g -c hello.ml

cmoからhello.byteを作る。

ocamlfind ocamlc -package lwt,js_of_ocaml.syntax -I ~/.opam/4.01.0/lib/stublibs -g -linkpkg -o hello.byte js_of_ocaml.cma hello.cmo

hello.byteからhello.jsを生成

js_of_ocaml hello.byte

本来のサンプルだと -I ~/.opam/4.01.0/lib/stublibs は不要らしいが、自分の場合はopamの設定に失敗しているのか、直接 dlljs_of_ocaml.so がある場所を指定してやらないと動かなかった。(このとき、brewで作った環境と同じエラーメッセージが出たので、もしかしたらこれだけで動くかもしれない)

hello.jsが生成できたら、あとはhtmlからhello.jsを開くだけ。おしまい。