Skip to content

Commit f17cf0e

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

File tree

8 files changed

+269
-12
lines changed

8 files changed

+269
-12
lines changed

src/dune_rules/compilation_context.ml

Lines changed: 18 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,14 @@ 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+
;;
369+
353370
let set_obj_dir t obj_dir = { t with obj_dir }
354371
let set_modes t ~modes = { t with modes }
355372
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: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,54 @@ 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
34+
~opaque
35+
~cm_kind
36+
~obj_dir
37+
~cms_cmt_dependency
38+
~bin_annot
39+
~bin_annot_cms
40+
~is_ox
41+
=
3442
List.concat_map ~f:(fun m ->
3543
let cmi_kind = Lib_mode.Cm_kind.cmi cm_kind in
3644
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)
45+
let deps =
46+
if Module.has m ~ml_kind:Impl && cm_kind = Ocaml Cmx && not opaque
47+
then (
48+
let cmx = Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Ocaml Cmx) in
49+
Path.build cmx :: deps)
50+
else if Module.has m ~ml_kind:Impl && cm_kind = Melange Cmj
51+
then (
52+
let cmj = Obj_dir.Module.cm_file_exn obj_dir m ~kind:(Melange Cmj) in
53+
Path.build cmj :: deps)
54+
else deps
55+
in
56+
(* Add .cms/.cmt dependencies when enabled. Like .cmx dependencies, these are
57+
skipped when -opaque is used. *)
58+
let cms_cmt_deps =
59+
let open Workspace.Context.Cms_cmt_dependency in
60+
match cms_cmt_dependency with
61+
| No_dependency -> []
62+
| Depends_on_cms when bin_annot_cms && is_ox && not opaque ->
63+
(* We pass as [cm_kind] [Ocaml Cmx/Cmi] but the specific [cm_kind]
64+
doesn't matter here: .cms/.cmt files are stored in byte_dir
65+
regardless (see [Obj_dir.Module.cms_file]). *)
66+
List.filter_opt
67+
[ Obj_dir.Module.cms_file obj_dir m ~ml_kind:Impl ~cm_kind:(Ocaml Cmx)
68+
; Obj_dir.Module.cms_file obj_dir m ~ml_kind:Intf ~cm_kind:(Ocaml Cmi)
69+
]
70+
|> List.map ~f:Path.build
71+
| Depends_on_cms -> []
72+
| Depends_on_cmt when bin_annot && is_ox && not opaque ->
73+
List.filter_opt
74+
[ Obj_dir.Module.cmt_file obj_dir m ~ml_kind:Impl ~cm_kind:(Ocaml Cmx)
75+
; Obj_dir.Module.cmt_file obj_dir m ~ml_kind:Intf ~cm_kind:(Ocaml Cmi)
76+
]
77+
|> List.map ~f:Path.build
78+
| Depends_on_cmt -> []
79+
in
80+
cms_cmt_deps @ deps)
4681
;;
4782

4883
let copy_interface ~sctx ~dir ~obj_dir ~cm_kind m =
@@ -230,8 +265,22 @@ let build_cm
230265
let other_cm_files =
231266
let dep_graph = Ml_kind.Dict.get (Compilation_context.dep_graphs cctx) ml_kind in
232267
let module_deps = Dep_graph.deps_of dep_graph m in
268+
let cms_cmt_dependency = Compilation_context.cms_cmt_dependency cctx in
269+
let bin_annot = Compilation_context.bin_annot cctx in
270+
let bin_annot_cms = Compilation_context.bin_annot_cms cctx in
271+
let is_ox = Ocaml_config.ox ocaml.ocaml_config in
233272
Action_builder.dyn_paths_unit
234-
(Action_builder.map module_deps ~f:(other_cm_files ~opaque ~cm_kind ~obj_dir))
273+
(Action_builder.map
274+
module_deps
275+
~f:
276+
(other_cm_files
277+
~opaque
278+
~cm_kind
279+
~obj_dir
280+
~cms_cmt_dependency
281+
~bin_annot
282+
~bin_annot_cms
283+
~is_ox))
235284
in
236285
let cmt_args =
237286
match cm_kind with

src/source/workspace.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,31 @@ 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 =
406+
enum [ "none", No_dependency; "cms", Depends_on_cms; "cmt", Depends_on_cmt ]
407+
;;
408+
end
409+
385410
module Common = struct
386411
type t =
387412
{ loc : Loc.t
@@ -396,6 +421,7 @@ module Context = struct
396421
; dynamically_linked_foreign_archives : bool
397422
; instrument_with : Lib_name.t list
398423
; merlin : Merlin.t
424+
; cms_cmt_dependency : Cms_cmt_dependency.t
399425
}
400426

401427
let to_dyn { name; targets; host_context; _ } =
@@ -419,6 +445,7 @@ module Context = struct
419445
; dynamically_linked_foreign_archives
420446
; instrument_with
421447
; merlin
448+
; cms_cmt_dependency
422449
}
423450
t
424451
=
@@ -435,6 +462,7 @@ module Context = struct
435462
t.dynamically_linked_foreign_archives
436463
&& List.equal Lib_name.equal instrument_with t.instrument_with
437464
&& Merlin.equal merlin t.merlin
465+
&& Cms_cmt_dependency.equal cms_cmt_dependency t.cms_cmt_dependency
438466
;;
439467

440468
let fdo_suffix t =
@@ -505,6 +533,12 @@ module Context = struct
505533
field_b
506534
~check:(Dune_lang.Syntax.since Stanza.syntax (3, 16))
507535
"generate_merlin_rules"
536+
and+ cms_cmt_dependency =
537+
field
538+
"cms-cmt-dependency"
539+
~default:Cms_cmt_dependency.No_dependency
540+
(Dune_lang.Syntax.since Dune_lang.Oxcaml.syntax (0, 1)
541+
>>> Cms_cmt_dependency.decode)
508542
in
509543
fun ~profile_default ~instrument_with_default ->
510544
let profile = Option.value profile ~default:profile_default in
@@ -537,6 +571,7 @@ module Context = struct
537571
(match generate_merlin_rules with
538572
| true -> Rules_only
539573
| false -> Not_selected))
574+
; cms_cmt_dependency
540575
}
541576
;;
542577
end
@@ -708,6 +743,7 @@ module Context = struct
708743
; dynamically_linked_foreign_archives = true
709744
; instrument_with = Option.value instrument_with ~default:[]
710745
; merlin = Not_selected
746+
; cms_cmt_dependency = Cms_cmt_dependency.No_dependency
711747
}
712748
}
713749
;;

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)