Add Compilation_context
Signed-off-by: Jeremie Dimino <jeremie@dimino.org>
This commit is contained in:
parent
69af40dced
commit
c9ead23c7d
|
@ -0,0 +1,84 @@
|
|||
open Import
|
||||
|
||||
module SC = Super_context
|
||||
|
||||
module Includes = struct
|
||||
type t = string list Arg_spec.t Cm_kind.Dict.t
|
||||
|
||||
let make sctx ~requires : _ Cm_kind.Dict.t =
|
||||
match requires with
|
||||
| Error exn -> Cm_kind.Dict.make_all (Arg_spec.Dyn (fun _ -> raise exn))
|
||||
| Ok libs ->
|
||||
let iflags =
|
||||
Lib.L.include_flags libs ~stdlib_dir:(SC.context sctx).stdlib_dir
|
||||
in
|
||||
let cmi_includes =
|
||||
Arg_spec.S [ iflags
|
||||
; Hidden_deps
|
||||
(SC.Libs.file_deps sctx libs ~ext:".cmi")
|
||||
]
|
||||
in
|
||||
let cmi_and_cmx_includes =
|
||||
Arg_spec.S [ iflags
|
||||
; Hidden_deps
|
||||
(SC.Libs.file_deps sctx libs ~ext:".cmi-and-.cmx")
|
||||
]
|
||||
in
|
||||
{ cmi = cmi_includes
|
||||
; cmo = cmi_includes
|
||||
; cmx = cmi_and_cmx_includes
|
||||
}
|
||||
|
||||
let empty =
|
||||
Cm_kind.Dict.make_all (Arg_spec.As [])
|
||||
end
|
||||
|
||||
type t =
|
||||
{ super_context : Super_context.t
|
||||
; scope : Scope.t
|
||||
; dir : Path.t
|
||||
; obj_dir : Path.t
|
||||
; modules : Module.t Module.Name.Map.t
|
||||
; alias_module : Module.t option
|
||||
; lib_interface_module : Module.t option
|
||||
; flags : Ocaml_flags.t
|
||||
; requires : Lib.t list Or_exn.t
|
||||
; includes : Includes.t
|
||||
; preprocessing : Preprocessing.t
|
||||
}
|
||||
|
||||
let super_context t = t.super_context
|
||||
let scope t = t.scope
|
||||
let dir t = t.dir
|
||||
let obj_dir t = t.obj_dir
|
||||
let modules t = t.modules
|
||||
let alias_module t = t.alias_module
|
||||
let lib_interface_module t = t.lib_interface_module
|
||||
let flags t = t.flags
|
||||
let requires t = t.requires
|
||||
let includes t = t.includes
|
||||
let preprocessing t = t.preprocessing
|
||||
|
||||
let create ~super_context ~scope ~dir ?(obj_dir=dir) ~modules ?alias_module
|
||||
?lib_interface_module ~flags ~requires
|
||||
?(preprocessing=Preprocessing.dummy) () =
|
||||
{ super_context
|
||||
; scope
|
||||
; dir
|
||||
; obj_dir
|
||||
; modules
|
||||
; alias_module
|
||||
; lib_interface_module
|
||||
; flags
|
||||
; requires
|
||||
; includes = Includes.make super_context ~requires
|
||||
; preprocessing
|
||||
}
|
||||
|
||||
let for_alias_module t =
|
||||
let flags = Ocaml_flags.default ~profile:(SC.profile t.super_context) in
|
||||
{ t with
|
||||
flags = Ocaml_flags.append_common flags ["-w"; "-49"]
|
||||
; includes = Includes.empty
|
||||
; alias_module = None
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
(** High-level API for compiling OCaml files *)
|
||||
|
||||
open Import
|
||||
|
||||
(** Represent a compilation context.
|
||||
|
||||
A compilation context contains all the necessary information to
|
||||
preprocess and compile OCaml source files. Exactly one compilation
|
||||
context is associated to each library, executable and executbales
|
||||
stanza.
|
||||
*)
|
||||
type t
|
||||
|
||||
(** Create a compilation context. *)
|
||||
val create
|
||||
: super_context : Super_context.t
|
||||
-> scope : Scope.t
|
||||
-> dir : Path.t
|
||||
-> ?obj_dir : Path.t
|
||||
-> modules : Module.t Module.Name.Map.t
|
||||
-> ?alias_module : Module.t
|
||||
-> ?lib_interface_module : Module.t
|
||||
-> flags : Ocaml_flags.t
|
||||
-> requires : Lib.t list Or_exn.t
|
||||
-> ?preprocessing : Preprocessing.t
|
||||
-> unit
|
||||
-> t
|
||||
|
||||
(** Return a compilation context suitable for compiling the alias module. *)
|
||||
val for_alias_module : t -> t
|
||||
|
||||
val super_context : t -> Super_context.t
|
||||
val scope : t -> Scope.t
|
||||
val dir : t -> Path.t
|
||||
val obj_dir : t -> Path.t
|
||||
val modules : t -> Module.t Module.Name.Map.t
|
||||
val alias_module : t -> Module.t option
|
||||
val lib_interface_module : t -> Module.t option
|
||||
val flags : t -> Ocaml_flags.t
|
||||
val requires : t -> Lib.t list Or_exn.t
|
||||
val includes : t -> string list Arg_spec.t Cm_kind.Dict.t
|
||||
val preprocessing : t -> Preprocessing.t
|
54
src/exe.ml
54
src/exe.ml
|
@ -1,6 +1,7 @@
|
|||
open Import
|
||||
open Build.O
|
||||
|
||||
module CC = Compilation_context
|
||||
module SC = Super_context
|
||||
|
||||
module Program = struct
|
||||
|
@ -103,19 +104,18 @@ module Linkage = struct
|
|||
end
|
||||
|
||||
let link_exe
|
||||
~dir
|
||||
~obj_dir
|
||||
~scope
|
||||
~requires
|
||||
~name
|
||||
~(linkage:Linkage.t)
|
||||
~top_sorted_modules
|
||||
?(flags=Ocaml_flags.empty)
|
||||
?(link_flags=Build.arr (fun _ -> []))
|
||||
?(js_of_ocaml=Jbuild.Js_of_ocaml.default)
|
||||
sctx
|
||||
cctx
|
||||
=
|
||||
let ctx = SC.context sctx in
|
||||
let sctx = CC.super_context cctx in
|
||||
let ctx = SC.context sctx in
|
||||
let dir = CC.dir cctx in
|
||||
let obj_dir = CC.obj_dir cctx in
|
||||
let requires = CC.requires cctx in
|
||||
let mode = linkage.mode in
|
||||
let exe = Path.relative dir (name ^ linkage.ext) in
|
||||
let compiler = Option.value_exn (Context.compiler ctx mode) in
|
||||
|
@ -139,7 +139,7 @@ let link_exe
|
|||
SC.add_rule sctx
|
||||
(Build.fanout3
|
||||
(register_native_objs_deps modules_and_cm_files >>^ snd)
|
||||
(Ocaml_flags.get flags mode)
|
||||
(Ocaml_flags.get (CC.flags cctx) mode)
|
||||
link_flags
|
||||
>>>
|
||||
Build.of_result_map requires ~f:(fun libs ->
|
||||
|
@ -162,57 +162,39 @@ let link_exe
|
|||
let cm_and_flags =
|
||||
Build.fanout
|
||||
(modules_and_cm_files >>^ snd)
|
||||
(SC.expand_and_eval_set sctx ~scope ~dir js_of_ocaml.flags
|
||||
(SC.expand_and_eval_set sctx ~scope:(CC.scope cctx) ~dir
|
||||
js_of_ocaml.flags
|
||||
~standard:(Build.return (Js_of_ocaml_rules.standard sctx)))
|
||||
in
|
||||
SC.add_rules sctx (List.map rules ~f:(fun r -> cm_and_flags >>> r))
|
||||
|
||||
let build_and_link_many
|
||||
~dir ~obj_dir ~programs ~modules
|
||||
~scope
|
||||
~programs
|
||||
~linkages
|
||||
?(requires=Ok [])
|
||||
?already_used
|
||||
?(flags=Ocaml_flags.empty)
|
||||
?link_flags
|
||||
?(js_of_ocaml=Jbuild.Js_of_ocaml.default)
|
||||
sctx
|
||||
cctx
|
||||
=
|
||||
let modules =
|
||||
Module.Name.Map.map modules ~f:(Module.set_obj_name ~wrapper:None)
|
||||
in
|
||||
|
||||
let dep_graphs =
|
||||
Ocamldep.rules sctx ~dir ~modules ?already_used
|
||||
~alias_module:None ~lib_interface_module:None
|
||||
in
|
||||
let dep_graphs = Ocamldep.rules cctx ?already_used in
|
||||
|
||||
(* CR-someday jdimino: this should probably say [~dynlink:false] *)
|
||||
Module_compilation.build_modules sctx
|
||||
~js_of_ocaml
|
||||
~dynlink:true ~flags ~scope ~dir ~obj_dir ~dep_graphs ~modules
|
||||
~alias_module:None
|
||||
~includes:(Module_compilation.Includes.make sctx ~requires);
|
||||
Module_compilation.build_modules cctx ~js_of_ocaml ~dep_graphs;
|
||||
|
||||
List.iter programs ~f:(fun { Program.name; main_module_name } ->
|
||||
let top_sorted_modules =
|
||||
let main = Option.value_exn
|
||||
(Module.Name.Map.find modules main_module_name) in
|
||||
(Module.Name.Map.find (CC.modules cctx) main_module_name) in
|
||||
Ocamldep.Dep_graph.top_closed_implementations dep_graphs.impl
|
||||
[main]
|
||||
in
|
||||
List.iter linkages ~f:(fun linkage ->
|
||||
link_exe sctx
|
||||
~dir
|
||||
~obj_dir
|
||||
~scope
|
||||
~requires
|
||||
link_exe cctx
|
||||
~name
|
||||
~linkage
|
||||
~top_sorted_modules
|
||||
~js_of_ocaml
|
||||
~flags
|
||||
?link_flags))
|
||||
|
||||
let build_and_link ~dir ~obj_dir ~program =
|
||||
build_and_link_many ~dir ~obj_dir ~programs:[program]
|
||||
let build_and_link ~program =
|
||||
build_and_link_many ~programs:[program]
|
||||
|
|
31
src/exe.mli
31
src/exe.mli
|
@ -1,7 +1,5 @@
|
|||
(** Compilation and linking of executables *)
|
||||
|
||||
open Import
|
||||
|
||||
module Program : sig
|
||||
type t =
|
||||
{ name : string
|
||||
|
@ -39,48 +37,31 @@ end
|
|||
(** Build and link one or more executables *)
|
||||
|
||||
val build_and_link
|
||||
: dir:Path.t
|
||||
-> obj_dir:Path.t
|
||||
-> program:Program.t
|
||||
-> modules:Module.t Module.Name.Map.t
|
||||
-> scope:Scope.t
|
||||
: program:Program.t
|
||||
-> linkages:Linkage.t list
|
||||
-> ?requires:Lib.t list Or_exn.t
|
||||
-> ?already_used:Module.Name.Set.t
|
||||
-> ?flags:Ocaml_flags.t
|
||||
-> ?link_flags:(unit, string list) Build.t
|
||||
-> ?js_of_ocaml:Jbuild.Js_of_ocaml.t
|
||||
-> Super_context.t
|
||||
-> Compilation_context.t
|
||||
-> unit
|
||||
|
||||
val build_and_link_many
|
||||
: dir:Path.t
|
||||
-> obj_dir:Path.t
|
||||
-> programs:Program.t list
|
||||
-> modules:Module.t Module.Name.Map.t
|
||||
-> scope:Scope.t
|
||||
: programs:Program.t list
|
||||
-> linkages:Linkage.t list
|
||||
-> ?requires:Lib.t list Or_exn.t
|
||||
-> ?already_used:Module.Name.Set.t
|
||||
-> ?flags:Ocaml_flags.t
|
||||
-> ?link_flags:(unit, string list) Build.t
|
||||
-> ?js_of_ocaml:Jbuild.Js_of_ocaml.t
|
||||
-> Super_context.t
|
||||
-> Compilation_context.t
|
||||
-> unit
|
||||
|
||||
(** {1 Low-level functions} *)
|
||||
|
||||
(** Link a single executable *)
|
||||
val link_exe
|
||||
: dir:Path.t
|
||||
-> obj_dir:Path.t
|
||||
-> scope:Scope.t
|
||||
-> requires:Lib.t list Or_exn.t
|
||||
-> name:string
|
||||
: name:string
|
||||
-> linkage:Linkage.t
|
||||
-> top_sorted_modules:(unit, Module.t list) Build.t
|
||||
-> ?flags:Ocaml_flags.t
|
||||
-> ?link_flags:(unit, string list) Build.t
|
||||
-> ?js_of_ocaml:Jbuild.Js_of_ocaml.t
|
||||
-> Super_context.t
|
||||
-> Compilation_context.t
|
||||
-> unit
|
||||
|
|
|
@ -572,14 +572,26 @@ module Gen(P : Install_rules.Params) = struct
|
|||
| Some m -> Module.Name.Map.add modules m.name m
|
||||
in
|
||||
|
||||
let dep_graphs =
|
||||
Ocamldep.rules sctx ~dir ~modules ~already_used ~alias_module
|
||||
~lib_interface_module:(
|
||||
if lib.wrapped then
|
||||
Module.Name.Map.find modules main_module_name
|
||||
else
|
||||
None)
|
||||
let lib_interface_module =
|
||||
if lib.wrapped then
|
||||
Module.Name.Map.find modules main_module_name
|
||||
else
|
||||
None
|
||||
in
|
||||
let cctx =
|
||||
Compilation_context.create ()
|
||||
~super_context:sctx
|
||||
~scope
|
||||
~dir
|
||||
~obj_dir
|
||||
~modules
|
||||
?alias_module
|
||||
?lib_interface_module
|
||||
~flags
|
||||
~requires
|
||||
~preprocessing:pp
|
||||
in
|
||||
let dep_graphs = Ocamldep.rules cctx ~already_used in
|
||||
|
||||
Option.iter alias_module ~f:(fun m ->
|
||||
let file =
|
||||
|
@ -604,23 +616,14 @@ module Gen(P : Install_rules.Params) = struct
|
|||
|
||||
let dynlink = lib.dynlink in
|
||||
let js_of_ocaml = lib.buildable.js_of_ocaml in
|
||||
Module_compilation.build_modules sctx
|
||||
~js_of_ocaml ~dynlink ~flags ~scope ~dir ~obj_dir ~dep_graphs
|
||||
~modules ~alias_module
|
||||
~includes:(Module_compilation.Includes.make sctx ~requires);
|
||||
Module_compilation.build_modules cctx ~js_of_ocaml ~dynlink ~dep_graphs;
|
||||
Option.iter alias_module ~f:(fun m ->
|
||||
let flags = Ocaml_flags.default ~profile:(SC.profile sctx) in
|
||||
Module_compilation.build_module sctx m
|
||||
let cctx = Compilation_context.for_alias_module cctx in
|
||||
Module_compilation.build_module cctx m
|
||||
~js_of_ocaml
|
||||
~dynlink
|
||||
~sandbox:alias_module_build_sandbox
|
||||
~flags:(Ocaml_flags.append_common flags ["-w"; "-49"])
|
||||
~scope
|
||||
~dir
|
||||
~obj_dir
|
||||
~dep_graphs:(Ocamldep.Dep_graphs.dummy m)
|
||||
~includes:Module_compilation.Includes.empty
|
||||
~alias_module:None);
|
||||
~dep_graphs:(Ocamldep.Dep_graphs.dummy m));
|
||||
|
||||
if Library.has_stubs lib then begin
|
||||
let h_files =
|
||||
|
@ -814,20 +817,22 @@ module Gen(P : Install_rules.Params) = struct
|
|||
~loc:exes.buildable.loc ~modules
|
||||
in
|
||||
|
||||
let preprocessor_deps =
|
||||
SC.Deps.interpret sctx exes.buildable.preprocessor_deps
|
||||
~scope ~dir
|
||||
in
|
||||
let pp =
|
||||
Preprocessing.make sctx ~dir ~dep_kind:Required
|
||||
~scope
|
||||
~preprocess:exes.buildable.preprocess
|
||||
~preprocessor_deps
|
||||
~lint:exes.buildable.lint
|
||||
~lib_name:None
|
||||
in
|
||||
let modules =
|
||||
let preprocessor_deps =
|
||||
SC.Deps.interpret sctx exes.buildable.preprocessor_deps
|
||||
~scope ~dir
|
||||
in
|
||||
let pp =
|
||||
Preprocessing.make sctx ~dir ~dep_kind:Required
|
||||
~scope
|
||||
~preprocess:exes.buildable.preprocess
|
||||
~preprocessor_deps
|
||||
~lint:exes.buildable.lint
|
||||
~lib_name:None
|
||||
in
|
||||
Preprocessing.pp_modules pp modules
|
||||
Module.Name.Map.map modules ~f:(fun m ->
|
||||
Preprocessing.pp_module_as pp m.name m
|
||||
|> Module.set_obj_name ~wrapper:None)
|
||||
in
|
||||
|
||||
let programs =
|
||||
|
@ -877,16 +882,23 @@ module Gen(P : Install_rules.Params) = struct
|
|||
let obj_dir =
|
||||
Utils.executable_object_directory ~dir (List.hd programs).name
|
||||
in
|
||||
Exe.build_and_link_many sctx
|
||||
~dir
|
||||
~obj_dir
|
||||
|
||||
let cctx =
|
||||
Compilation_context.create ()
|
||||
~super_context:sctx
|
||||
~scope
|
||||
~dir
|
||||
~obj_dir
|
||||
~modules
|
||||
~flags
|
||||
~requires
|
||||
~preprocessing:pp
|
||||
in
|
||||
|
||||
Exe.build_and_link_many cctx
|
||||
~programs
|
||||
~modules
|
||||
~already_used
|
||||
~scope
|
||||
~linkages
|
||||
~requires
|
||||
~flags
|
||||
~link_flags
|
||||
~js_of_ocaml:exes.buildable.js_of_ocaml;
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ include Sub_system.Register_end_point(
|
|||
; syntax = OCaml
|
||||
}
|
||||
; intf = None
|
||||
; obj_name = ""
|
||||
; obj_name = name
|
||||
}
|
||||
in
|
||||
|
||||
|
@ -239,16 +239,19 @@ include Sub_system.Register_end_point(
|
|||
>>>
|
||||
Build.action_dyn ~targets:[target] ());
|
||||
|
||||
Exe.build_and_link sctx
|
||||
~dir:inline_test_dir
|
||||
~obj_dir:inline_test_dir
|
||||
let cctx =
|
||||
Compilation_context.create ()
|
||||
~super_context:sctx
|
||||
~scope
|
||||
~dir:inline_test_dir
|
||||
~modules
|
||||
~requires:runner_libs
|
||||
~flags:(Ocaml_flags.of_list ["-w"; "-24"]);
|
||||
in
|
||||
Exe.build_and_link cctx
|
||||
~program:{ name; main_module_name }
|
||||
~modules
|
||||
~scope
|
||||
~linkages:[Exe.Linkage.native_or_custom (SC.context sctx)]
|
||||
~requires:runner_libs
|
||||
~link_flags:(Build.return ["-linkall"])
|
||||
~flags:(Ocaml_flags.of_list ["-w"; "-24"]);
|
||||
~link_flags:(Build.return ["-linkall"]);
|
||||
|
||||
let flags =
|
||||
let flags =
|
||||
|
|
|
@ -2,39 +2,9 @@ open Import
|
|||
open Build.O
|
||||
open! No_io
|
||||
|
||||
module CC = Compilation_context
|
||||
module SC = Super_context
|
||||
|
||||
module Includes = struct
|
||||
type t = string list Arg_spec.t Cm_kind.Dict.t
|
||||
|
||||
let make sctx ~requires : _ Cm_kind.Dict.t =
|
||||
match requires with
|
||||
| Error exn -> Cm_kind.Dict.make_all (Arg_spec.Dyn (fun _ -> raise exn))
|
||||
| Ok libs ->
|
||||
let iflags =
|
||||
Lib.L.include_flags libs ~stdlib_dir:(SC.context sctx).stdlib_dir
|
||||
in
|
||||
let cmi_includes =
|
||||
Arg_spec.S [ iflags
|
||||
; Hidden_deps
|
||||
(SC.Libs.file_deps sctx libs ~ext:".cmi")
|
||||
]
|
||||
in
|
||||
let cmi_and_cmx_includes =
|
||||
Arg_spec.S [ iflags
|
||||
; Hidden_deps
|
||||
(SC.Libs.file_deps sctx libs ~ext:".cmi-and-.cmx")
|
||||
]
|
||||
in
|
||||
{ cmi = cmi_includes
|
||||
; cmo = cmi_includes
|
||||
; cmx = cmi_and_cmx_includes
|
||||
}
|
||||
|
||||
let empty =
|
||||
Cm_kind.Dict.make_all (Arg_spec.As [])
|
||||
end
|
||||
|
||||
module Target : sig
|
||||
type t
|
||||
val cm : Module.t -> Cm_kind.t -> t
|
||||
|
@ -49,9 +19,11 @@ end = struct
|
|||
let file dir t = Path.append dir t
|
||||
end
|
||||
|
||||
let build_cm sctx ?sandbox ~dynlink ~flags ~cm_kind ~dep_graphs
|
||||
~includes ~dir ~obj_dir ~alias_module (m : Module.t) =
|
||||
let ctx = SC.context sctx in
|
||||
let build_cm cctx ?sandbox ?(dynlink=true) ~dep_graphs ~cm_kind (m : Module.t) =
|
||||
let sctx = CC.super_context cctx in
|
||||
let dir = CC.dir cctx in
|
||||
let obj_dir = CC.obj_dir cctx in
|
||||
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
|
||||
|
@ -120,16 +92,16 @@ let build_cm sctx ?sandbox ~dynlink ~flags ~cm_kind ~dep_graphs
|
|||
SC.add_rule sctx ?sandbox
|
||||
(Build.paths extra_deps >>>
|
||||
other_cm_files >>>
|
||||
Ocaml_flags.get_for_cm flags ~cm_kind >>>
|
||||
Ocaml_flags.get_for_cm (CC.flags cctx) ~cm_kind >>>
|
||||
Build.run ~context:ctx (Ok compiler)
|
||||
[ Dyn (fun ocaml_flags -> As ocaml_flags)
|
||||
; cmt_args
|
||||
; A "-I"; Path obj_dir
|
||||
; includes
|
||||
; Cm_kind.Dict.get (CC.includes cctx) cm_kind
|
||||
; As extra_args
|
||||
; if dynlink || cm_kind <> Cmx then As [] else A "-nodynlink"
|
||||
; A "-no-alias-deps"; opaque
|
||||
; (match alias_module with
|
||||
; (match CC.alias_module cctx with
|
||||
| None -> S []
|
||||
| Some (m : Module.t) ->
|
||||
As ["-open"; Module.Name.to_string m.name])
|
||||
|
@ -138,14 +110,15 @@ let build_cm sctx ?sandbox ~dynlink ~flags ~cm_kind ~dep_graphs
|
|||
; Hidden_targets hidden_targets
|
||||
])))
|
||||
|
||||
let build_module sctx ?sandbox ~dynlink ?js_of_ocaml ~flags m ~scope ~dir
|
||||
~obj_dir ~dep_graphs ~includes ~alias_module =
|
||||
let build_module ?sandbox ?js_of_ocaml ?dynlink ~dep_graphs cctx m =
|
||||
List.iter Cm_kind.all ~f:(fun cm_kind ->
|
||||
let includes = Cm_kind.Dict.get includes cm_kind in
|
||||
build_cm sctx ?sandbox ~dynlink ~flags ~dir ~obj_dir ~dep_graphs m ~cm_kind
|
||||
~includes ~alias_module);
|
||||
build_cm cctx m ?sandbox ?dynlink ~dep_graphs ~cm_kind);
|
||||
Option.iter js_of_ocaml ~f:(fun js_of_ocaml ->
|
||||
(* Build *.cmo.js *)
|
||||
let sctx = CC.super_context cctx in
|
||||
let scope = CC.scope cctx in
|
||||
let dir = CC.dir cctx in
|
||||
let obj_dir = CC.obj_dir cctx in
|
||||
let src = Module.cm_file_unsafe m ~obj_dir Cm_kind.Cmo in
|
||||
let target =
|
||||
Path.extend_basename (Module.cm_file_unsafe m ~obj_dir:dir Cm_kind.Cmo)
|
||||
|
@ -154,12 +127,9 @@ let build_module sctx ?sandbox ~dynlink ?js_of_ocaml ~flags m ~scope ~dir
|
|||
SC.add_rules sctx
|
||||
(Js_of_ocaml_rules.build_cm sctx ~scope ~dir ~js_of_ocaml ~src ~target))
|
||||
|
||||
let build_modules sctx ~dynlink ~js_of_ocaml ~flags ~scope ~dir ~obj_dir
|
||||
~dep_graphs ~modules ~includes ~alias_module =
|
||||
let build_modules ?sandbox ?js_of_ocaml ?dynlink ~dep_graphs cctx =
|
||||
Module.Name.Map.iter
|
||||
(match alias_module with
|
||||
| None -> modules
|
||||
| Some (m : Module.t) -> Module.Name.Map.remove modules m.name)
|
||||
~f:(fun m ->
|
||||
build_module sctx m ~dynlink ~js_of_ocaml ~flags ~scope ~dir ~obj_dir
|
||||
~dep_graphs ~includes ~alias_module)
|
||||
(match CC.alias_module cctx with
|
||||
| None -> CC.modules cctx
|
||||
| Some (m : Module.t) -> Module.Name.Map.remove (CC.modules cctx) m.name)
|
||||
~f:(build_module cctx ?sandbox ?js_of_ocaml ?dynlink ~dep_graphs)
|
||||
|
|
|
@ -2,42 +2,21 @@
|
|||
|
||||
open Import
|
||||
|
||||
module Includes : sig
|
||||
type t
|
||||
|
||||
val make : Super_context.t -> requires:Lib.t list Or_exn.t -> t
|
||||
|
||||
(** Empty set of include directories *)
|
||||
val empty : t
|
||||
end
|
||||
|
||||
(** Setup rules to build a single module. *)
|
||||
val build_module
|
||||
: Super_context.t
|
||||
-> ?sandbox:bool
|
||||
-> dynlink:bool
|
||||
: ?sandbox:bool
|
||||
-> ?js_of_ocaml:Jbuild.Js_of_ocaml.t
|
||||
-> flags:Ocaml_flags.t
|
||||
-> Module.t
|
||||
-> scope:Scope.t
|
||||
-> dir:Path.t
|
||||
-> obj_dir:Path.t
|
||||
-> ?dynlink:bool
|
||||
-> dep_graphs:Ocamldep.Dep_graphs.t
|
||||
-> includes:Includes.t
|
||||
-> alias_module:Module.t option
|
||||
-> Compilation_context.t
|
||||
-> Module.t
|
||||
-> unit
|
||||
|
||||
(** Setup rules to build all of [modules] *)
|
||||
(** Setup rules to build all of the modules in the compilation context. *)
|
||||
val build_modules
|
||||
: Super_context.t
|
||||
-> dynlink:bool
|
||||
-> js_of_ocaml:Jbuild.Js_of_ocaml.t
|
||||
-> flags:Ocaml_flags.t
|
||||
-> scope:Scope.t
|
||||
-> dir:Path.t
|
||||
-> obj_dir:Path.t
|
||||
: ?sandbox:bool
|
||||
-> ?js_of_ocaml:Jbuild.Js_of_ocaml.t
|
||||
-> ?dynlink:bool
|
||||
-> dep_graphs:Ocamldep.Dep_graphs.t
|
||||
-> modules:Module.t Module.Name.Map.t
|
||||
-> includes:Includes.t
|
||||
-> alias_module:Module.t option
|
||||
-> Compilation_context.t
|
||||
-> unit
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
open Import
|
||||
open Build.O
|
||||
|
||||
module CC = Compilation_context
|
||||
module SC = Super_context
|
||||
|
||||
module Dep_graph = struct
|
||||
|
@ -66,13 +67,16 @@ let parse_module_names ~(unit : Module.t) ~modules words =
|
|||
else
|
||||
Module.Name.Map.find modules m)
|
||||
|
||||
let is_alias_module ~(alias_module : Module.t option) (m : Module.t) =
|
||||
match alias_module with
|
||||
let is_alias_module cctx (m : Module.t) =
|
||||
match CC.alias_module cctx with
|
||||
| None -> false
|
||||
| Some alias -> alias.name = m.name
|
||||
|
||||
let parse_deps ~dir ~file ~unit
|
||||
~modules ~alias_module ~lib_interface_module lines =
|
||||
let parse_deps cctx ~file ~unit lines =
|
||||
let dir = CC.dir cctx in
|
||||
let alias_module = CC.alias_module cctx in
|
||||
let lib_interface_module = CC.lib_interface_module cctx in
|
||||
let modules = CC.modules cctx in
|
||||
let invalid () =
|
||||
die "ocamldep returned unexpected output for %s:\n\
|
||||
%s"
|
||||
|
@ -99,7 +103,7 @@ let parse_deps ~dir ~file ~unit
|
|||
(match lib_interface_module with
|
||||
| None -> ()
|
||||
| Some (m : Module.t) ->
|
||||
if unit.name <> m.name && not (is_alias_module unit ~alias_module) &&
|
||||
if unit.name <> m.name && not (is_alias_module cctx unit) &&
|
||||
List.exists deps ~f:(fun x -> Module.name x = m.name) then
|
||||
die "Module %a in directory %s depends on %a.\n\
|
||||
This doesn't make sense to me.\n\
|
||||
|
@ -116,9 +120,10 @@ let parse_deps ~dir ~file ~unit
|
|||
| None -> deps
|
||||
| Some m -> m :: deps
|
||||
|
||||
let deps_of ~ml_kind ~dir ~modules ~already_used
|
||||
~alias_module ~lib_interface_module sctx unit =
|
||||
if is_alias_module unit ~alias_module then
|
||||
let deps_of cctx ~ml_kind ~already_used unit =
|
||||
let sctx = CC.super_context cctx in
|
||||
let dir = CC.dir cctx in
|
||||
if is_alias_module cctx unit then
|
||||
Build.return []
|
||||
else
|
||||
match Module.file ~dir unit ml_kind with
|
||||
|
@ -140,7 +145,7 @@ let deps_of ~ml_kind ~dir ~modules ~already_used
|
|||
let build_paths dependencies =
|
||||
let dependency_file_path m =
|
||||
let path =
|
||||
if is_alias_module m ~alias_module then
|
||||
if is_alias_module cctx m then
|
||||
None
|
||||
else
|
||||
match Module.file ~dir m Ml_kind.Intf with
|
||||
|
@ -153,9 +158,7 @@ let deps_of ~ml_kind ~dir ~modules ~already_used
|
|||
in
|
||||
SC.add_rule sctx
|
||||
( Build.lines_of ocamldep_output
|
||||
>>^ parse_deps
|
||||
~dir ~file ~unit ~modules ~alias_module
|
||||
~lib_interface_module
|
||||
>>^ parse_deps cctx ~file ~unit
|
||||
>>^ (fun modules ->
|
||||
(build_paths modules,
|
||||
List.map modules ~f:(fun m ->
|
||||
|
@ -165,29 +168,22 @@ let deps_of ~ml_kind ~dir ~modules ~already_used
|
|||
end;
|
||||
Build.memoize (Path.to_string all_deps_file)
|
||||
( Build.lines_of all_deps_file
|
||||
>>^ parse_module_names ~unit ~modules)
|
||||
>>^ parse_module_names ~unit ~modules:(CC.modules cctx))
|
||||
|
||||
let rules_generic ~(ml_kind:Ml_kind.t) ~dir ~modules ~for_modules
|
||||
?(already_used=Module.Name.Set.empty)
|
||||
~alias_module ~lib_interface_module sctx =
|
||||
let per_module =
|
||||
Module.Name.Map.map for_modules
|
||||
~f:(deps_of ~ml_kind ~dir ~modules ~already_used
|
||||
~alias_module ~lib_interface_module sctx)
|
||||
in
|
||||
{ Dep_graph.
|
||||
dir
|
||||
; per_module
|
||||
}
|
||||
|
||||
let rules ~dir ~modules ?already_used ~alias_module ~lib_interface_module sctx =
|
||||
let rules_generic ?(already_used=Module.Name.Set.empty) cctx ~modules =
|
||||
Ml_kind.Dict.of_func
|
||||
(rules_generic sctx ~dir ~modules ~for_modules:modules
|
||||
?already_used ~alias_module ~lib_interface_module)
|
||||
(fun ~ml_kind ->
|
||||
let per_module =
|
||||
Module.Name.Map.map modules
|
||||
~f:(deps_of cctx ~already_used ~ml_kind)
|
||||
in
|
||||
{ Dep_graph.
|
||||
dir = CC.dir cctx
|
||||
; per_module
|
||||
})
|
||||
|
||||
let rules_for_auxiliary_module ~dir ~modules ~alias_module
|
||||
~lib_interface_module sctx (m : Module.t) =
|
||||
let for_modules = Module.Name.Map.singleton m.name m in
|
||||
Ml_kind.Dict.of_func
|
||||
(rules_generic sctx ~dir ~modules ~for_modules
|
||||
?already_used:None ~alias_module ~lib_interface_module)
|
||||
let rules ?already_used cctx =
|
||||
rules_generic ?already_used cctx ~modules:(CC.modules cctx)
|
||||
|
||||
let rules_for_auxiliary_module cctx (m : Module.t) =
|
||||
rules_generic cctx ~modules:(Module.Name.Map.singleton m.name m)
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
(** ocamldep management *)
|
||||
|
||||
open Stdune
|
||||
|
||||
module Dep_graph : sig
|
||||
type t
|
||||
|
||||
|
@ -22,33 +20,18 @@ module Dep_graphs : sig
|
|||
val dummy : Module.t -> t
|
||||
end
|
||||
|
||||
(** Generate ocamldep rules for the given modules. [item] is either
|
||||
the internal name of a library of the first name of a list of
|
||||
executables.
|
||||
|
||||
For wrapped libraries, [lib_interface_module] is the main module
|
||||
of the library.
|
||||
(** Generate ocamldep rules for all the modules in the context.
|
||||
|
||||
[already_used] represents the modules that are used by another
|
||||
stanzas in the same directory. No [.d] rule will be generated for
|
||||
such modules.
|
||||
|
||||
Return arrows that evaluate to the dependency graphs. *)
|
||||
such modules. *)
|
||||
val rules
|
||||
: dir:Path.t
|
||||
-> modules:Module.t Module.Name.Map.t
|
||||
-> ?already_used:Module.Name.Set.t
|
||||
-> alias_module:Module.t option
|
||||
-> lib_interface_module:Module.t option
|
||||
-> Super_context.t
|
||||
: ?already_used:Module.Name.Set.t
|
||||
-> Compilation_context.t
|
||||
-> Dep_graphs.t
|
||||
|
||||
(** Compute the dependencies of an auxiliary module. *)
|
||||
val rules_for_auxiliary_module
|
||||
: dir:Path.t
|
||||
-> modules:Module.t Module.Name.Map.t
|
||||
-> alias_module:Module.t option
|
||||
-> lib_interface_module:Module.t option
|
||||
-> Super_context.t
|
||||
: Compilation_context.t
|
||||
-> Module.t
|
||||
-> Dep_graphs.t
|
||||
|
|
|
@ -295,6 +295,8 @@ let lint_module sctx ~dir ~dep_kind ~lint ~lib_name ~scope = Staged.stage (
|
|||
|
||||
type t = (Module.t -> lint:bool -> Module.t) Per_module.t
|
||||
|
||||
let dummy = Per_module.for_all (fun m ~lint:_ -> m)
|
||||
|
||||
let make sctx ~dir ~dep_kind ~lint ~preprocess
|
||||
~preprocessor_deps ~lib_name ~scope =
|
||||
let preprocessor_deps =
|
||||
|
|
|
@ -5,6 +5,8 @@ open! Import
|
|||
(** Preprocessing object *)
|
||||
type t
|
||||
|
||||
val dummy : t
|
||||
|
||||
val make
|
||||
: Super_context.t
|
||||
-> dir:Path.t
|
||||
|
|
23
src/utop.ml
23
src/utop.ml
|
@ -62,7 +62,7 @@ let setup sctx ~dir ~(libs : Library.t list) ~scope =
|
|||
; syntax = Module.Syntax.OCaml
|
||||
}
|
||||
; intf = None
|
||||
; obj_name = "" } in
|
||||
; obj_name = exe_name } in
|
||||
let utop_exe_dir = utop_exe_dir ~dir in
|
||||
let requires =
|
||||
let open Result.O in
|
||||
|
@ -70,16 +70,19 @@ let setup sctx ~dir ~(libs : Library.t list) ~scope =
|
|||
("utop" :: List.map libs ~f:(fun (lib : Library.t) -> lib.name))
|
||||
>>= Lib.closure
|
||||
in
|
||||
Exe.build_and_link sctx
|
||||
~dir:utop_exe_dir
|
||||
~obj_dir:utop_exe_dir
|
||||
let cctx =
|
||||
Compilation_context.create ()
|
||||
~super_context:sctx
|
||||
~scope
|
||||
~dir:utop_exe_dir
|
||||
~modules
|
||||
~requires
|
||||
~flags:(Ocaml_flags.append_common
|
||||
(Ocaml_flags.default ~profile:(Super_context.profile sctx))
|
||||
["-w"; "-24"])
|
||||
in
|
||||
Exe.build_and_link cctx
|
||||
~program:{ name = exe_name ; main_module_name }
|
||||
~modules
|
||||
~scope
|
||||
~linkages:[Exe.Linkage.custom]
|
||||
~requires
|
||||
~flags:(Ocaml_flags.append_common
|
||||
(Ocaml_flags.default ~profile:(Super_context.profile sctx))
|
||||
["-w"; "-24"])
|
||||
~link_flags:(Build.return ["-linkall"; "-warn-error"; "-31"]);
|
||||
add_module_rules sctx ~dir:utop_exe_dir requires
|
||||
|
|
Loading…
Reference in New Issue