OCamlのパッケージインストール時にファイルをコピーする

OCamlプログラムをduneを使用してビルドしている場合、インストールする時にバイナリファイル以外のファイルも一緒にコピーしたい場合があると思います。

それをopam、duneを使用している時にどのように行うか調べました。

Duneの設定

設定はduneファイルにStanzaの設定を追加するだけです。 dune.readthedocs.io

filesにコピーしたいファイル、sectionにコピー先、packageにパッケージ名を指定します。
パッケージ管理にopamを利用している場合は、/[ホームディレクトリ]/.opam/[コンパイラバージョン]/[Sectionで指定したカテゴリ]/[パッケージ名] にファイルがコピーされます。

具体的には /Users/holyshared/.opam/4.09.0/share/ogenになります。

(install
  (files ../templates/opam.mustache ../templates/default.mk)
  (section share)
  (package my_package)
)

大抵の場合はexecutable, executables stanzaのいずれかと一緒に指定する事になると思います。

(executables
  (names main)
  (public_names ogen)
  (libraries ogen cmdliner)
)

(install
  (files ../templates/opam.mustache ../templates/default.mk)
  (section share)
  (package my_package)
)

プログラムからのファイルの参照

インストール時にコピーしたファイルを読み込んだりしたい時、opamの場合はパスを環境変数のOPAM_SWITCH_PREFIXを利用して解決します。

OPAM_SWITCH_PREFIX/[ホームディレクトリ]/.opam/[コンパイラバージョン]/ になります。
これはopamでコンパイラのバージョン切り替えたりしても正しく切り替わります。

この環境変数は /[ホームディレクトリ]/.opam/opam-init/variables.sh に定義されています。
後はプログラムで Sys.getenv_opt などを利用してパスを取得します。

let prefix = match Sys.getenv_opt "OPAM_SWITCH_PREFIX" with
  | Some v -> v
  | None -> ""

パッケージのインストール

パッケージのインストールはビルドした後に、installコマンドを実行することでローカルにインストールできます。

dune build
dune install