type holyshared = Engineer<mixed>

技術的なことなど色々

jbuilderでビルドに必要なファイルを生成する

jbuilderでビルドに必要なファイルを生成する方法を調べました。
なんで調べたかというと、atdgenjsonのパーサーのコードを出力したかったからです。

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

jbuilderatdgenをインストールします。

opam install atdgen jbuilder

ruleをjbuildファイルに追加する

次のようなJSONスキーマファイルがある場合、jbuildファイルにruleを追加するだけでOKです。
スキーマファイルはuser.atdします。(拡張子はなんでもいいはず)

スキーマファイル

type user = {
  name: string;
  description: string;
}

jbuildファイル

targetsに生成されるファイルを指定して、depsに依存しているファイルを指定します。
また、actionで実行するコマンドを指定します。

パラメータ

パラメータ 説明
\${@} targetsで指定したファイルリスト
\${<} depsで指定したファイルリスト
\${bin:} プログラム名、PATHなどからプログラムを検索する

他にもあるので、variables-expansionを参照してください。

JSONパーサーの生成

JSONパーサーを生成するruleは下記の通りです。

(rule (
  (targets (user_j.ml user_j.mli))
  (deps (user.atd))
  (action (run ${bin:atdgen} -j ${<}))
))

実際に発行されるコマンドは下記の通りです。

atdgen -j user.atd 

型の定義ファイルの生成

型の定義ファイルの生成するruleは下記の通りです。

(rule (
  (targets (user_t.ml user_t.mli))
  (deps (user.atd))
  (action (run ${bin:atdgen} -t ${<}))
))

実際に発行されるコマンドは下記の通りです。

atdgen -t user.atd 

jbuildファイルのlibrariesを追加する

jbuildファイルのlibrary設定のlibrariesにatdgenを指定します。

(library (
  (public_name user)
  (name user)
  (libraries (atdgen))
))

また、user.mlファイルには生成されたコードを利用するようにしてみます。
User_tは生成される予定のモジュールです。

let make ~name ~description =
  User_t.({ name=name; description=description })

ビルドできるか試す

ビルドコマンドでビルドできるか試します。

jbuilder build

Unbound moduleなどのコンパイルエラーが出なければ問題ないはずです。
生成されたコードは_buildのサブディレクトリにオブジェクトファイルなどと一緒に出力されるようで、 コードの管理からは外れていて問題ないようです。

実際に試したコードは下記にあります。
example_jbuilder_with_atdgen