Skip to content

Commit 67863a7

Browse files
ejgallegoLysxia
andcommitted
[rocq] Support for installation of package metadata.
We now install a `rocq-package` file for each Rocq theory. This way, when Rocq developments build with Dune are globally installed, we can find out additional metadata, such as the list of their dependencies. Fixes #11012 fixes #11483 TODO: - update changelog - update documentation - rebase on top of (lang rocq 0.1) Co-authored-by: Li-yao Xia <[email protected]>
1 parent 05017cd commit 67863a7

File tree

37 files changed

+417
-95
lines changed

37 files changed

+417
-95
lines changed

src/dune_rules/coq/coq_lib.ml

Lines changed: 79 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,19 @@ and Dune : sig
7373
; implicit : bool (* Only useful for the stdlib *)
7474
; use_stdlib : bool
7575
(* whether this theory uses the stdlib, eventually set to false for all libs *)
76-
; src_root : Path.Build.t
77-
; obj_root : Path.Build.t
76+
; src_root : (Path.Build.t, Path.t list) Either.t
77+
(* Right: list of source files *)
78+
; obj_root : (Path.Build.t, Path.t) Either.t
79+
(* Left: local library. Right: installed library. *)
7880
; theories : (Loc.t * R.t) list Resolve.t
7981
; libraries : (Loc.t * Lib.t) list Resolve.t
8082
; theories_closure : R.t list Resolve.t Lazy.t
81-
; package : Package.t option
83+
; package : [ `Private | `Local of Package.t | `Dependency ]
8284
}
8385

8486
val to_dyn : t -> Dyn.t
85-
val src_root : t -> Path.Build.t
86-
val obj_root : t -> Path.Build.t
87+
val src_root : t -> (Path.Build.t, Path.t list) Either.t
88+
val obj_root : t -> (Path.Build.t, Path.t) Either.t
8789
val implicit : t -> bool
8890

8991
(** ML libraries *)
@@ -96,12 +98,14 @@ end = struct
9698
; implicit : bool (* Only useful for the stdlib *)
9799
; use_stdlib : bool
98100
(* whether this theory uses the stdlib, eventually set to false for all libs *)
99-
; src_root : Path.Build.t
100-
; obj_root : Path.Build.t
101+
; src_root : (Path.Build.t, Path.t list) Either.t
102+
(* Right: list of source files *)
103+
; obj_root : (Path.Build.t, Path.t) Either.t
104+
(* Left: local library. Right: installed library. *)
101105
; theories : (Loc.t * R.t) list Resolve.t
102106
; libraries : (Loc.t * Lib.t) list Resolve.t
103107
; theories_closure : R.t list Resolve.t Lazy.t
104-
; package : Package.t option
108+
; package : [ `Private | `Local of Package.t | `Dependency ]
105109
}
106110

107111
let to_dyn
@@ -125,14 +129,14 @@ end = struct
125129
; "id", Id.to_dyn id
126130
; "implicit", Bool.to_dyn implicit
127131
; "use_stdlib", Bool.to_dyn use_stdlib
128-
; "src_root", Path.Build.to_dyn src_root
129-
; "obj_root", Path.Build.to_dyn obj_root
132+
; "src_root", Either.to_dyn Path.Build.to_dyn (list Path.to_dyn) src_root
133+
; "obj_root", Either.to_dyn Path.Build.to_dyn Path.to_dyn obj_root
130134
; "theories", Resolve.to_dyn (Dyn.list (Dyn.pair Loc.to_dyn R.to_dyn)) theories
131135
; ( "libraries"
132136
, Resolve.to_dyn (Dyn.list (Dyn.pair Loc.to_dyn Lib.to_dyn)) libraries )
133137
; ( "theories_closure"
134138
, Resolve.to_dyn (Dyn.list R.to_dyn) (Lazy.force theories_closure) )
135-
; "package", Dyn.option Package.to_dyn package
139+
; "package", match package with `Private -> Dyn.variant "Private" [] | `Local pkg -> Dyn.variant "Local" [Package.to_dyn pkg] | `Dependency -> Dyn.variant "Dependency" []
136140
])
137141
;;
138142

@@ -202,7 +206,7 @@ let name = function
202206
;;
203207

204208
let obj_root = function
205-
| Dune t -> Dune.obj_root t |> Path.build
209+
| Dune t -> Dune.obj_root t |> Either.map ~l:Path.build ~r:Fun.id
206210
| Legacy t -> Legacy.installed_root t
207211
;;
208212

@@ -361,11 +365,13 @@ module DB = struct
361365
module rec R : sig
362366
val resolve_boot
363367
: t
368+
-> db:Lib.DB.t
364369
-> coq_lang_version:Dune_sexp.Syntax.Version.t
365370
-> (Loc.t * lib) option Resolve.Memo.t
366371

367372
val resolve
368373
: t
374+
-> db:Lib.DB.t
369375
-> coq_lang_version:Dune_sexp.Syntax.Version.t
370376
-> Loc.t * Coq_lib_name.t
371377
-> lib Resolve.Memo.t
@@ -423,91 +429,103 @@ module DB = struct
423429
else theories
424430
;;
425431

426-
let resolve_boot ~coq_lang_version ~coq_db (boot_id : Id.t option) =
432+
let resolve_boot ~db ~coq_lang_version ~coq_db (boot_id : Id.t option) =
427433
match boot_id with
428434
| Some boot_id ->
429435
let open Resolve.Memo.O in
430-
let+ lib = resolve ~coq_lang_version coq_db (boot_id.loc, boot_id.name) in
436+
let+ lib = resolve ~db ~coq_lang_version coq_db (boot_id.loc, boot_id.name) in
431437
Some (boot_id.loc, lib)
432438
| None -> Resolve.Memo.return None
433439
;;
434440

435441
let resolve_theory
442+
~db
436443
~coq_lang_version
437444
~allow_private_deps
438445
~coq_db
439446
~boot_id
440447
(loc, theory_name)
441448
=
442449
let open Resolve.Memo.O in
443-
let* theory = resolve ~coq_lang_version coq_db (loc, theory_name) in
450+
let* theory = resolve ~db ~coq_lang_version coq_db (loc, theory_name) in
444451
let* () = Resolve.Memo.lift @@ check_boot ~boot_id theory in
445452
let+ () =
446453
if allow_private_deps
447454
then Resolve.Memo.return ()
448455
else (
449456
match theory with
450-
| Dune { package = None; _ } -> Error.private_deps_not_allowed ~loc theory_name
457+
| Dune { package = `Private; _ } -> Error.private_deps_not_allowed ~loc theory_name
451458
| Legacy _ | Dune _ -> Resolve.Memo.return ())
452459
in
453460
loc, theory
454461
;;
455462

456-
let resolve_theories ~coq_lang_version ~allow_private_deps ~coq_db ~boot_id theories =
457-
let f = resolve_theory ~coq_lang_version ~allow_private_deps ~coq_db ~boot_id in
463+
let resolve_theories ~db ~coq_lang_version ~allow_private_deps ~coq_db ~boot_id theories =
464+
let f = resolve_theory ~db ~coq_lang_version ~allow_private_deps ~coq_db ~boot_id in
458465
Resolve.Memo.List.map theories ~f
459466
;;
460467

461-
let create_from_stanza_impl (coq_db, db, dir, (s : Coq_stanza.Theory.t)) =
468+
let create_from_coq_package_impl (coq_db, db, (s : (Path.Build.t * Coq_stanza.Theory.t, Coq_package.t) Either.t)) =
469+
let of_package = function
470+
| None -> `Private
471+
| Some pkg -> `Local pkg
472+
in
473+
let path, package, s = match s with
474+
| Left ((dir, s)) -> Left dir, of_package s.package, Coq_package.of_stanza s
475+
| Right p -> Right (Coq_package.path p), `Dependency, Coq_package.meta p in
462476
let name = s.name in
463-
let id = Id.create ~path:(Path.build dir) ~name in
464-
let coq_lang_version = s.buildable.coq_lang_version in
477+
let id = Id.create ~path:(Either.map ~l:Path.build ~r:Fun.id path) ~name in
478+
let coq_lang_version = s.coq_lang_version in
465479
let open Memo.O in
466480
let boot_id = if s.boot then None else boot_library_id coq_db in
467-
let allow_private_deps = Option.is_none s.package in
468-
let use_stdlib = s.buildable.use_stdlib in
481+
let allow_private_deps = match package with `Private -> true | _ -> false in
482+
let use_stdlib = s.use_stdlib in
469483
let+ libraries =
470-
resolve_plugins ~db ~allow_private_deps ~name:(snd name) s.buildable.plugins
484+
resolve_plugins ~db ~allow_private_deps ~name:(snd name) s.plugins
471485
and+ theories =
472486
resolve_theories
487+
~db
473488
~coq_db
474489
~coq_lang_version
475490
~allow_private_deps
476491
~boot_id
477-
s.buildable.theories
478-
and+ boot = resolve_boot ~coq_lang_version ~coq_db boot_id in
492+
s.theories
493+
and+ boot = resolve_boot ~db ~coq_lang_version ~coq_db boot_id in
479494
let theories = maybe_add_boot ~boot ~use_stdlib ~is_boot:s.boot theories in
480495
let map_error x =
481496
let human_readable_description () = Id.pp id in
482497
Resolve.push_stack_frame ~human_readable_description x
483498
in
484499
let theories = map_error theories in
485500
let libraries = map_error libraries in
486-
{ Dune.loc = s.buildable.loc
501+
let src_root = Either.map ~l:(fun dir -> Left dir) ~r:(fun _path -> Right []) path in
502+
{ Dune.loc = s.loc
487503
; boot_id
488504
; id
489505
; use_stdlib
490506
; implicit = s.boot
491-
; obj_root = dir
492-
; src_root = dir
507+
; obj_root = path
508+
; src_root
493509
; theories
494510
; libraries
495511
; theories_closure =
496512
lazy
497513
(Resolve.bind theories ~f:(fun theories ->
498514
List.map theories ~f:snd |> top_closure))
499-
; package = s.package
515+
; package
500516
}
501517
;;
502518

503519
module Input = struct
504-
type nonrec t = t * Lib.DB.t * Path.Build.t * Coq_stanza.Theory.t
520+
type nonrec t = t * Lib.DB.t * (Path.Build.t * Coq_stanza.Theory.t, Coq_package.t) Either.t
505521

506-
let equal (coq_db, ml_db, path, stanza) (coq_db', ml_db', path', stanza') =
522+
let equal (coq_db, ml_db, s) (coq_db', ml_db', s') =
507523
phys_equal coq_db coq_db'
508524
&& phys_equal ml_db ml_db'
509-
&& Path.Build.equal path path'
510-
&& phys_equal stanza stanza'
525+
&& match (s, s') with
526+
| Left ((path, s)), Left ((path', s')) -> Path.Build.equal path path' && phys_equal s s'
527+
| Right s, Right s' -> phys_equal s s'
528+
| _, _ -> false
511529
;;
512530

513531
let hash = Poly.hash
@@ -517,27 +535,41 @@ module DB = struct
517535
let memo =
518536
Memo.create
519537
"create-from-stanza"
520-
~human_readable_description:(fun (_, _, path, theory) ->
521-
Id.pp (Id.create ~path:(Path.build path) ~name:theory.name))
538+
~human_readable_description:(fun (_, _, theory) ->
539+
let (path, name) = match theory with
540+
| Left (dir, stanza) -> Path.build dir, stanza.name
541+
| Right p -> (Coq_package.path p), (Coq_package.meta p).name in
542+
Id.pp (Id.create ~path ~name))
522543
~input:(module Input)
523-
create_from_stanza_impl
544+
create_from_coq_package_impl
524545
;;
525546

526-
let create_from_stanza coq_db db dir stanza = Memo.exec memo (coq_db, db, dir, stanza)
547+
let create_from_coq_package coq_db ~db pkg =
548+
Memo.exec memo (coq_db, db, Right pkg)
549+
550+
let create_from_stanza coq_db db dir stanza = Memo.exec memo (coq_db, db, Left ((dir, stanza)))
527551

528552
(* XXX: Memoize? This is pretty cheap so not sure worth the cost,
529553
still called too much I have observed, suspicious! *)
530-
let create_from_coqpath ~boot_id cp =
554+
let create_from_coqpath_legacy ~boot_id cp =
531555
let name = Coq_path.name cp in
532556
let installed_root = Coq_path.path cp in
533557
let implicit = Coq_path.stdlib cp in
534-
let cmxs_directories = Coq_path.cmxs_directories cp in
558+
let cmxs_directories = Coq_path.cmxs_directories_legacy cp in
535559
let vo = Coq_path.vo cp in
536560
let id = Id.create ~path:installed_root ~name:(Loc.none, name) in
537561
Resolve.Memo.return
538-
{ Legacy.boot_id; id; implicit; installed_root; vo; cmxs_directories }
562+
(Legacy { Legacy.boot_id; id; implicit; installed_root; vo; cmxs_directories })
539563
;;
540564

565+
let create_from_coqpath coq_db ~db = function
566+
| Coq_path.Coq_package pkg ->
567+
Memo.map (create_from_coq_package coq_db ~db pkg) ~f:(fun dune ->
568+
Resolve.return (Dune dune))
569+
| Coq_path.Legacy _ as cp ->
570+
let boot_id = coq_db.boot_id in
571+
create_from_coqpath_legacy ~boot_id cp
572+
541573
module Resolve_result_no_redirect = struct
542574
(** In our second iteration, we remove all the redirects *)
543575
type t =
@@ -582,7 +614,7 @@ module DB = struct
582614

583615
(** Our final final resolve is used externally, and should return the
584616
library data found from the previous iterations. *)
585-
let resolve coq_db ~coq_lang_version (loc, name) =
617+
let resolve coq_db ~db ~coq_lang_version (loc, name) =
586618
match find coq_db ~coq_lang_version name with
587619
| Not_found -> Error.theory_not_found ~loc name
588620
| Hidden reason -> Error.hidden_without_composition ~loc ~reason name
@@ -594,15 +626,12 @@ module DB = struct
594626
let+ (_ : (Loc.t * lib) list) = theory.theories in
595627
Dune theory
596628
| Found_path cp ->
597-
let open Resolve.Memo.O in
598-
let boot_id = coq_db.boot_id in
599-
let+ theory = create_from_coqpath ~boot_id cp in
600-
Legacy theory
629+
create_from_coqpath coq_db ~db cp
601630
;;
602631

603-
let resolve_boot coq_db ~coq_lang_version =
632+
let resolve_boot coq_db ~db ~coq_lang_version =
604633
let boot_id = boot_library_id coq_db in
605-
resolve_boot ~coq_lang_version ~coq_db boot_id
634+
resolve_boot ~db ~coq_lang_version ~coq_db boot_id
606635
;;
607636
end
608637

@@ -692,8 +721,8 @@ module DB = struct
692721
;;
693722

694723
(* Resolve helpers *)
695-
let find_many t theories ~coq_lang_version =
696-
Resolve.Memo.List.map theories ~f:(resolve ~coq_lang_version t)
724+
let find_many t theories ~db ~coq_lang_version =
725+
Resolve.Memo.List.map theories ~f:(resolve ~db ~coq_lang_version t)
697726
;;
698727
end
699728

src/dune_rules/coq/coq_lib.mli

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Dune : sig
88
type t
99

1010
(** Source directory *)
11-
val src_root : t -> Path.Build.t
11+
val src_root : t -> (Path.Build.t, Path.t list) Either.t
1212

1313
(** ML libraries *)
1414
val libraries : t -> (Loc.t * Lib.t) list Resolve.t
@@ -80,16 +80,19 @@ module DB : sig
8080
val find_many
8181
: t
8282
-> (Loc.t * Coq_lib_name.t) list
83+
-> db:Lib.DB.t
8384
-> coq_lang_version:Dune_sexp.Syntax.Version.t
8485
-> lib list Resolve.Memo.t
8586

8687
val resolve_boot
8788
: t
89+
-> db:Lib.DB.t
8890
-> coq_lang_version:Dune_sexp.Syntax.Version.t
8991
-> (Loc.t * lib) option Resolve.Memo.t
9092

9193
val resolve
9294
: t
95+
-> db:Lib.DB.t
9396
-> coq_lang_version:Dune_sexp.Syntax.Version.t
9497
-> Loc.t * Coq_lib_name.t
9598
-> lib Resolve.Memo.t

0 commit comments

Comments
 (0)