これは ML Advent Calendar 2017 の 6日目の記事です.
ご案内: Jbuilder (Dune) でもっと楽に OCaml プロジェクトを作る もご覧ください。
Oasis は OCaml のビルドツールの一つです. 最低限必要な設定ファイルを作れば,ありがちな依存解析を全て自動的にやってくれて便利です. いわゆる ./configure && make && make install 式のインストーラをうまいこと自動生成してくれます. さらに OCamlfind (Findlib) 周りもよしなにしてくれるので,他の OCamlfind パッケージを使ったり,自前のパッケージの開発も簡単にできます.
しかし,Oasis の日本語の解説記事はこれといって見当たりません.そこで,この記事では私が Oasis をどのように使っているかを書きます. こまかいことは Oasis のマニュアル を読んでください. 具体例としては,大きいものだと Tyxml があり,他には "_oasis" で github をググる などの方法もあります.
Oasis と OCaml のビルドシステム
Oasis は,他のビルドシステム (OCamlbulid か Omake) を呼び出してプロジェクトをビルドします.Oasis が各ツールのビルドスクリプトを自動生成してくれるのです.
実際,既存のビルドシステムにはそれぞれ一長一短があるように思います:
- make. OCamlマニュアルには,典型的な Makefile の例 が掲載されていますが,よほど小さなプロジェクト以外には使えないでしょう. シリアスに Makefile で生きていくなら,よく使う定義をまとめた OCamlMakefile を使うのが良いかもしれませんが,試したことはない.
-
OCamlbuild は OCaml コンパイラについてくるので可搬性が高いですが,ビルド規則を OCaml のソースコード (
myocamlbuild.ml) に書くのがいかにも複雑な感じです. - Omake は, OCamlプロジェクトに限らず使える柔軟性と汎用性が強みであり,広く使われていますが,私には OMakefile の敷居が高かったです (ヘタレ.一応,使おうとした形跡 はあります).
- Jbuilder は Jane Street Capital 発で,今後のデファクトになっていきそうな感じがしますが,S式を書きたくないのと,よく知らないので今回はパスです.
Oasis なら, _oasis という設定ファイルに最低限のことを書くだけで良いです.
使い方
-
_oasisファイルを作る (下記).
-
Library(またはExecutable) セクションを作る -
Modulesフィールドに最低1つのモジュールを書いておく.
oasis setup
-
Makefileや./configure,setup.mlなどのスクリプト一式が生成される.
-
make(&& make install)
簡単ですね.また,./configure (ocaml setup.ml -configure) は, 初回に make を叩いた時に自動で呼ばれます.
注意:
- プロジェクトにモジュールを追加した時は,
_oasisを編集してoasis setupを呼ぶ - 何故かビルドが上手くいかなくなったら
make distcleanか,git clean -fdXで要らないファイルを削除してoasis setupを再実行する.このため.gitignoreも載せておきます.
_oasis ファイル
OCamlfind で使える典型的なパッケージを作る場合は次のような _oasis を作ります.実行ファイルを作るときは Library を Executable に変えるだけです.複数のライブラリや実行ファイルも書けます.
OASISFormat: 0.4
Plugins: META (0.4), DevFiles (0.4)
BuildTools: ocamlbuild
Name: ocamlsample
Version: 0.1
Homepage: https://github.com/keigoi/ocamlsample
Synopsis: A sample library
Authors: Keigo Imai
License: Apache
Library samplelib
Path: lib
Findlibname: samplelib
BuildDepends: threads, str
Modules: Sample
Oasis プラグイン:
-
METAプラグイン は OCamlfind の META ファイルを生成 -
DevFilesプラグイン は(setup.mlを呼ぶだけの)スクリプト configure や Makefile を生成
Library セクションについて.
-
Pathは,ソースコードを置くディレクトリです.他の Library や Executable とは重複できないようです. -
Findlibnameは,このライブラリを使う時にocamlfind -package パッケージ名で指定する時のパッケージ名になります. -
BuildDependsには依存する OCamlfind のパッケージ名を書きます. -
Modulesは,ライブラリに含めるモジュールのリスト.ファイル名ではなく,モジュール名(sample.mlならSampleのように). - OCamlfind 向けのオプション:
FindlibParent(親パッケージ),XMETAType(ppx を作る場合には syntax などと書く),XMETARequires(他の依存パッケージ),XMETAExtraLines(META に追加する行. ppx の実行ファイル等を指定) など
テスト (Test) やドキュメント生成 (Document), リポジトリ情報 (SourceRepository) のためのセクションもあります.マニュアルを見よ.
インストール
make install で適当な位置にライブラリをインストールしてくれます. Executables はデフォルトでは /usr/local/bin に入るはず. インストール位置は全て, ./configure に与えるオプションで変えられます.
$ make install
ocaml setup.ml -install
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/sample.ml
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/samplelib.cma
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/samplelib.cmxa
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/samplelib.a
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/samplelib.cmxs
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/sample.cmi
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/sample.cmt
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/sample.annot
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/sample.cmx
Installed /Users/keigoi/.opam/4.05.0+flambda/lib/samplelib/META
やったね!
OMake を使う場合
ビルドシステムとして OMake を使う場合は,BuildTools: ocamlbuild の代わりに,以下のように書けばよいようです.
OCamlVersion: >= 4.01
BuildType: OMake (0.4)
BuildTools: omake
配布時に必要なファイル
私は,最低限 ./configure && make && make install をできるようにしておきたいので,以下のファイルはリポジトリにコミットしています.
Makefile
configure
myocamlbuild.ml (OCamlbuild の場合)
setup.ml
**/META
**/*.mldylib
**/*.mllib
.gitignore
これを書いておいて,何か変なことになったら git clean -fdX しています.
*.annot
*.cmo
*.cma
*.cmi
*.a
*.o
*.cmx
*.cmxs
*.cmxa
*.cmt
# ocamlbuild working directory
_build/
# ocamlbuild targets
*.byte
*.native
# oasis generated files
setup.data
setup.log
# omake files
*.omc
*.om
.omakedb
.omakedb.lock
PPX を伴うライブラリを作る
PPX を提供するライブラリを作るときは次のようにします.
- Executable でプリプロセッサの実行形式を作る (仮に
ppx_exampleとする) - 提供するライブラリの Library に
XMETAExtraLines: ppx = "ppx_example"を追加する
同じプロジェクトの他のソースコード(テストコード等)で PPX を使いたい場合は、_tags ファイルに
# OASIS_START
# OASIS_STOP
<test/*.ml>: ppx_example
と書いておいて, myocamlbulid.ml でなんとかするしかないようです.例
気になること
-
makeする度にocaml setup.ml -buildが走るが,このときに 1秒くらい固まる気がする.もっとサクサク動かない? - 偶に
makeが失敗しoasis setupしてもビルドできない状態に陥る.私は何も考えずgit clean -fdXしているが….
まとめ
Oasis は, _oasis から OCamlbuild の myocamlbuild.ml や OMake の OMakefile, OMakeroot を生成してくれる便利ツールで, OCaml のツールチェインに慣れていない人でも使えるのではないかと思います. Oasis で happy OCaml life を!