Skip to content

Commit 620a450

Browse files
authored
Merge pull request #12124 from Alizter/gh12018
fix(ctypes): mismatch between modules field and ctypes stanza
2 parents 304d9ac + 87faddc commit 620a450

5 files changed

Lines changed: 135 additions & 10 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
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
Reproduction case for https://github.com/ocaml/dune/issues/12018
2+
3+
$ cat > dune-project <<EOF
4+
> (lang dune 3.20)
5+
> (using ctypes 0.3)
6+
> EOF
7+
8+
$ cat > type_description.ml <<EOF
9+
> module Types (F : Ctypes.TYPE) = struct end
10+
> EOF
11+
12+
$ cat > function_description.ml <<EOF
13+
> open Ctypes
14+
> module Types = Types_generated
15+
>
16+
> module Functions (F : Ctypes.FOREIGN) = struct
17+
> open F
18+
> let add2 =
19+
> foreign "example_add2" (int @-> returning int)
20+
> end
21+
> EOF
22+
23+
$ cat > foo.ml <<EOF
24+
> let () = Printf.printf "%d" (C.Functions.add2 2)
25+
> EOF
26+
27+
$ cat > dune <<EOF
28+
> (executable
29+
> (name foo)
30+
> (modules foo)
31+
> (ctypes
32+
> (external_library_name libexample)
33+
> (headers (include "example.h"))
34+
> (build_flags_resolver pkg_config)
35+
> (type_description
36+
> (instance Types)
37+
> (functor Type_description))
38+
> (function_description
39+
> (instance Functions)
40+
> (functor Function_description))
41+
> (generated_entry_point C)))
42+
> EOF
43+
44+
$ LIBEX=$(realpath "$PWD/libexample")
45+
$ DYLD_LIBRARY_PATH="$LIBEX" LD_LIBRARY_PATH="$LIBEX" PKG_CONFIG_PATH="$LIBEX/pkgconfig" PKG_CONFIG_ARGN="--define-prefix" dune exec ./foo.exe
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.
56+
[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)