2017-04-28 14:12:05 +00:00
|
|
|
open Import
|
|
|
|
open Build.O
|
2017-05-18 16:11:39 +00:00
|
|
|
open! No_io
|
2017-04-28 14:12:05 +00:00
|
|
|
|
|
|
|
module SC = Super_context
|
|
|
|
|
|
|
|
let build_cm sctx ?sandbox ~dynlink ~flags ~cm_kind ~(dep_graph:Ocamldep.dep_graph)
|
2017-07-21 15:52:28 +00:00
|
|
|
~requires ~(modules : Module.t String_map.t) ~dir ~alias_module (m : Module.t) =
|
2017-04-28 14:12:05 +00:00
|
|
|
let ctx = SC.context sctx in
|
|
|
|
Option.iter (Mode.of_cm_kind cm_kind |> Context.compiler ctx) ~f:(fun compiler ->
|
|
|
|
Option.iter (Module.cm_source ~dir m cm_kind) ~f:(fun src ->
|
|
|
|
let ml_kind = Cm_kind.source cm_kind in
|
|
|
|
let dst = Module.cm_file m ~dir cm_kind in
|
|
|
|
let extra_args, extra_deps, extra_targets =
|
|
|
|
match cm_kind, m.intf with
|
|
|
|
(* If there is no mli, [ocamlY -c file.ml] produces both the
|
|
|
|
.cmY and .cmi. We choose to use ocamlc to produce the cmi
|
|
|
|
and to produce the cmx we have to wait to avoid race
|
|
|
|
conditions. *)
|
|
|
|
| Cmo, None -> [], [], [Module.cm_file m ~dir Cmi]
|
|
|
|
| Cmx, None ->
|
|
|
|
(* Change [-intf-suffix] so that the compiler thinks the
|
|
|
|
cmi exists and reads it instead of re-creating it, which
|
|
|
|
could create a race condition. *)
|
|
|
|
([ "-intf-suffix"
|
|
|
|
; Filename.extension m.impl.name
|
|
|
|
],
|
|
|
|
[Module.cm_file m ~dir Cmi], [])
|
|
|
|
| Cmi, None -> assert false
|
|
|
|
| Cmi, Some _ -> [], [], []
|
|
|
|
(* We need the .cmi to build either the .cmo or .cmx *)
|
|
|
|
| (Cmo | Cmx), Some _ -> [], [Module.cm_file m ~dir Cmi], []
|
|
|
|
in
|
|
|
|
let extra_targets =
|
|
|
|
match cm_kind with
|
|
|
|
| Cmx -> Path.relative dir (m.obj_name ^ ctx.ext_obj) :: extra_targets
|
|
|
|
| Cmi | Cmo -> extra_targets
|
|
|
|
in
|
|
|
|
let dep_graph = Ml_kind.Dict.get dep_graph ml_kind in
|
|
|
|
let other_cm_files =
|
|
|
|
Build.dyn_paths
|
|
|
|
(dep_graph >>^ (fun dep_graph ->
|
|
|
|
let deps =
|
|
|
|
List.map (Utils.find_deps ~dir dep_graph m.name)
|
|
|
|
~f:(Utils.find_module ~dir modules)
|
|
|
|
in
|
|
|
|
List.concat_map
|
|
|
|
deps
|
|
|
|
~f:(fun m ->
|
|
|
|
match cm_kind with
|
|
|
|
| Cmi | Cmo -> [Module.cm_file m ~dir Cmi]
|
|
|
|
| Cmx -> [Module.cm_file m ~dir Cmi; Module.cm_file m ~dir Cmx])))
|
|
|
|
in
|
|
|
|
let extra_targets, cmt_args =
|
|
|
|
match cm_kind with
|
|
|
|
| Cmx -> (extra_targets, Arg_spec.S [])
|
|
|
|
| Cmi | Cmo ->
|
|
|
|
let fn = Option.value_exn (Module.cmt_file m ~dir ml_kind) in
|
|
|
|
(fn :: extra_targets, A "-bin-annot")
|
|
|
|
in
|
2017-05-15 13:46:23 +00:00
|
|
|
SC.add_rule sctx ?sandbox
|
2017-04-28 14:12:05 +00:00
|
|
|
(Build.paths extra_deps >>>
|
|
|
|
other_cm_files >>>
|
2017-06-15 10:02:19 +00:00
|
|
|
requires &&&
|
|
|
|
Ocaml_flags.get_for_cm flags ~cm_kind >>>
|
2017-11-07 13:42:55 +00:00
|
|
|
Build.run ~context:ctx (Ok compiler)
|
2017-05-15 13:46:23 +00:00
|
|
|
~extra_targets
|
2017-06-15 10:02:19 +00:00
|
|
|
[ Dyn (fun (_, ocaml_flags) -> As ocaml_flags)
|
2017-04-28 14:12:05 +00:00
|
|
|
; cmt_args
|
2017-06-15 10:02:19 +00:00
|
|
|
; Dyn (fun (libs, _) -> Lib.include_flags libs)
|
2017-04-28 14:12:05 +00:00
|
|
|
; As extra_args
|
|
|
|
; if dynlink || cm_kind <> Cmx then As [] else A "-nodynlink"
|
|
|
|
; A "-no-alias-deps"
|
|
|
|
; A "-I"; Path dir
|
|
|
|
; (match alias_module with
|
|
|
|
| None -> S []
|
|
|
|
| Some (m : Module.t) -> As ["-open"; m.name])
|
2017-05-15 13:46:23 +00:00
|
|
|
; A "-o"; Target dst
|
2017-04-28 14:12:05 +00:00
|
|
|
; A "-c"; Ml_kind.flag ml_kind; Dep src
|
|
|
|
])))
|
|
|
|
|
2017-07-05 19:55:17 +00:00
|
|
|
let build_module sctx ?sandbox ~dynlink ~js_of_ocaml ~flags m ~scope ~dir ~dep_graph
|
2017-05-18 12:49:56 +00:00
|
|
|
~modules ~requires ~alias_module =
|
2017-04-28 14:12:05 +00:00
|
|
|
List.iter Cm_kind.all ~f:(fun cm_kind ->
|
2017-05-18 12:49:56 +00:00
|
|
|
let requires = Cm_kind.Dict.get requires cm_kind in
|
2017-07-21 15:52:28 +00:00
|
|
|
build_cm sctx ?sandbox ~dynlink ~flags ~dir ~dep_graph ~modules m ~cm_kind
|
2017-05-18 12:49:56 +00:00
|
|
|
~requires ~alias_module);
|
2017-05-02 10:25:37 +00:00
|
|
|
(* Build *.cmo.js *)
|
|
|
|
let src = Module.cm_file m ~dir Cm_kind.Cmo in
|
2017-07-05 19:55:17 +00:00
|
|
|
SC.add_rules sctx (Js_of_ocaml_rules.build_cm sctx ~scope ~dir ~js_of_ocaml ~src)
|
2017-04-28 14:12:05 +00:00
|
|
|
|
2017-07-05 19:55:17 +00:00
|
|
|
let build_modules sctx ~dynlink ~js_of_ocaml ~flags ~scope ~dir ~dep_graph ~modules ~requires
|
2017-05-29 13:06:52 +00:00
|
|
|
~alias_module =
|
2017-05-18 12:49:56 +00:00
|
|
|
let cmi_requires =
|
|
|
|
Build.memoize "cmi library dependencies"
|
|
|
|
(requires
|
|
|
|
>>>
|
|
|
|
SC.Libs.file_deps sctx ~ext:".cmi")
|
|
|
|
in
|
|
|
|
let cmi_and_cmx_requires =
|
|
|
|
Build.memoize "cmi and cmx library dependencies"
|
|
|
|
(requires
|
|
|
|
>>>
|
|
|
|
SC.Libs.file_deps sctx ~ext:".cmi-and-.cmx")
|
|
|
|
in
|
|
|
|
let requires : _ Cm_kind.Dict.t =
|
|
|
|
{ cmi = cmi_requires
|
|
|
|
; cmo = cmi_requires
|
|
|
|
; cmx = cmi_and_cmx_requires
|
|
|
|
}
|
|
|
|
in
|
2017-04-28 14:12:05 +00:00
|
|
|
String_map.iter
|
|
|
|
(match alias_module with
|
|
|
|
| None -> modules
|
|
|
|
| Some (m : Module.t) -> String_map.remove m.name modules)
|
|
|
|
~f:(fun ~key:_ ~data:m ->
|
2017-07-05 19:55:17 +00:00
|
|
|
build_module sctx m ~dynlink ~js_of_ocaml ~flags ~scope ~dir ~dep_graph ~modules ~requires
|
2017-04-28 14:12:05 +00:00
|
|
|
~alias_module)
|