Skip to content

Commit c4c1df4

Browse files
committed
.cms/.cmt dependency
Signed-off-by: Simon Spies <sspies@janestreet.com>
1 parent d86815f commit c4c1df4

File tree

8 files changed

+258
-12
lines changed

8 files changed

+258
-12
lines changed

src/dune_rules/compilation_context.ml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ type t =
100100
; modes : Lib_mode.Map.Set.t
101101
; bin_annot : bool
102102
; bin_annot_cms : bool
103+
; cms_cmt_dependency : Workspace.Context.Cms_cmt_dependency.t
103104
; loc : Loc.t option
104105
; ocaml : Ocaml_toolchain.t
105106
; for_ : Compilation_mode.t
@@ -128,6 +129,7 @@ let implements t = t.implements
128129
let modes t = t.modes
129130
let bin_annot t = t.bin_annot
130131
let bin_annot_cms t = t.bin_annot_cms
132+
let cms_cmt_dependency t = t.cms_cmt_dependency
131133
let context t = Super_context.context t.super_context
132134
let dep_graphs t = t.modules.dep_graphs
133135
let ocaml t = t.ocaml
@@ -163,6 +165,7 @@ let create
163165
?modes
164166
?bin_annot
165167
?bin_annot_cms
168+
?cms_cmt_dependency
166169
?loc
167170
?instances
168171
for_
@@ -216,6 +219,12 @@ let create
216219
match bin_annot_cms with
217220
| Some b -> Memo.return b
218221
| None -> Env_stanza_db.bin_annot_cms ~dir:(Obj_dir.dir obj_dir)
222+
and+ cms_cmt_dependency =
223+
match cms_cmt_dependency with
224+
| Some v -> Memo.return v
225+
| None ->
226+
let context = Super_context.context super_context in
227+
Memo.return (Context.cms_cmt_dependency context)
219228
in
220229
{ super_context
221230
; scope
@@ -238,6 +247,7 @@ let create
238247
; modes
239248
; bin_annot
240249
; bin_annot_cms
250+
; cms_cmt_dependency
241251
; loc
242252
; ocaml
243253
; instances
@@ -349,7 +359,13 @@ let for_plugin_executable t ~embed_in_plugin_libraries =
349359
{ t with requires_link }
350360
;;
351361

352-
let without_bin_annot t = { t with bin_annot = false; bin_annot_cms = false }
362+
let without_bin_annot t =
363+
{ t with
364+
bin_annot = false
365+
; bin_annot_cms = false
366+
; cms_cmt_dependency = Workspace.Context.Cms_cmt_dependency.No_dependency
367+
}
368+
;;
353369
let set_obj_dir t obj_dir = { t with obj_dir }
354370
let set_modes t ~modes = { t with modes }
355371
let instances t = t.instances

src/dune_rules/compilation_context.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ val create
3737
-> ?modes:Lib_mode.Map.Set.t
3838
-> ?bin_annot:bool
3939
-> ?bin_annot_cms:bool
40+
-> ?cms_cmt_dependency:Workspace.Context.Cms_cmt_dependency.t
4041
-> ?loc:Loc.t
4142
-> ?instances:Parameterised_rules.instances list Resolve.Memo.t
4243
-> Compilation_mode.t
@@ -84,6 +85,7 @@ val for_module_generated_at_link_time
8485
val for_plugin_executable : t -> embed_in_plugin_libraries:(Loc.t * Lib_name.t) list -> t
8586
val bin_annot : t -> bool
8687
val bin_annot_cms : t -> bool
88+
val cms_cmt_dependency : t -> Workspace.Context.Cms_cmt_dependency.t
8789
val without_bin_annot : t -> t
8890

8991
(** The dependency graph for the modules of the library. *)

src/dune_rules/context.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ type builder =
7979
; target_exec : (string * string list) option
8080
; for_host : (Context_name.t * t Memo.t) option
8181
; path : Path.t list
82+
; cms_cmt_dependency : Workspace.Context.Cms_cmt_dependency.t
8283
}
8384

8485
and t =
@@ -118,6 +119,7 @@ module Builder = struct
118119
; target_exec = None
119120
; for_host = None
120121
; path = []
122+
; cms_cmt_dependency = Workspace.Context.Cms_cmt_dependency.No_dependency
121123
}
122124
;;
123125

@@ -154,6 +156,7 @@ module Builder = struct
154156
; dynamically_linked_foreign_archives
155157
; instrument_with
156158
; merlin
159+
; cms_cmt_dependency
157160
}
158161
=
159162
let env =
@@ -173,6 +176,7 @@ module Builder = struct
173176
; env = Memo.return env
174177
; findlib_toolchain = toolchain
175178
; target_exec = None
179+
; cms_cmt_dependency
176180
}
177181
;;
178182
end
@@ -199,6 +203,7 @@ let fdo_target_exe t = t.builder.fdo_target_exe
199203
let instrument_with t = t.builder.instrument_with
200204
let merlin t = t.builder.merlin
201205
let profile t = t.builder.profile
206+
let cms_cmt_dependency t = t.builder.cms_cmt_dependency
202207
let equal x y = Context_name.equal x.builder.name y.builder.name
203208
let hash t = Context_name.hash t.builder.name
204209
let build_context t = t.build_context

src/dune_rules/context.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ val findlib_toolchain : t -> Context_name.t option
5151
val instrument_with : t -> Lib_name.t list
5252
val profile : t -> Profile.t
5353
val merlin : t -> bool
54+
val cms_cmt_dependency : t -> Workspace.Context.Cms_cmt_dependency.t
5455
val equal : t -> t -> bool
5556
val hash : t -> int
5657
val to_dyn : t -> Dyn.t

src/dune_rules/module_compilation.ml

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,47 @@ let opens modules m =
3030
Command.Args.As (Modules.With_vlib.local_open modules m |> Ocaml_flags.open_flags)
3131
;;
3232

33-
let other_cm_files ~opaque ~cm_kind ~obj_dir =
33+
let other_cm_files ~opaque ~cm_kind ~obj_dir ~cms_cmt_dependency ~bin_annot ~bin_annot_cms
34+
~is_ox =
3435
List.concat_map ~f:(fun m ->
3536
let cmi_kind = Lib_mode.Cm_kind.cmi cm_kind in
3637
let deps = [ Path.build (Obj_dir.Module.cm_file_exn obj_dir m ~kind:cmi_kind) ] in
37-
if Module.has m ~ml_kind:Impl && cm_kind = Ocaml Cmx && not opaque
38-
then (
39-
let cmx = Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Ocaml Cmx) in
40-
Path.build cmx :: deps)
41-
else if Module.has m ~ml_kind:Impl && cm_kind = Melange Cmj
42-
then (
43-
let cmj = Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Melange Cmj) in
44-
Path.build cmj :: deps)
45-
else deps)
38+
let deps =
39+
if Module.has m ~ml_kind:Impl && cm_kind = Ocaml Cmx && not opaque
40+
then (
41+
let cmx = Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Ocaml Cmx) in
42+
Path.build cmx :: deps)
43+
else if Module.has m ~ml_kind:Impl && cm_kind = Melange Cmj
44+
then (
45+
let cmj = Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Melange Cmj) in
46+
Path.build cmj :: deps)
47+
else deps
48+
in
49+
(* Add .cms/.cmt dependencies when enabled. Like .cmx dependencies, these are
50+
skipped when -opaque is used. *)
51+
let cms_cmt_deps =
52+
let open Workspace.Context.Cms_cmt_dependency in
53+
match cms_cmt_dependency with
54+
| No_dependency -> []
55+
| Depends_on_cms when bin_annot_cms && is_ox && not opaque ->
56+
(* We pass as [cm_kind] [Ocaml Cmx/Cmi] but the specific [cm_kind]
57+
doesn't matter here: .cms/.cmt files are stored in byte_dir
58+
regardless (see [Obj_dir.Module.cms_file]). *)
59+
List.filter_opt
60+
[ Obj_dir.Module.cms_file obj_dir m ~ml_kind:Impl ~cm_kind:(Ocaml Cmx)
61+
; Obj_dir.Module.cms_file obj_dir m ~ml_kind:Intf ~cm_kind:(Ocaml Cmi)
62+
]
63+
|> List.map ~f:Path.build
64+
| Depends_on_cms -> []
65+
| Depends_on_cmt when bin_annot && is_ox && not opaque ->
66+
List.filter_opt
67+
[ Obj_dir.Module.cmt_file obj_dir m ~ml_kind:Impl ~cm_kind:(Ocaml Cmx)
68+
; Obj_dir.Module.cmt_file obj_dir m ~ml_kind:Intf ~cm_kind:(Ocaml Cmi)
69+
]
70+
|> List.map ~f:Path.build
71+
| Depends_on_cmt -> []
72+
in
73+
cms_cmt_deps @ deps)
4674
;;
4775

4876
let copy_interface ~sctx ~dir ~obj_dir ~cm_kind m =
@@ -230,8 +258,21 @@ let build_cm
230258
let other_cm_files =
231259
let dep_graph = Ml_kind.Dict.get (Compilation_context.dep_graphs cctx) ml_kind in
232260
let module_deps = Dep_graph.deps_of dep_graph m in
261+
let cms_cmt_dependency = Compilation_context.cms_cmt_dependency cctx in
262+
let bin_annot = Compilation_context.bin_annot cctx in
263+
let bin_annot_cms = Compilation_context.bin_annot_cms cctx in
264+
let is_ox = Ocaml_config.ox ocaml.ocaml_config in
233265
Action_builder.dyn_paths_unit
234-
(Action_builder.map module_deps ~f:(other_cm_files ~opaque ~cm_kind ~obj_dir))
266+
(Action_builder.map module_deps
267+
~f:
268+
(other_cm_files
269+
~opaque
270+
~cm_kind
271+
~obj_dir
272+
~cms_cmt_dependency
273+
~bin_annot
274+
~bin_annot_cms
275+
~is_ox))
235276
in
236277
let cmt_args =
237278
match cm_kind with

src/source/workspace.ml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,29 @@ module Context = struct
382382
;;
383383
end
384384

385+
module Cms_cmt_dependency = struct
386+
type t =
387+
| No_dependency
388+
| Depends_on_cms
389+
| Depends_on_cmt
390+
391+
let equal x y =
392+
match x, y with
393+
| No_dependency, No_dependency
394+
| Depends_on_cms, Depends_on_cms
395+
| Depends_on_cmt, Depends_on_cmt -> true
396+
| (No_dependency | Depends_on_cms | Depends_on_cmt), _ -> false
397+
;;
398+
399+
let to_dyn : t -> Dyn.t = function
400+
| No_dependency -> String "none"
401+
| Depends_on_cms -> String "cms"
402+
| Depends_on_cmt -> String "cmt"
403+
;;
404+
405+
let decode = enum [ "none", No_dependency; "cms", Depends_on_cms; "cmt", Depends_on_cmt ]
406+
end
407+
385408
module Common = struct
386409
type t =
387410
{ loc : Loc.t
@@ -396,6 +419,7 @@ module Context = struct
396419
; dynamically_linked_foreign_archives : bool
397420
; instrument_with : Lib_name.t list
398421
; merlin : Merlin.t
422+
; cms_cmt_dependency : Cms_cmt_dependency.t
399423
}
400424

401425
let to_dyn { name; targets; host_context; _ } =
@@ -419,6 +443,7 @@ module Context = struct
419443
; dynamically_linked_foreign_archives
420444
; instrument_with
421445
; merlin
446+
; cms_cmt_dependency
422447
}
423448
t
424449
=
@@ -435,6 +460,7 @@ module Context = struct
435460
t.dynamically_linked_foreign_archives
436461
&& List.equal Lib_name.equal instrument_with t.instrument_with
437462
&& Merlin.equal merlin t.merlin
463+
&& Cms_cmt_dependency.equal cms_cmt_dependency t.cms_cmt_dependency
438464
;;
439465

440466
let fdo_suffix t =
@@ -505,6 +531,12 @@ module Context = struct
505531
field_b
506532
~check:(Dune_lang.Syntax.since Stanza.syntax (3, 16))
507533
"generate_merlin_rules"
534+
and+ cms_cmt_dependency =
535+
field
536+
"cms-cmt-dependency"
537+
~default:Cms_cmt_dependency.No_dependency
538+
(Dune_lang.Syntax.since Dune_lang.Oxcaml.syntax (0, 1)
539+
>>> Cms_cmt_dependency.decode)
508540
in
509541
fun ~profile_default ~instrument_with_default ->
510542
let profile = Option.value profile ~default:profile_default in
@@ -537,6 +569,7 @@ module Context = struct
537569
(match generate_merlin_rules with
538570
| true -> Rules_only
539571
| false -> Not_selected))
572+
; cms_cmt_dependency
540573
}
541574
;;
542575
end
@@ -708,6 +741,7 @@ module Context = struct
708741
; dynamically_linked_foreign_archives = true
709742
; instrument_with = Option.value instrument_with ~default:[]
710743
; merlin = Not_selected
744+
; cms_cmt_dependency = Cms_cmt_dependency.No_dependency
711745
}
712746
}
713747
;;

src/source/workspace.mli

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,16 @@ module Context : sig
6060
val to_dyn : t -> Dyn.t
6161
end
6262

63+
module Cms_cmt_dependency : sig
64+
type t =
65+
| No_dependency
66+
| Depends_on_cms
67+
| Depends_on_cmt
68+
69+
val equal : t -> t -> bool
70+
val to_dyn : t -> Dyn.t
71+
end
72+
6373
module Common : sig
6474
type t =
6575
{ loc : Loc.t
@@ -80,6 +90,7 @@ module Context : sig
8090
; dynamically_linked_foreign_archives : bool
8191
; instrument_with : Lib_name.t list
8292
; merlin : Merlin.t
93+
; cms_cmt_dependency : Cms_cmt_dependency.t
8394
}
8495
end
8596

0 commit comments

Comments
 (0)