2017-05-11 17:09:44 +00:00
|
|
|
open Import
|
2017-06-02 13:32:05 +00:00
|
|
|
open Jbuild
|
2017-05-11 17:09:44 +00:00
|
|
|
open Build.O
|
|
|
|
|
|
|
|
module SC = Super_context
|
|
|
|
|
|
|
|
let ( ++ ) = Path.relative
|
|
|
|
|
|
|
|
let get_odoc sctx = SC.resolve_program sctx "odoc" ~hint:"opam install odoc"
|
2017-05-22 13:12:02 +00:00
|
|
|
let odoc_ext = ".odoc"
|
2017-05-11 17:09:44 +00:00
|
|
|
|
|
|
|
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
|
2017-05-12 17:05:59 +00:00
|
|
|
~lib_public_name ~(lib : Library.t) =
|
2017-05-11 17:09:44 +00:00
|
|
|
let context = SC.context sctx in
|
2017-07-06 12:32:46 +00:00
|
|
|
let html_dir = doc_dir ++ lib_public_name ++ String.capitalize_ascii m.obj_name in
|
2017-05-25 15:57:29 +00:00
|
|
|
let html_file = html_dir ++ "index.html" in
|
2017-05-11 17:09:44 +00:00
|
|
|
SC.add_rule sctx
|
2017-05-22 13:12:02 +00:00
|
|
|
(SC.Libs.static_file_deps (dir, lib) ~ext:odoc_ext
|
2017-05-11 17:09:44 +00:00
|
|
|
>>>
|
|
|
|
includes
|
|
|
|
>>>
|
2017-05-25 15:57:29 +00:00
|
|
|
Build.progn
|
2017-05-26 17:08:07 +00:00
|
|
|
[ Build.remove_tree html_dir
|
2017-05-29 13:51:46 +00:00
|
|
|
; Build.mkdir html_dir
|
2017-05-26 17:08:07 +00:00
|
|
|
; Build.run ~context ~dir odoc ~extra_targets:[html_file]
|
2017-05-25 15:57:29 +00:00
|
|
|
[ A "html"
|
|
|
|
; Dyn (fun x -> x)
|
|
|
|
; A "-I"; Path dir
|
|
|
|
; A "-o"; Path doc_dir
|
|
|
|
; Dep odoc_file
|
|
|
|
]
|
|
|
|
; Build.create_file (html_dir ++ Config.jbuilder_keep_fname)
|
|
|
|
]
|
|
|
|
);
|
2017-05-11 17:09:44 +00:00
|
|
|
html_file
|
|
|
|
|
2017-05-12 14:05:16 +00:00
|
|
|
let lib_index sctx ~odoc ~dir ~(lib : Library.t) ~lib_public_name ~doc_dir ~modules
|
|
|
|
~includes =
|
|
|
|
let context = SC.context sctx in
|
|
|
|
let generated_index_mld = dir ++ sprintf "%s-generated.mld" lib.name in
|
|
|
|
let source_index_mld = dir ++ sprintf "%s.mld" lib.name in
|
|
|
|
let header = {|{%html:<nav><a href="..">Up</a></nav>%}|} in
|
|
|
|
SC.add_rule sctx
|
|
|
|
(Build.if_file_exists source_index_mld
|
|
|
|
~then_:(Build.contents source_index_mld
|
|
|
|
>>^ fun s -> sprintf "%s\n%s" header s)
|
|
|
|
~else_:(Build.arr (fun () ->
|
|
|
|
(if lib.wrapped then
|
|
|
|
sprintf
|
|
|
|
"%s\n\
|
|
|
|
{1 Library %s}\n\
|
|
|
|
The entry point for this library is module {!module:%s}."
|
|
|
|
header
|
|
|
|
lib_public_name
|
2017-07-06 12:32:46 +00:00
|
|
|
(String.capitalize_ascii lib.name)
|
2017-05-12 14:05:16 +00:00
|
|
|
else
|
|
|
|
sprintf
|
|
|
|
"%s\n\
|
|
|
|
{1 Library %s}\n\
|
|
|
|
This library exposes the following toplevel modules: {!modules:%s}."
|
|
|
|
header
|
|
|
|
lib_public_name
|
|
|
|
(String_map.keys modules |> String.concat ~sep:" "))))
|
|
|
|
>>>
|
2017-08-17 13:03:11 +00:00
|
|
|
Build.write_file_dyn generated_index_mld);
|
2017-05-12 14:05:16 +00:00
|
|
|
let html_file =
|
|
|
|
doc_dir ++ lib_public_name ++ "index.html"
|
|
|
|
in
|
|
|
|
SC.add_rule sctx
|
2017-05-22 13:12:02 +00:00
|
|
|
(SC.Libs.static_file_deps (dir, lib) ~ext:odoc_ext
|
2017-05-12 14:05:16 +00:00
|
|
|
>>>
|
|
|
|
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
|
|
|
|
; A "--index-for"; A lib_public_name
|
|
|
|
; Dep generated_index_mld
|
|
|
|
]);
|
|
|
|
html_file
|
|
|
|
|
2017-05-22 13:12:02 +00:00
|
|
|
let doc_dir ~context = Path.relative context.Context.build_dir "_doc"
|
2017-05-11 17:09:44 +00:00
|
|
|
|
2017-05-22 13:12:02 +00:00
|
|
|
let css_file ~doc_dir = doc_dir ++ "odoc.css"
|
2017-05-11 17:09:44 +00:00
|
|
|
|
|
|
|
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 =
|
2017-05-15 14:18:41 +00:00
|
|
|
Build.memoize "odoc deps"
|
|
|
|
((* 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))
|
2017-05-11 17:09:44 +00:00
|
|
|
in
|
|
|
|
let odoc = get_odoc sctx in
|
|
|
|
let includes =
|
2017-07-21 14:43:44 +00:00
|
|
|
Build.memoize "includes"
|
|
|
|
(requires
|
|
|
|
>>>
|
|
|
|
SC.Libs.file_deps sctx ~ext:odoc_ext
|
2017-07-21 16:30:51 +00:00
|
|
|
>>^ Lib.include_flags)
|
2017-05-11 17:09:44 +00:00
|
|
|
in
|
2017-05-12 14:05:16 +00:00
|
|
|
let modules_and_odoc_files =
|
2017-05-11 17:09:44 +00:00
|
|
|
List.map (String_map.values modules)
|
|
|
|
~f:(compile_module sctx ~odoc ~dir ~includes ~dep_graph ~modules
|
|
|
|
~lib_public_name:public.name)
|
|
|
|
in
|
2017-05-22 13:12:02 +00:00
|
|
|
SC.Libs.setup_file_deps_alias sctx ~ext:odoc_ext (dir, lib)
|
2017-05-12 14:05:16 +00:00
|
|
|
(List.map modules_and_odoc_files ~f:snd);
|
2017-05-22 13:12:02 +00:00
|
|
|
let doc_dir = doc_dir ~context in
|
2017-05-29 14:49:29 +00:00
|
|
|
(*
|
2017-05-12 14:05:16 +00:00
|
|
|
let modules_and_odoc_files =
|
2017-05-11 17:09:44 +00:00
|
|
|
if lib.wrapped then
|
|
|
|
let main_module_name = String.capitalize_ascii lib.name in
|
2017-05-12 14:05:16 +00:00
|
|
|
List.filter modules_and_odoc_files
|
|
|
|
~f:(fun (m, _) -> m.Module.name = main_module_name)
|
2017-05-11 17:09:44 +00:00
|
|
|
else
|
2017-05-12 14:05:16 +00:00
|
|
|
modules_and_odoc_files
|
2017-05-29 14:49:29 +00:00
|
|
|
in*)
|
2017-05-11 17:09:44 +00:00
|
|
|
let html_files =
|
2017-05-12 14:05:16 +00:00
|
|
|
List.map modules_and_odoc_files ~f:(fun (m, odoc_file) ->
|
2017-05-12 17:05:59 +00:00
|
|
|
to_html sctx m odoc_file ~doc_dir ~odoc ~dir ~includes ~lib
|
2017-05-11 17:09:44 +00:00
|
|
|
~lib_public_name:public.name)
|
|
|
|
in
|
2017-05-12 14:05:16 +00:00
|
|
|
let lib_index_html =
|
|
|
|
lib_index sctx ~dir ~lib ~lib_public_name:public.name ~doc_dir
|
|
|
|
~modules ~includes ~odoc
|
|
|
|
in
|
2017-05-22 13:12:02 +00:00
|
|
|
Alias.add_deps (SC.aliases sctx) (Alias.doc ~dir)
|
|
|
|
(css_file ~doc_dir
|
2017-05-12 14:05:16 +00:00
|
|
|
:: lib_index_html
|
|
|
|
:: html_files))
|
2017-05-11 17:09:44 +00:00
|
|
|
|
|
|
|
let setup_css_rule sctx =
|
|
|
|
let context = SC.context sctx in
|
2017-05-22 13:12:02 +00:00
|
|
|
let doc_dir = doc_dir ~context in
|
2017-05-11 17:09:44 +00:00
|
|
|
SC.add_rule sctx
|
|
|
|
(Build.run ~context
|
|
|
|
~dir:context.build_dir
|
2017-05-22 13:12:02 +00:00
|
|
|
~extra_targets:[css_file ~doc_dir]
|
2017-05-11 17:09:44 +00:00
|
|
|
(get_odoc sctx)
|
|
|
|
[ A "css"; A "-o"; Path doc_dir ]);
|