Skip to content

Commit 48e34b2

Browse files
committed
[coq] Add dependency to META file for Coq plugins
Traditionally, `coqdep` requires the source files of all involved theories to be present in the filesystem, as to resolve logical paths to files. For `.v` files this process is easy, however for plugins, `coqdep` relies on the presence of a `plugin.mlpack` file as a hint that a `plugin.cmxs` file will be produced, so it can correctly map `Declare Ml` to the right `.cmxs`. Starting with 8.16, `coqdep` can alternatively use `META` files to do this mapping, but that requires `META` files to be present in the build tree, at the right path pointed by `OCAMLPATH`. We thus add the `META` files as a dependency for coqdep, which is backwards compatible and will allow us to fix Dune to work with the new findlib-based plugin loading method in Coq 8.16. Unfortunately, the code in Coq upstream seems pretty broken (it seems to produce paths that are wrong w.r.t. our `META` files), so this will need fixing in Coq to fully work, but this is the Dune part, so the rest of work belongs to Coq upstream IIANM. The issue upstream is rocq-prover/rocq#16571 Signed-off-by: Emilio Jesus Gallego Arias <e+git@x80.org>
1 parent 1b8a4c0 commit 48e34b2

File tree

14 files changed

+130
-22
lines changed

14 files changed

+130
-22
lines changed

CHANGES.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,20 @@
7171

7272
- The test suite for Coq now requires Coq >= 8.16 due to changes in the
7373
plugin loading mechanism upstream (which now uses findlib).
74-
74+
7575
- Starting with Coq build language 0.6, theories can be built without importing
7676
Coq's standard library by including `(stdlib no)`.
7777
(#6165 #6164, fixes #6163, @ejgallego @Alizter @LasseBlaauwbroek)
7878

7979
- on macOS, sign executables produced by artifact substitution (#6137, fixes
8080
#5650, @emillon)
8181

82+
- The `(coq.theory ...)` stanza will now ensure that for each declared
83+
`(plugin ...)`, the `META` file for is built before calling
84+
`coqdep`. This enables to use the new `findlib`-based loading method
85+
in Coq 8.16, however as of Coq 8.16.0, Coq itself has some bugs
86+
preventing this to work yet. (#6167 , workarounds #5767, @ejgallego)
87+
8288
3.4.1 (26-07-2022)
8389
------------------
8490

src/dune_rules/coq_rules.ml

+42-7
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,33 @@ let resolve_program sctx ~loc ~dir prog =
5656
~hint:"opam install coq"
5757

5858
module Coq_plugin = struct
59+
let meta_info ~coq_lang_version ~plugin_loc ~context (lib : Lib.t) =
60+
let debug = false in
61+
let name = Lib.name lib |> Lib_name.to_string in
62+
if debug then Format.eprintf "Meta info for %s@\n" name;
63+
match Lib_info.status (Lib.info lib) with
64+
| Public (_, pkg) ->
65+
let package = Package.name pkg in
66+
let meta_i =
67+
Path.Build.relative
68+
(Local_install_path.lib_dir ~context ~package)
69+
"META"
70+
in
71+
if debug then
72+
Format.eprintf "Meta for %s: %s@\n" name (Path.Build.to_string meta_i);
73+
Some (Path.build meta_i)
74+
| Installed -> None
75+
| Installed_private | Private _ ->
76+
let is_error = coq_lang_version >= (0, 6) in
77+
let text = if is_error then "not supported" else "deprecated" in
78+
User_warning.emit ?loc:plugin_loc ~is_error
79+
[ Pp.textf "Using private library %s as a Coq plugin is %s" text
80+
name
81+
];
82+
None
83+
5984
(* compute include flags and mlpack rules *)
60-
let setup_ml_deps libs theories =
85+
let setup_ml_deps ~coq_lang_version ~context ~plugin_loc libs theories =
6186
(* Pair of include flags and paths to mlpack *)
6287
let libs =
6388
let open Resolve.Memo.O in
@@ -76,18 +101,27 @@ module Coq_plugin = struct
76101
( flags
77102
, let* libs = Resolve.Memo.read libs in
78103
(* If the mlpack files don't exist, don't fail *)
79-
Action_builder.paths_existing (List.concat_map ~f:Util.ml_pack_files libs)
80-
)
81-
82-
let of_buildable ~lib_db ~theories_deps (buildable : Coq_stanza.Buildable.t) =
104+
Action_builder.all_unit
105+
[ Action_builder.paths
106+
(List.filter_map
107+
~f:(meta_info ~plugin_loc ~coq_lang_version ~context)
108+
libs)
109+
; Action_builder.paths_existing
110+
(List.concat_map ~f:Util.ml_pack_files libs)
111+
] )
112+
113+
let of_buildable ~context ~lib_db ~theories_deps
114+
(buildable : Coq_stanza.Buildable.t) =
83115
let res =
84116
let open Resolve.Memo.O in
85117
let+ libs =
86118
Resolve.Memo.List.map buildable.plugins ~f:(fun (loc, name) ->
87119
let+ lib = Lib.DB.resolve lib_db (loc, name) in
88120
(loc, lib))
89121
in
90-
setup_ml_deps libs theories_deps
122+
let coq_lang_version = buildable.coq_lang_version in
123+
let plugin_loc = List.hd_opt buildable.plugins |> Option.map ~f:fst in
124+
setup_ml_deps ~plugin_loc ~coq_lang_version ~context libs theories_deps
91125
in
92126
let ml_flags = Resolve.Memo.map res ~f:fst in
93127
let mlpack_rule =
@@ -290,12 +324,13 @@ module Context = struct
290324
let loc = buildable.loc in
291325
let use_stdlib = buildable.use_stdlib in
292326
let rr = resolve_program sctx ~dir ~loc in
327+
let context = Super_context.context sctx |> Context.name in
293328
let* expander = Super_context.expander sctx ~dir in
294329
let* scope = Scope.DB.find_by_dir dir in
295330
let lib_db = Scope.libs scope in
296331
(* ML-level flags for depending libraries *)
297332
let ml_flags, mlpack_rule =
298-
Coq_plugin.of_buildable ~theories_deps ~lib_db buildable
333+
Coq_plugin.of_buildable ~context ~theories_deps ~lib_db buildable
299334
in
300335
let mode = select_native_mode ~sctx ~buildable in
301336
let* native_includes =

test/blackbox-tests/test-cases/coq/deprecate-libraries.t/bar.opam

Whitespace-only changes.

test/blackbox-tests/test-cases/coq/deprecate-libraries.t/run.t

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,42 @@
11
The libraries field is deprecated
22
$ cat > dune << EOF
33
> (library
4+
> (public_name bar.foo)
45
> (name foo))
56
>
6-
> (coq.theory
7+
> (coq.theory
78
> (name bar)
8-
> (libraries foo))
9+
> (libraries bar.foo))
910
> EOF
1011

1112
$ dune build
12-
File "dune", line 6, characters 1-16:
13-
6 | (libraries foo))
14-
^^^^^^^^^^^^^^^
13+
File "dune", line 7, characters 1-20:
14+
7 | (libraries bar.foo))
15+
^^^^^^^^^^^^^^^^^^^
1516
Warning: 'libraries' was deprecated in version 0.5 of the Coq language. It
1617
has been renamed to 'plugins'.
1718

1819
Having both a libraries and plugins field is an error
1920
$ cat > dune << EOF
2021
> (library
22+
> (public_name bar.foo)
2123
> (name foo))
2224
>
23-
> (coq.theory
25+
> (coq.theory
2426
> (name bar)
25-
> (libraries foo)
26-
> (plugins foo))
27+
> (libraries bar.foo)
28+
> (plugins bar.foo))
2729
> EOF
2830

2931
$ dune build
30-
File "dune", line 6, characters 1-16:
31-
6 | (libraries foo)
32-
^^^^^^^^^^^^^^^
32+
File "dune", line 7, characters 1-20:
33+
7 | (libraries bar.foo)
34+
^^^^^^^^^^^^^^^^^^^
3335
Warning: 'libraries' was deprecated in version 0.5 of the Coq language. It
3436
has been renamed to 'plugins'.
35-
File "dune", line 6, characters 12-15:
36-
6 | (libraries foo)
37-
^^^
37+
File "dune", line 7, characters 12-19:
38+
7 | (libraries bar.foo)
39+
^^^^^^^
3840
Error: Cannot both use 'plugins' and 'libraries', please remove 'libraries'
3941
as it has been deprecated since version 0.5 of the Coq language. It will be
4042
removed before version 1.0.

test/blackbox-tests/test-cases/coq/plugin-meta.t/bar.opam

Whitespace-only changes.

test/blackbox-tests/test-cases/coq/plugin-meta.t/bar.v

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(lang dune 3.5)
2+
(using coq 0.6)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let foo = "bar"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
The libraries field is deprecated
2+
$ cat > dune << EOF
3+
> (library
4+
> (public_name bar.foo)
5+
> (name foo))
6+
>
7+
> (coq.theory
8+
> (name bar)
9+
> (plugins bar.foo))
10+
> EOF
11+
12+
$ dune build bar.v.d
13+
$ ls -R _build/install/default/lib/bar
14+
_build/install/default/lib/bar:
15+
META
16+

test/blackbox-tests/test-cases/coq/plugin-private.t/bar.opam

Whitespace-only changes.

test/blackbox-tests/test-cases/coq/plugin-private.t/bar.v

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(lang dune 3.5)
2+
(using coq 0.6)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let foo = "bar"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
The libraries field is deprecated
2+
$ cat > dune << EOF
3+
> (library
4+
> (name foo))
5+
>
6+
> (coq.theory
7+
> (name bar)
8+
> (plugins foo))
9+
> EOF
10+
11+
$ dune build
12+
File "dune", line 6, characters 10-13:
13+
6 | (plugins foo))
14+
^^^
15+
Error: Using private library not supported as a Coq plugin is foo
16+
[1]
17+
18+
Having both a libraries and plugins field is an error
19+
$ cat > dune << EOF
20+
> (library
21+
> (public_name bar.foo)
22+
> (name foo))
23+
>
24+
> (coq.theory
25+
> (name bar)
26+
> (libraries bar.foo)
27+
> (plugins bar.foo))
28+
> EOF
29+
30+
$ dune build
31+
File "dune", line 7, characters 1-20:
32+
7 | (libraries bar.foo)
33+
^^^^^^^^^^^^^^^^^^^
34+
Warning: 'libraries' was deprecated in version 0.5 of the Coq language. It
35+
has been renamed to 'plugins'.
36+
File "dune", line 7, characters 12-19:
37+
7 | (libraries bar.foo)
38+
^^^^^^^
39+
Error: Cannot both use 'plugins' and 'libraries', please remove 'libraries'
40+
as it has been deprecated since version 0.5 of the Coq language. It will be
41+
removed before version 1.0.
42+
[1]
43+

0 commit comments

Comments
 (0)