Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making ocamlbuild pass both .ml and .mli files to ocamldoc

I want to include source code in my generated docs. This works when I invoke ocamldoc on the command-line like this: ocamldoc -I _build -html -keep-code -colorize-code *.{ml,mli} -d .docdir. However, I'm having troubles integrating this with ocamlbuild.

I'm using the following code in myocamlbuild.ml:

open Ocamlbuild_plugin;;

dispatch begin function
  | After_options ->
      Options.ocamldoc := S[A"ocamldoc"; A"-keep-code"; A"-colorize-code"]
  | _ -> ()
end

But this only includes the source for files with no corresponding interface file - contrary to what is said here, it looks like ocamlbuild refuses to pass .ml files to ocamldoc when there is an .mli file present. Is there a way to coax ocamlbuild into doing what I want?

like image 859
Mikhail Glushenkov Avatar asked Dec 11 '12 20:12

Mikhail Glushenkov


2 Answers

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.

like image 52
nberth Avatar answered Oct 18 '22 03:10

nberth


It seems that there is currently no support for that in OCamlbuild. Could you please submit a feature request for this on the bugtracker?

like image 31
gasche Avatar answered Oct 18 '22 04:10

gasche