From 3ec09d2093927af827eb974df690505355e1323d Mon Sep 17 00:00:00 2001 From: octoio <144470924+octoio@users.noreply.github.com> Date: Tue, 30 Sep 2025 19:29:27 -0700 Subject: [PATCH 1/3] Add automated ATD rule generation guide for Dune --- doc/atdgen-tutorial.rst | 145 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 10 deletions(-) diff --git a/doc/atdgen-tutorial.rst b/doc/atdgen-tutorial.rst index 07960a38..1130f4e4 100644 --- a/doc/atdgen-tutorial.rst +++ b/doc/atdgen-tutorial.rst @@ -1228,31 +1228,156 @@ There is an `atdgen plugin for ocamlbuild `_. + (rule + (targets example_v.ml example_v.mli) + (deps example.atd) + (mode fallback) + (action (run atdgen -v %{deps}))) + +You can refer to ``example_t.ml``, ``example_j.ml``, and ``example_v.ml`` as usual +(by default, they will be automatically linked into the library being built in the +same directory). Note that any options ``atdgen`` supports can be included in the ``run atdgen`` section (``-open``, ``-deriving-conv``, etc.). +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) + (mode fallback) + (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) + (mode fallback) + (action + (run atdgen -t %%{deps}))) + + |} + base base base; + (* Generate -v rules *) + Printf.printf + {|(rule + (targets %s_v.ml %s_v.mli) + (deps %s.atd) + (mode fallback) + (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 --------------------------- From 2003ba7369fa8564fe6785a949f168f2ec557cf3 Mon Sep 17 00:00:00 2001 From: octoio <144470924+octoio@users.noreply.github.com> Date: Tue, 30 Sep 2025 19:36:41 -0700 Subject: [PATCH 2/3] Adjust the manual section --- doc/atdgen-tutorial.rst | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/doc/atdgen-tutorial.rst b/doc/atdgen-tutorial.rst index 1130f4e4..e7acae0e 100644 --- a/doc/atdgen-tutorial.rst +++ b/doc/atdgen-tutorial.rst @@ -1238,30 +1238,25 @@ Given an ``example.atd``, you can manually specify rules like: :: (rule - (targets example_j.ml example_j.mli) + (targets example_j.ml + example_j.mli) (deps example.atd) - (mode fallback) (action (run atdgen -j -j-std %{deps}))) (rule - (targets example_t.ml example_t.mli) + (targets example_t.ml + example_t.mli) (deps example.atd) - (mode fallback) (action (run atdgen -t %{deps}))) - (rule - (targets example_v.ml example_v.mli) - (deps example.atd) - (mode fallback) - (action (run atdgen -v %{deps}))) - -You can refer to ``example_t.ml``, ``example_j.ml``, and ``example_v.ml`` as usual -(by default, they will be automatically linked into the library being built in the -same directory). +You can refer to ``example_t.ml`` and ``example_j.ml`` as usual (by default, they +will be automatically linked into the library being built in the same directory). 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 34704102fb8a80721407d7a99e52f5566e69cd4b Mon Sep 17 00:00:00 2001 From: octoio <144470924+octoio@users.noreply.github.com> Date: Mon, 13 Oct 2025 18:01:52 +0000 Subject: [PATCH 3/3] Remove 'mode fallback' lines from atdgen rule generation examples --- doc/atdgen-tutorial.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/atdgen-tutorial.rst b/doc/atdgen-tutorial.rst index e7acae0e..06b8feb9 100644 --- a/doc/atdgen-tutorial.rst +++ b/doc/atdgen-tutorial.rst @@ -1281,7 +1281,6 @@ to automatically generate rules for all ``.atd`` files in a directory. {|(rule (targets %s_j.ml %s_j.mli) (deps %s.atd) - (mode fallback) (action (run atdgen -j -j-std %%{deps}))) @@ -1292,7 +1291,6 @@ to automatically generate rules for all ``.atd`` files in a directory. {|(rule (targets %s_t.ml %s_t.mli) (deps %s.atd) - (mode fallback) (action (run atdgen -t %%{deps}))) @@ -1303,7 +1301,6 @@ to automatically generate rules for all ``.atd`` files in a directory. {|(rule (targets %s_v.ml %s_v.mli) (deps %s.atd) - (mode fallback) (action (run atdgen -v %%{deps})))