Edited at

ocamlfind の公式ドキュメントの個人的まとめ

More than 1 year has passed since last update.

パッケージのインストールや依存関係の管理は opam を使えばよいが、ちょっとしたコンパイルや古めのソースを確認するときには依然ocamlfind の知識は必要そうなので、公式ドキュメントの個人的まとめ。


ocamlfind の依存管理が解決するもの


  1. ライブラリをファイル階層順に保存する

  2. 保存したライブラリを使用したプログラムのコンパイルとリンク

  3. ライブラリの依存管理

Findlibは、特定のディレクトリ構造を保つことが必要。

任意の場所にファイルをインストールすることはできない。

findlibはファイルリストを保持していない。

すべてのライブラリは、ライブラリのアーカイブファイルとインタフェースファイルのような独自のディレクトリに格納される。


Findlib

ocamlfind は Findlib のコマンドラインインターフェイス。


  1. ocamlc、ocamlopt、ocamlmktop、ocamlcpを呼び出して、パッケージングやリンクに必要なコンパイラの引数を自動的に追加できる

  2. パッケージのインストールとアンインストール

  3. 依存パッケージの発見


簡単な使い方


  • 他の人が書いたパッケージをリンクする場合


    • コンパイラを起動するコマンドを変更


    • ocamlc program.mlocamlfind 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))})])}
=========