dune/src/odoc.ml

178 lines
5.6 KiB
OCaml
Raw Normal View History

2017-05-11 17:09:44 +00:00
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"
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
let html_dir = doc_dir ++ lib_public_name ++ String.capitalize m.obj_name in
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
>>>
Build.progn
[ Build.remove_tree html_dir
2017-05-29 13:51:46 +00:00
; Build.mkdir html_dir
; 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
]
; 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
(String.capitalize lib.name)
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:" "))))
>>>
Build.update_file_dyn generated_index_mld);
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 =
requires
>>>
2017-05-22 13:12:02 +00:00
SC.Libs.file_deps sctx ~ext:odoc_ext
2017-05-11 17:09:44 +00:00
>>^ Lib.include_flags
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-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
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 ]);