As I needed to hack something to do a similar stuff, maybe it'll help if I post it here as answer (at least until OCamlbuild features that). So, here is the relevant part of my myocamlbuild.ml
:
open Ocamlbuild_plugin;;
dispatch begin function
| After_rules ->
(* Using both .ml and .mli files to build documentation: *)
rule "ocaml: ml & mli -> odoc"
~insert:`top
~tags:["ocaml"; "doc"; "doc_use_interf_n_implem"]
~prod:"%.odoc"
(* "%.cmo" so that cmis of ml dependencies are already built: *)
~deps:["%.ml"; "%.mli"; "%.cmo"]
begin fun env build ->
let mli = env "%.mli" and ml = env "%.ml" and odoc = env "%.odoc" in
let tags =
(Tags.union (tags_of_pathname mli) (tags_of_pathname ml))
++"doc_use_interf_n_implem"++"ocaml"++"doc" in
let include_dirs = Pathname.include_dirs_of (Pathname.dirname ml) in
let include_flags =
List.fold_right (fun p acc -> A"-I" :: A p :: acc) include_dirs [] in
Cmd (S [!Options.ocamldoc; A"-dump"; Px odoc;
T (tags++"doc"++"pp"); S (include_flags);
A"-intf"; P mli; A"-impl"; P ml])
end;
(* Specifying merge options with tags: *)
pflag ["ocaml"; "doc"; "doc_use_interf_n_implem"] "merge"
(fun s -> S[A"-m"; A s]);
end
Then adding the tag doc_use_interf_n_implem
to .ml
and/or .mli
files for which the documentation should be generated from both implementation and interface should do the trick.
With the code above, adding merging options can also be done by adding tags like for instance merge(A)
(to merge all).
Note this is a hack that may break stuffs in complex projects. Notably, I did not test it with camlp[45]
-processed files, nor with OCamlbuild versions other that 4.00.1.