Start of odoc rules

This commit is contained in:
Jeremie Dimino 2017-05-11 18:09:44 +01:00 committed by Jérémie Dimino
parent e301f38358
commit 7f8f4b23ee
7 changed files with 160 additions and 0 deletions

View File

@ -44,11 +44,13 @@ let file_with_digest_suffix t ~digest =
let default = make "DEFAULT"
let runtest = make "runtest"
let install = make "install"
let doc = make "doc"
let recursive_aliases =
[ default
; runtest
; install
; doc
]
module Store = struct

View File

@ -5,6 +5,7 @@ val make : string -> dir:Path.t -> t
val default : dir:Path.t -> t
val runtest : dir:Path.t -> t
val install : dir:Path.t -> t
val doc : dir:Path.t -> t
val dep : t -> ('a, 'a) Build.t
val file : t -> Path.t

View File

@ -365,6 +365,9 @@ module Gen(P : Params) = struct
SC.add_rule sctx build
);
(* Odoc *)
Odoc.setup_library_rules sctx lib ~dir ~requires ~modules ~dep_graph;
let flags =
match alias_module with
| None -> flags.common
@ -629,6 +632,7 @@ module Gen(P : Params) = struct
let () = List.iter (SC.stanzas sctx) ~f:rules
let () =
SC.add_rules sctx (Js_of_ocaml_rules.setup_separate_compilation_rules sctx)
let () = Odoc.setup_css_rule sctx
(* +-----------------------------------------------------------------+
| META |

View File

@ -46,3 +46,10 @@ let cmt_file t ~dir (kind : Ml_kind.t) =
match kind with
| Impl -> Some (Path.relative dir (t.obj_name ^ ".cmt"))
| Intf -> Option.map t.intf ~f:(fun _ -> Path.relative dir (t.obj_name ^ ".cmti"))
let odoc_file t ~dir = Path.relative dir (t.obj_name ^ ".odoc")
let cmti_file t ~dir =
match t.intf with
| None -> Path.relative dir (t.obj_name ^ ".cmt")
| Some _ -> Path.relative dir (t.obj_name ^ ".cmti")

View File

@ -30,3 +30,8 @@ val file : t -> dir:Path.t -> Ml_kind.t -> Path.t option
val cm_source : t -> dir:Path.t -> Cm_kind.t -> Path.t option
val cm_file : t -> dir:Path.t -> Cm_kind.t -> Path.t
val cmt_file : t -> dir:Path.t -> Ml_kind.t -> Path.t option
val odoc_file : t -> dir:Path.t -> Path.t
(** Either the .cmti, or .cmt if the module has no interface *)
val cmti_file : t -> dir:Path.t -> Path.t

126
src/odoc.ml Normal file
View File

@ -0,0 +1,126 @@
open Import
open Jbuild_types
open Build.O
module SC = Super_context
let ( ++ ) = Path.relative
let get_odoc sctx = SC.resolve_program sctx "odoc" ~hint:"opam install odoc"
let lib_odoc_all ~dir (lib : Library.t) =
Alias.file (Alias.lib_odoc_all ~dir lib.name)
let lib_dependencies (libs : Lib.t list) =
List.filter_map libs ~f:(function
| External _ -> None
| Internal (dir, lib) -> Some (lib_odoc_all ~dir lib))
let module_deps (m : Module.t) ~dir ~dep_graph ~modules =
Build.dyn_paths
(dep_graph
>>^ fun graph ->
List.map (Utils.find_deps ~dir graph m.name)
~f:(fun name ->
let m = Utils.find_module ~dir modules name in
Module.odoc_file m ~dir))
let compile_module sctx (m : Module.t) ~odoc ~dir ~includes ~dep_graph ~modules
~lib_public_name =
let context = SC.context sctx in
let odoc_file = Module.odoc_file m ~dir in
SC.add_rule sctx
(module_deps m ~dir ~dep_graph ~modules
>>>
includes
>>>
Build.run ~context ~dir odoc ~extra_targets:[odoc_file]
[ A "compile"
; Dyn (fun x -> x)
; A "-I"; Path dir
; As ["--pkg"; lib_public_name]
; Dep (Module.cmti_file m ~dir)
]);
(m, odoc_file)
let to_html sctx (m : Module.t) odoc_file ~doc_dir ~odoc ~dir ~includes
~dep_graph ~modules ~lib_public_name =
let context = SC.context sctx in
let html_file =
doc_dir ++ lib_public_name ++ m.name ++ "index.html"
in
SC.add_rule sctx
(module_deps m ~dir ~dep_graph ~modules
>>>
includes
>>>
Build.run ~context ~dir odoc ~extra_targets:[html_file]
[ A "html"
; Dyn (fun x -> x)
; A "-I"; Path dir
; A "-o"; Path doc_dir
; Dep odoc_file
]);
html_file
let doc_dir = Path.of_string "_build/doc"
let css_file sctx =
let context = SC.context sctx in
doc_dir ++ context.name ++ "odoc.css"
let setup_library_rules sctx (lib : Library.t) ~dir ~modules ~requires
~(dep_graph:Ocamldep.dep_graph) =
Option.iter lib.public ~f:(fun public ->
let context = SC.context sctx in
let dep_graph =
(* Use the dependency graph given by ocamldep. However, when a module has no .mli,
use the dependencies for the .ml *)
Build.fanout dep_graph.intf dep_graph.impl
>>^ fun (intf, impl) ->
String_map.merge intf impl ~f:(fun _ intf impl ->
match intf, impl with
| Some _, _ -> intf
| None, Some _ -> impl
| None, None -> assert false)
in
let odoc = get_odoc sctx in
let includes =
requires
>>>
Build.dyn_paths (Build.arr lib_dependencies)
>>^ Lib.include_flags
in
let odoc_files =
List.map (String_map.values modules)
~f:(compile_module sctx ~odoc ~dir ~includes ~dep_graph ~modules
~lib_public_name:public.name)
in
let aliases = SC.aliases sctx in
Alias.add_deps aliases (Alias.lib_odoc_all ~dir lib.name)
(List.map odoc_files ~f:snd);
let doc_dir = doc_dir ++ context.name in
let odoc_files =
if lib.wrapped then
let main_module_name = String.capitalize_ascii lib.name in
List.filter odoc_files ~f:(fun (m, _) -> m.Module.name = main_module_name)
else
odoc_files
in
let html_files =
List.map odoc_files ~f:(fun (m, odoc_file) ->
to_html sctx m odoc_file ~doc_dir ~odoc ~dir ~includes ~dep_graph ~modules
~lib_public_name:public.name)
in
Alias.add_deps aliases (Alias.doc ~dir) (css_file sctx :: html_files))
let setup_css_rule sctx =
let context = SC.context sctx in
let doc_dir = doc_dir ++ context.name in
SC.add_rule sctx
(Build.run ~context
~dir:context.build_dir
~extra_targets:[doc_dir ++ "odoc.css"]
(get_odoc sctx)
[ A "css"; A "-o"; Path doc_dir ]);

15
src/odoc.mli Normal file
View File

@ -0,0 +1,15 @@
(** Odoc rules *)
open Import
open Jbuild_types
val setup_library_rules
: Super_context.t
-> Library.t
-> dir:Path.t
-> modules:Module.t String_map.t
-> requires:(unit, Lib.t list) Build.t
-> dep_graph:Ocamldep.dep_graph
-> unit
val setup_css_rule : Super_context.t -> unit