Skip to content

Commit 87faddc

Browse files
committed
fix(ctypes): add proper user message for missing modules
Signed-off-by: Ali Caglayan <alizter@gmail.com>
1 parent 3cad8e1 commit 87faddc

5 files changed

Lines changed: 89 additions & 67 deletions

File tree

src/dune_rules/buildable_rules.ml

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ let modules_rules
9494
~preprocessor_deps
9595
~lint
9696
~empty_module_interface_if_absent
97+
~ctypes
98+
~modules_loc
99+
~buildable_loc
97100
sctx
98101
expander
99102
~dir
@@ -135,6 +138,39 @@ let modules_rules
135138
fun name -> default || List.mem executable_names name ~equal:Module_name.equal)
136139
else fun _ -> default
137140
in
141+
let* () =
142+
match ctypes with
143+
| Some ctypes ->
144+
let (ctypes : Ctypes_field.t) = ctypes in
145+
let modules = Modules.With_vlib.modules modules in
146+
(* Here we collect all the modules that ctypes expects to be present in
147+
that stanza in order to validate their existence. We do this using
148+
[Memo.parallel_iter] in order to collect all the errors rather than
149+
just the first occurances. *)
150+
(ctypes.type_description.functor_loc, ctypes.type_description.functor_)
151+
:: List.map
152+
~f:(fun (x : Ctypes_field.Function_description.t) -> x.functor_loc, x.functor_)
153+
ctypes.function_description
154+
|> Memo.parallel_iter ~f:(fun ((functor_loc, m) : Loc.t * Module_name.t) ->
155+
match Modules.With_vlib.find modules m with
156+
| Some _ -> Memo.return ()
157+
| None ->
158+
let loc =
159+
Option.first_some modules_loc buildable_loc
160+
|> Option.value
161+
~default:
162+
(Path.build dir |> Path.drop_optional_build_context |> Loc.in_dir)
163+
in
164+
User_error.raise
165+
~loc
166+
[ Pp.textf
167+
"Module %s is required by ctypes at %s but is missing in the modules \
168+
field of the stanza."
169+
(Module_name.to_string m)
170+
(Loc.to_file_colon_line functor_loc)
171+
])
172+
| None -> Memo.return ()
173+
in
138174
let+ modules =
139175
Modules.map_user_written modules ~f:(fun m ->
140176
let* m = Pp_spec.pp_module pp m in
@@ -159,15 +195,31 @@ let modules_rules sctx kind expander ~dir scope modules =
159195
[ Pp.text "The compiler you are using is not compatible with library parameter"
160196
]
161197
in
162-
let preprocess, preprocessor_deps, lint, empty_module_interface_if_absent =
198+
let ( preprocess
199+
, preprocessor_deps
200+
, lint
201+
, empty_module_interface_if_absent
202+
, ctypes
203+
, modules_loc
204+
, buildable_loc )
205+
=
163206
match kind with
164207
| Executables (buildable, _) | Library (buildable, _) | Parameter (buildable, _) ->
165208
( buildable.preprocess
166209
, buildable.preprocessor_deps
167210
, buildable.lint
168-
, buildable.empty_module_interface_if_absent )
211+
, buildable.empty_module_interface_if_absent
212+
, buildable.ctypes
213+
, Ordered_set_lang.Unexpanded.loc buildable.modules.modules
214+
, Some buildable.loc )
169215
| Melange { preprocess; preprocessor_deps; lint; empty_module_interface_if_absent } ->
170-
preprocess, preprocessor_deps, lint, empty_module_interface_if_absent
216+
( preprocess
217+
, preprocessor_deps
218+
, lint
219+
, empty_module_interface_if_absent
220+
, None
221+
, None
222+
, None )
171223
in
172224
let lib_name =
173225
match kind with
@@ -184,6 +236,9 @@ let modules_rules sctx kind expander ~dir scope modules =
184236
~preprocessor_deps
185237
~lint
186238
~empty_module_interface_if_absent
239+
~ctypes
240+
~modules_loc
241+
~buildable_loc
187242
sctx
188243
expander
189244
~dir

src/dune_rules/ctypes/ctypes_field.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,16 @@ end
9191
module Type_description = struct
9292
type t =
9393
{ functor_ : Module_name.t
94+
; functor_loc : Loc.t
9495
; instance : Module_name.t
9596
}
9697

9798
let decode =
9899
let open Dune_lang.Decoder in
99100
fields
100-
(let+ functor_ = field "functor" Module_name.decode
101+
(let+ functor_loc, functor_ = located @@ field "functor" Module_name.decode
101102
and+ instance = field "instance" Module_name.decode in
102-
{ functor_; instance })
103+
{ functor_; functor_loc; instance })
103104
;;
104105
end
105106

@@ -108,6 +109,7 @@ module Function_description = struct
108109
{ concurrency : Concurrency_policy.t
109110
; errno_policy : Errno_policy.t
110111
; functor_ : Module_name.t
112+
; functor_loc : Loc.t
111113
; instance : Module_name.t
112114
}
113115

@@ -116,11 +118,12 @@ module Function_description = struct
116118
fields
117119
(let+ concurrency = field_o "concurrency" Concurrency_policy.decode
118120
and+ errno_policy = field_o "errno_policy" Errno_policy.decode
119-
and+ functor_ = field "functor" Module_name.decode
121+
and+ functor_loc, functor_ = located @@ field "functor" Module_name.decode
120122
and+ instance = field "instance" Module_name.decode in
121123
{ concurrency = Option.value concurrency ~default:Concurrency_policy.default
122124
; errno_policy = Option.value errno_policy ~default:Errno_policy.default
123125
; functor_
126+
; functor_loc
124127
; instance
125128
})
126129
;;

src/dune_rules/ctypes/ctypes_field.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ end
3636
module Type_description : sig
3737
type t =
3838
{ functor_ : Module_name.t
39+
; functor_loc : Loc.t
3940
; instance : Module_name.t
4041
}
4142
end
@@ -45,6 +46,7 @@ module Function_description : sig
4546
{ concurrency : Concurrency_policy.t
4647
; errno_policy : Errno_policy.t
4748
; functor_ : Module_name.t
49+
; functor_loc : Loc.t
4850
; instance : Module_name.t
4951
}
5052
end

test/blackbox-tests/test-cases/ctypes/gh12018.t

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -43,61 +43,15 @@ Reproduction case for https://github.com/ocaml/dune/issues/12018
4343

4444
$ LIBEX=$(realpath "$PWD/libexample")
4545
$ DYLD_LIBRARY_PATH="$LIBEX" LD_LIBRARY_PATH="$LIBEX" PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" dune exec ./foo.exe
46-
Internal error, please report upstream including the contents of _build/log.
47-
Description:
48-
("link_many: unable to find module",
49-
{ main_module_name = "Libexample__type_gen"
50-
; modules =
51-
Modules
52-
(Singleton
53-
{ source =
54-
{ path = [ "Foo" ]
55-
; files =
56-
{ impl =
57-
Some
58-
{ path = In_build_dir "default/foo.ml"
59-
; original_path = In_build_dir "default/foo.ml"
60-
; dialect = "ocaml"
61-
}
62-
; intf =
63-
Some
64-
{ path = In_build_dir "default/foo.mli"
65-
; original_path = In_build_dir "default/foo.mli"
66-
; dialect = "ocaml"
67-
}
68-
}
69-
}
70-
; obj_name = "dune__exe__Foo"
71-
; pp = None
72-
; visibility = "public"
73-
; kind = "impl"
74-
; install_as = None
75-
})
76-
})
77-
Raised at Stdune__Code_error.raise in file
78-
"otherlibs/stdune/src/code_error.ml", line 10, characters 30-62
79-
Called from Dune_rules__Exe.link_many.(fun) in file "src/dune_rules/exe.ml",
80-
lines 312-316, characters 12-15
81-
Called from Fiber__Scheduler.exec in file "src/fiber/src/scheduler.ml", line
82-
76, characters 8-11
83-
Re-raised at Stdune__Exn.raise_with_backtrace in file
84-
"otherlibs/stdune/src/exn.ml", line 38, characters 27-56
85-
Called from Fiber__Scheduler.exec in file "src/fiber/src/scheduler.ml", line
86-
76, characters 8-11
87-
Re-raised at Stdune__Exn.raise_with_backtrace in file
88-
"otherlibs/stdune/src/exn.ml", line 38, characters 27-56
89-
Called from Fiber__Scheduler.exec in file "src/fiber/src/scheduler.ml", line
90-
76, characters 8-11
91-
Re-raised at Stdune__Exn.raise_with_backtrace in file
92-
"otherlibs/stdune/src/exn.ml", line 38, characters 27-56
93-
Called from Fiber__Scheduler.exec in file "src/fiber/src/scheduler.ml", line
94-
76, characters 8-11
95-
-> required by ("<unnamed>", ())
96-
-> required by ("load-dir", In_build_dir "default")
97-
98-
I must not crash. Uncertainty is the mind-killer. Exceptions are the
99-
little-death that brings total obliteration. I will fully express my cases.
100-
Execution will pass over me and through me. And when it has gone past, I
101-
will unwind the stack along its path. Where the cases are handled there will
102-
be nothing. Only I will remain.
46+
File "dune", line 3, characters 10-13:
47+
3 | (modules foo)
48+
^^^
49+
Error: Module Function_description is required by ctypes at dune:13 but is
50+
missing in the modules field of the stanza.
51+
File "dune", line 3, characters 10-13:
52+
3 | (modules foo)
53+
^^^
54+
Error: Module Type_description is required by ctypes at dune:10 but is
55+
missing in the modules field of the stanza.
10356
[1]
57+

test/blackbox-tests/test-cases/ctypes/github-5561-name-mangle.t

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,16 @@
1616
> EOF
1717

1818
$ bash -c 'set -o pipefail; dune build 2>&1 | head -n 20'
19-
File "fooBar__type_gen.ml", line 3, characters 12-34:
20-
3 | (module Type_description.Types)
21-
^^^^^^^^^^^^^^^^^^^^^^
22-
Error: Unbound module Type_description
19+
File "dune", lines 1-9, characters 0-211:
20+
1 | (library
21+
2 | (name foo)
22+
3 | (ctypes
23+
4 | (external_library_name fooBar)
24+
5 | (build_flags_resolver vendored)
25+
6 | (generated_entry_point Types_generated2)
26+
7 | (type_description
27+
8 | (instance Type)
28+
9 | (functor Type_description))))
29+
Error: Module Type_description is required by ctypes at dune:9 but is missing
30+
in the modules field of the stanza.
2331
[1]

0 commit comments

Comments
 (0)