パッケージのインストールや依存関係の管理は opam
を使えばよいが、ちょっとしたコンパイルや古めのソースを確認するときには依然ocamlfind
の知識は必要そうなので、公式ドキュメントの個人的まとめ。
ocamlfind の依存管理が解決するもの
- ライブラリをファイル階層順に保存する
- 保存したライブラリを使用したプログラムのコンパイルとリンク
- ライブラリの依存管理
Findlibは、特定のディレクトリ構造を保つことが必要。
任意の場所にファイルをインストールすることはできない。
findlibはファイルリストを保持していない。
すべてのライブラリは、ライブラリのアーカイブファイルとインタフェースファイルのような独自のディレクトリに格納される。
Findlib
ocamlfind は Findlib のコマンドラインインターフェイス。
- ocamlc、ocamlopt、ocamlmktop、ocamlcpを呼び出して、パッケージングやリンクに必要なコンパイラの引数を自動的に追加できる
- パッケージのインストールとアンインストール
- 依存パッケージの発見
簡単な使い方
- 他の人が書いたパッケージをリンクする場合
- コンパイラを起動するコマンドを変更
-
ocamlc program.ml
→ocamlfind ocamlc -package name_of_package_to_use -linkpkg program.ml
-
program.ml
内の指定されたパッケージを参照することができる
-
- モジュールのコレクションをパッケージにする場合
- 必要な他のパッケージなど、必要な情報を記述した管理ファイル(META)を書き込む
Packages を使う
ocamlfind list
でインストールされてるパッケージ一覧を表示。 -describe
オプションで詳細も表示。
パッケージのあるディレクトリを表示
ocamlfind query 名前
ちなみに標準では /usr/local/lib/ocaml/site-lib
にOCamlライブラリが格納されることが多い(らしい)。
環境変数 OCAMLPATH
が設定されていると、先にそのパスを見に行く。
次に findlib.conf (ocamlfind.conf?)
の設定を見に行く。
$ cat ~/.opam/4.06.0/lib/findlib.conf
destdir="/Users/hoge/.opam/4.06.0/lib"
path="/Users/hoge/.opam/4.06.0/lib"
ocamlc="ocamlc.opt"
ocamlopt="ocamlopt.opt"
ocamldep="ocamldep.opt"
ocamldoc="ocamldoc.opt"
METAファイル
METAファイルの記述例
description = "説明文をここに"
requires = "必要なパッケージ名をカンマ区切りで並べて書く,hoge,fuga"
version = "1"
パッケージが使用するときに実際にリンクするファイル名をカンマ区切りで並べる(byte, native で別に書く)
archive(byte) = "p.cma"
archive(native) = "p.cmxa"
上記の (byte)
や (native)
などの括弧内の値の指定を 述語
という。
METAファイルに記述されている情報の取得
ocamlfind query -long-format パッケージ名
や -predicates
オプションで述語指定したりもできる。
ocamlfind query -long-format -predicates byte,native camlp4
-recursive
を付けると、 require
で指定されている依存先パッケージのMETAの情報も見れる。
findlibでプログラムをコンパイル&リンクする
コンパイル
ocamlfind ocamlc -package hoge -c main.ml
これは以下と等価(ライブラリのパスは例)
ライブラリのインクルードをよしなに行ってくれる。
ocamlc -I /usr/local/lib/ocaml/site-lib/hoge -c main.ml
リンク
ocamlfind ocamlc -o program -package hoge -linkpkg prog1.cmo prog2.cmo prog3.cmo
これは以下と等価。
ocamlc -o program -I /usr/local/lib/ocaml/site-lib/hoge hoge.cma prog1.cmo prog2.cmo prog3.cmo
ocamlfind経由で呼び出される場合は、コンパイラオプションはオリジナルのもの加えてocamlfindが提供するものも使えるようになる。
-package <name>
-linkpkg
-predicates <predicate-list>
-dontlink <name>
-passopt <opt>
コンパイルのみを行う場合、つまり -c
オプションが有効な場合、通常は -package
オプションが必要
インストールしたパッケージのサブコマンドを呼び出す
PATHを通さなくても ocamlfind 経由で呼び出せて便利
ocamlfind パッケージ名/バイナリ名
例: ppx_tools
でインストールされるコマンドを呼び出す
$ opam install ppx_tools
The following actions will be performed:
∗ install ppx_tools 5.1+4.06.0
=-=- Gathering sources =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 🐫
[default] https://opam.ocaml.org/archives/ppx_tools.5.1+4.06.0+opam.tar.gz downloaded
=-=- Processing actions -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 🐫
∗ installed ppx_tools.5.1+4.06.0
Done.
$ ocamlfind ppx_tools/dumpast -e "1 + 2"
1 + 2
==>
{pexp_desc =
Pexp_apply ({pexp_desc = Pexp_ident {txt = Lident "+"}},
[(Nolabel, {pexp_desc = Pexp_constant (Pconst_integer ("1", None))});
(Nolabel, {pexp_desc = Pexp_constant (Pconst_integer ("2", None))})])}
=========