OCamlのプロジェクトをduneを使って管理してみる。
Duneとは
Dune は OCaml 用のビルドシステムです。 似たようなものにoasisと言うのもありますが、こちらの方が新しくて簡単らしいです。
インストール
OPAM
が入っている前提でいきます。
opam install dune
インストールができたらバージョンを確認してみます。
dune --version
2.5.1
執筆時点では、2.5.1がインストールされました。
プロジェクトを作成する
早速プロジェクトを作成していきます。myproject
と言うプロジェクトを作成してみます。
dune init project myproject
これを実行すると、以下のようなファイル群が作成されます。
myproject
├── bin
│ ├── dune
│ └── main.ml
├── lib
│ └── dune
├── myproject.opam
└── test
├── dune
└── myproject.ml
各ディレクトリに入っているdune
ファイルが設定ファイルになります。
bin
が実行ファイル、lib
がライブラリ、test
がテスト用のディレクトリです。
コマンドのproject
部分をexecutable
, test
, library
にするとそれそれ単体で作成することもできます。
ビルドしてみる
プロジェクトが作成できたら、まずはビルドしてみます。
dune build
すると_build
と言うディレクトリとdune-project
と言うファイルができるはずです。
_build
にはビルドした生成物が入っています。
dune-project
はプロジェクト全体の設定を記述するファイルです。
プロジェクト全体の情報を記述する
dune-project
はの中身は初期状態だと以下のようになっていると思います。
(lang dune 2.5)
(name myproject)
ここにプロジェクトの情報を記述していきます。
(記述しなくても普通にビルドは通るので飛ばしてもOK)
(lang dune 2.5)
(name myproject)
(version 0.0.0)
(generate_opam_files true)
(source (github username/myproject))
(license MIT)
(authors "author<email@email.com>" "author2<email2@email.com>")
(maintainers "author<email@email.com>")
(package
(name myproject)
(synopsis "Short description")
(description "Long description")
(depends
(ounit :with-test)
(dune (> 1.5))))
(generate_opam_files true)
を設定してパッケージに関する情報を記述すると次にビルドされたときに<project_name>.opam
が自動生成されます。
上記の例では、依存関係にounit
とduen
自身を指定してみました。
duneファイルの中身を記述する
それぞれのディレクトリに入っているdune
ファイルに情報を追加していきます。bin/dune
(executable
(public_name myproject)
(name main)
(libraries myproject))
初期状態だとこんな感じだと思います。(executable
がこのディレクトリないのファイルが実行ファイルとしてコンパイルされることを示します。
(public_name myproject)
はdune
コマンドで指定する際の名称です。
(name main)
と設定してあればmain.ml
がエントリーポイントになります。
(libraries myproject)
部分が、依存するライブラリです。
プロジェクトで依存するライブラリがあればここに追加していきます。(libraries deplib1 deplib2)
みたいな感じです。
後述する、lib
ディレクトリのライブラリの名称をmylib
に変更するので(libraries
部分を書き換えます。
(executable
(public_name myproject)
(name main)
(libraries mylib))
lib/dune
の初期状態
(library
(name myproject))
(library
部分がこのディレクトリの中身がライブラリ(モジュール)であることを示します。(name myproject)
部分がエントリーポイント(モジュール名)になります。
依存するライブラリがあれば先ほどと同様に(libraries
を書き加えます。
(name )
部分をmylib
に書き換えます。mylib.ml
がモジュールになります。
外から利用する場合はMylib.~~
みたいな形で使えます。
(library
(name mylib))
**test/dune
の初期状態 **
(test
(name myproject))
(test
部分がこのディレクトリないのファイルがテストであることを示します。(name myproject)
部分でテストの際のエントリーポイントを指定します。
(name \test)
に変更してエントリーポイントをtest.ml
とかにするとわかりやすいかと思います。
ここにounitを追加してみます。
(test
(name myproject_test)
(libraries oUnit))
あとは、ごく簡単な実行の仕方の紹介です。
実行してみる
dune exec
を実行するとbin
ディレクトリの中身がコンパイルされて実行されます。
main.ml
を編集していなければ、Hello, World
が表示されると思います。
テストを実行する
dune runtest
を実行するとtest
ディレクトリの中身がコンパイルされてテストが実行されます。
ビルドキャッシュを削除する
ビルドキャッシュとは言っても_build
を消すだけです。
dune clean
最後に
以上、簡単にOCamlのビルドシステムのduneを試してみました。
参考
https://dune.build/ https://qiita.com/keigoi/items/a68298fcd39322004fed