• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ocaml / dune / 28994

07 Nov 2024 06:11PM UTC coverage: 6.924% (-0.003%) from 6.927%
28994

push

github

web-flow
refactor: remove [Lib_config] from [Lib] (#11105)

Signed-off-by: Rudi Grinberg <me@rgrinberg.com>

1 of 41 new or added lines in 10 files covered. (2.44%)

6 existing lines in 4 files now uncovered.

2951 of 42620 relevant lines covered (6.92%)

26728.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.83
/src/dune_rules/compilation_context.ml
1
open Import
2
open Memo.O
3

4
module Includes = struct
5
  type t = Command.Args.without_targets Command.Args.t Lib_mode.Cm_kind.Map.t
6

7
  let make ~project ~opaque ~direct_requires ~hidden_requires lib_config
8
    : _ Lib_mode.Cm_kind.Map.t
9
    =
10
    (* TODO : some of the requires can filtered out using [ocamldep] info *)
11
    let open Resolve.Memo.O in
×
12
    let iflags direct_libs hidden_libs mode =
NEW
13
      Lib_flags.L.include_flags ~project ~direct_libs ~hidden_libs mode lib_config
×
14
    in
15
    let make_includes_args ~mode groups =
16
      Command.Args.memo
×
17
        (Resolve.Memo.args
×
18
           (let+ direct_libs = direct_requires
19
            and+ hidden_libs = hidden_requires in
20
            Command.Args.S
×
21
              [ iflags direct_libs hidden_libs mode
×
22
              ; Hidden_deps (Lib_file_deps.deps (direct_libs @ hidden_libs) ~groups)
×
23
              ]))
24
    in
25
    let cmi_includes = make_includes_args ~mode:(Ocaml Byte) [ Ocaml Cmi ] in
26
    let cmx_includes =
×
27
      Command.Args.memo
28
        (Resolve.Memo.args
×
29
           (let+ direct_libs = direct_requires
30
            and+ hidden_libs = hidden_requires in
31
            Command.Args.S
×
32
              [ iflags direct_libs hidden_libs (Ocaml Native)
×
33
              ; Hidden_deps
34
                  (if opaque
35
                   then
36
                     List.map (direct_libs @ hidden_libs) ~f:(fun lib ->
37
                       ( lib
×
38
                       , if Lib.is_local lib
39
                         then [ Lib_file_deps.Group.Ocaml Cmi ]
×
40
                         else [ Ocaml Cmi; Ocaml Cmx ] ))
×
41
                     |> Lib_file_deps.deps_with_exts
×
42
                   else
43
                     Lib_file_deps.deps
×
44
                       (direct_libs @ hidden_libs)
45
                       ~groups:[ Lib_file_deps.Group.Ocaml Cmi; Ocaml Cmx ])
46
              ]))
47
    in
48
    let melange_cmi_includes = make_includes_args ~mode:Melange [ Melange Cmi ] in
×
49
    let melange_cmj_includes =
×
50
      make_includes_args ~mode:Melange [ Melange Cmi; Melange Cmj ]
51
    in
52
    { ocaml = { cmi = cmi_includes; cmo = cmi_includes; cmx = cmx_includes }
×
53
    ; melange = { cmi = melange_cmi_includes; cmj = melange_cmj_includes }
54
    }
55
  ;;
56

57
  let empty = Lib_mode.Cm_kind.Map.make_all Command.Args.empty
38✔
58
end
59

60
type opaque =
61
  | Explicit of bool
62
  | Inherit_from_settings
63

64
let eval_opaque (ocaml : Ocaml_toolchain.t) profile = function
65
  | Explicit b -> b
×
66
  | Inherit_from_settings ->
×
67
    Profile.is_dev profile && Ocaml.Version.supports_opaque_for_mli ocaml.version
×
68
;;
69

70
type modules =
71
  { modules : Modules.With_vlib.t
72
  ; dep_graphs : Dep_graph.t Ml_kind.Dict.t
73
  }
74

75
let singleton_modules m =
76
  { modules = Modules.With_vlib.singleton m; dep_graphs = Dep_graph.Ml_kind.dummy m }
×
77
;;
78

79
type t =
80
  { super_context : Super_context.t
81
  ; scope : Scope.t
82
  ; obj_dir : Path.Build.t Obj_dir.t
83
  ; modules : modules
84
  ; flags : Ocaml_flags.t
85
  ; requires_compile : Lib.t list Resolve.Memo.t
86
  ; requires_hidden : Lib.t list Resolve.Memo.t
87
  ; requires_link : Lib.t list Resolve.t Memo.Lazy.t
88
  ; includes : Includes.t
89
  ; preprocessing : Pp_spec.t
90
  ; opaque : bool
91
  ; stdlib : Ocaml_stdlib.t option
92
  ; js_of_ocaml : Js_of_ocaml.In_context.t option Js_of_ocaml.Mode.Pair.t
93
  ; sandbox : Sandbox_config.t
94
  ; package : Package.t option
95
  ; vimpl : Vimpl.t option
96
  ; melange_package_name : Lib_name.t option
97
  ; modes : Lib_mode.Map.Set.t
98
  ; bin_annot : bool
99
  ; ocamldep_modules_data : Ocamldep.Modules_data.t
100
  ; loc : Loc.t option
101
  ; ocaml : Ocaml_toolchain.t
102
  }
103

104
let loc t = t.loc
×
105
let super_context t = t.super_context
×
106
let scope t = t.scope
×
107
let dir t = Obj_dir.dir t.obj_dir
×
108
let obj_dir t = t.obj_dir
×
109
let modules t = t.modules.modules
×
110
let flags t = t.flags
×
111
let requires_compile t = t.requires_compile
×
112
let requires_hidden t = t.requires_hidden
×
113
let requires_link t = Memo.Lazy.force t.requires_link
×
114
let includes t = t.includes
×
115
let preprocessing t = t.preprocessing
×
116
let opaque t = t.opaque
×
117
let stdlib t = t.stdlib
×
118
let js_of_ocaml t = t.js_of_ocaml
×
119
let sandbox t = t.sandbox
×
120
let set_sandbox t sandbox = { t with sandbox }
×
121
let package t = t.package
×
122
let melange_package_name t = t.melange_package_name
×
123
let vimpl t = t.vimpl
×
124
let modes t = t.modes
×
125
let bin_annot t = t.bin_annot
×
126
let context t = Super_context.context t.super_context
×
127
let ocamldep_modules_data t = t.ocamldep_modules_data
×
128
let dep_graphs t = t.modules.dep_graphs
×
129
let ocaml t = t.ocaml
×
130

131
let create
132
  ~super_context
133
  ~scope
134
  ~obj_dir
135
  ~modules
136
  ~flags
137
  ~requires_compile
138
  ~requires_link
139
  ?(preprocessing = Pp_spec.dummy)
×
140
  ~opaque
141
  ?stdlib
142
  ~js_of_ocaml
143
  ~package
144
  ~melange_package_name
145
  ?vimpl
146
  ?modes
147
  ?bin_annot
148
  ?loc
149
  ()
150
  =
151
  let project = Scope.project scope in
×
152
  let context = Super_context.context super_context in
×
153
  let* ocaml = Context.ocaml context in
×
154
  let direct_requires, hidden_requires =
×
155
    if Dune_project.implicit_transitive_deps project
156
    then Memo.Lazy.force requires_link, Resolve.Memo.return []
×
157
    else if Version.supports_hidden_includes ocaml.version
×
158
            && Dune_project.dune_version project >= (3, 17)
×
159
    then (
×
160
      let requires_hidden =
161
        let open Resolve.Memo.O in
162
        let+ requires_compile = requires_compile
163
        and+ requires_link = Memo.Lazy.force requires_link in
×
164
        let requires_table = Table.create (module Lib) 5 in
×
165
        List.iter ~f:(fun lib -> Table.set requires_table lib ()) requires_compile;
×
166
        List.filter requires_link ~f:(fun l -> not (Table.mem requires_table l))
×
167
      in
168
      requires_compile, requires_hidden)
169
    else requires_compile, Resolve.Memo.return []
×
170
  in
171
  let sandbox = Sandbox_config.no_special_requirements in
172
  let modes =
173
    let default =
174
      { Lib_mode.Map.ocaml = Mode.Dict.make_both (Some Mode_conf.Kind.Inherited)
×
175
      ; melange = None
176
      }
177
    in
178
    Option.value ~default modes |> Lib_mode.Map.map ~f:Option.is_some
×
179
  in
180
  let opaque =
181
    let profile = Context.profile context in
182
    eval_opaque ocaml profile opaque
×
183
  in
184
  let ocamldep_modules_data : Ocamldep.Modules_data.t =
185
    { dir = Obj_dir.dir obj_dir
×
186
    ; sandbox
187
    ; obj_dir
188
    ; sctx = super_context
189
    ; vimpl
190
    ; modules
191
    ; stdlib
192
    }
193
  in
194
  let+ dep_graphs = Dep_rules.rules ocamldep_modules_data
×
195
  and+ bin_annot =
196
    match bin_annot with
197
    | Some b -> Memo.return b
×
198
    | None -> Env_stanza_db.bin_annot ~dir:(Obj_dir.dir obj_dir)
×
199
  in
200
  { super_context
×
201
  ; scope
202
  ; obj_dir
203
  ; modules = { modules; dep_graphs }
204
  ; flags
205
  ; requires_compile = direct_requires
206
  ; requires_hidden = hidden_requires
207
  ; requires_link
208
  ; includes =
NEW
209
      Includes.make ~project ~opaque ~direct_requires ~hidden_requires ocaml.lib_config
×
210
  ; preprocessing
211
  ; opaque
212
  ; stdlib
213
  ; js_of_ocaml
214
  ; sandbox
215
  ; package
216
  ; vimpl
217
  ; melange_package_name
218
  ; modes
219
  ; bin_annot
220
  ; ocamldep_modules_data
221
  ; loc
222
  ; ocaml
223
  }
224
;;
225

226
let alias_and_root_module_flags =
227
  let extra = [ "-w"; "-49"; "-nopervasives"; "-nostdlib" ] in
228
  fun base -> Ocaml_flags.append_common base extra
×
229
;;
230

231
let for_alias_module t alias_module =
232
  let keep_flags = Modules.With_vlib.is_stdlib_alias (modules t) alias_module in
×
233
  let flags =
×
234
    if keep_flags
235
    then (* in the case of stdlib, these flags can be written by the user *)
236
      t.flags
×
237
    else (
×
238
      let project = Scope.project t.scope in
239
      let dune_version = Dune_project.dune_version project in
×
240
      let profile = Super_context.context t.super_context |> Context.profile in
×
241
      Ocaml_flags.default ~dune_version ~profile)
×
242
  in
243
  let sandbox =
244
    (* If the compiler reads the cmi for module alias even with [-w -49
245
       -no-alias-deps], we must sandbox the build of the alias module since the
246
       modules it references are built after. *)
247
    if Ocaml.Version.always_reads_alias_cmi t.ocaml.version
248
    then Sandbox_config.needs_sandboxing
×
249
    else Sandbox_config.no_special_requirements
×
250
  in
251
  let (modules, includes) : modules * Includes.t =
252
    match Modules.With_vlib.is_stdlib_alias t.modules.modules alias_module with
253
    | false -> singleton_modules alias_module, Includes.empty
×
254
    | true ->
×
255
      (* The stdlib alias module is different from the alias modules usually
256
         produced by Dune: it contains code and depends on a few other
257
         [CamlinnternalXXX] modules from the stdlib, so we need the full set of
258
         modules to compile it. *)
259
      t.modules, t.includes
260
  in
261
  { t with
262
    flags = alias_and_root_module_flags flags
×
263
  ; includes
264
  ; stdlib = None
265
  ; sandbox
266
  ; modules
267
  }
268
;;
269

270
let for_root_module t root_module =
271
  let flags =
×
272
    let project = Scope.project t.scope in
273
    let dune_version = Dune_project.dune_version project in
×
274
    let profile = Super_context.context t.super_context |> Context.profile in
×
275
    Ocaml_flags.default ~profile ~dune_version
×
276
  in
277
  { t with
278
    flags = alias_and_root_module_flags flags
×
279
  ; stdlib = None
280
  ; modules = singleton_modules root_module
×
281
  }
282
;;
283

284
let for_module_generated_at_link_time cctx ~requires ~module_ =
285
  let opaque =
×
286
    (* Cmi's of link time generated modules are compiled with -opaque, hence
287
       their implementation must also be compiled with -opaque *)
288
    Ocaml.Version.supports_opaque_for_mli cctx.ocaml.version
289
  in
290
  let direct_requires = requires in
×
291
  let hidden_requires = Resolve.Memo.return [] in
292
  let modules = singleton_modules module_ in
×
293
  let includes =
×
294
    Includes.make
295
      ~project:(Scope.project cctx.scope)
×
296
      ~opaque
297
      ~direct_requires
298
      ~hidden_requires
299
      cctx.ocaml.lib_config
300
  in
UNCOV
301
  { cctx with
×
302
    opaque
303
  ; flags = Ocaml_flags.empty
304
  ; requires_link = Memo.lazy_ (fun () -> requires)
×
305
  ; requires_compile = requires
306
  ; includes
307
  ; modules
308
  }
309
;;
310

311
let for_wrapped_compat t =
312
  (* See #10689 *)
313
  let flags = Ocaml_flags.append_common t.flags [ "-w"; "-53" ] in
×
314
  { t with includes = Includes.empty; stdlib = None; flags }
×
315
;;
316

317
let for_plugin_executable t ~embed_in_plugin_libraries =
318
  let libs = Scope.libs t.scope in
×
319
  let requires_link =
×
320
    Memo.lazy_ (fun () ->
321
      Resolve.Memo.List.map ~f:(Lib.DB.resolve libs) embed_in_plugin_libraries)
×
322
  in
323
  { t with requires_link }
×
324
;;
325

326
let without_bin_annot t = { t with bin_annot = false }
×
327

328
let entry_module_names sctx t =
329
  match Lib_info.entry_modules (Lib.info t) with
×
330
  | External d -> Resolve.Memo.of_result d
×
331
  | Local ->
×
332
    let+ modules = Dir_contents.modules_of_lib sctx t in
×
333
    let modules = Option.value_exn modules in
×
334
    Resolve.return (Modules.With_vlib.entry_modules modules |> List.map ~f:Module.name)
×
335
;;
336

337
let root_module_entries t =
338
  let open Action_builder.O in
×
339
  let* requires = Resolve.Memo.read t.requires_compile in
×
340
  let* l =
×
341
    Action_builder.List.map requires ~f:(fun lib ->
×
342
      Action_builder.of_memo (entry_module_names t.super_context lib) >>= Resolve.read)
×
343
  in
344
  Action_builder.return (List.concat l)
×
345
;;
346

347
let set_obj_dir t obj_dir = { t with obj_dir }
×
348
let set_modes t ~modes = { t with modes }
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc