diff --git a/doc/atdgen-tutorial.rst b/doc/atdgen-tutorial.rst index 07960a38..06b8feb9 100644 --- a/doc/atdgen-tutorial.rst +++ b/doc/atdgen-tutorial.rst @@ -1228,8 +1228,12 @@ There is an `atdgen plugin for ocamlbuild `_. Note that any options ``atdgen`` supports can be included in the ``run atdgen`` section (``-open``, ``-deriving-conv``, etc.). +You will need to write rules for each .atd file individually or ... + +Automated Approach with Code Generation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While Dune does not yet support `wildcard rules `_, +you can work around this limitation using Dune's `rule generation feature `_ +to automatically generate rules for all ``.atd`` files in a directory. + +**Step 1:** Create a generator directory (e.g., ``gen/``) with a ``dune`` file: + +:: + + (executable + (name gen)) + +**Step 2:** Create the generator OCaml program (``gen/gen.ml``): + +:: + + let generate_atdgen_rules base = + (* Generate -j rules *) + Printf.printf + {|(rule + (targets %s_j.ml %s_j.mli) + (deps %s.atd) + (action + (run atdgen -j -j-std %%{deps}))) + + |} + base base base; + (* Generate -t rules *) + Printf.printf + {|(rule + (targets %s_t.ml %s_t.mli) + (deps %s.atd) + (action + (run atdgen -t %%{deps}))) + + |} + base base base; + (* Generate -v rules *) + Printf.printf + {|(rule + (targets %s_v.ml %s_v.mli) + (deps %s.atd) + (action + (run atdgen -v %%{deps}))) + + |} + base base base + ;; + + let collect_atd_files () = + Sys.readdir "." + |> Array.to_list + |> List.sort String.compare + |> List.filter_map (fun filename -> + match Filename.chop_suffix_opt ~suffix:".atd" filename with + | Some base -> Some base + | None -> None) + ;; + + let () = + let atd_files = collect_atd_files () in + List.iter generate_atdgen_rules atd_files + ;; + +**Step 3:** Create an empty ``dune.inc`` file: + +:: + + ; Generated rules will be included here + +**Step 4:** Update your main ``dune`` file to include and generate ``dune.inc``: + +:: + + ; Include auto-generated rules for .atd files + (include dune.inc) + + ; Generate the dune.inc file from all .atd files + (rule + (alias genatd) + (mode promote) + (deps (glob_files *.atd)) + (action + (with-stdout-to + dune.inc + (run gen/gen.exe)))) + +**Step 5:** Generate the initial ``dune.inc`` file: + +:: + + $ dune build @genatd + +This only needs to be run once when you first create the empty ``dune.inc`` file. + +**Step 6:** Build your project: + +:: + + $ dune build + +From this point forward, Dune will automatically regenerate ``dune.inc`` whenever +you add, remove, or modify ``.atd`` files. The generated rules will be promoted +to your source tree automatically. + +This approach is especially useful when working with many ``.atd`` files, as it +eliminates the need to manually maintain build rules for each file. You can also +customize the generator to add project-specific ``atdgen`` flags (like +``-deriving-conv "eq,show"`` or ``-j-strict-fields``) or generate additional +stanzas (like library definitions with auto-discovered modules). + Dealing with untypable JSON ---------------------------