Skip to content

Commit 079eda9

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 Co-authored-by: Li-yao Xia <[email protected]> Signed-off-by: Emilio Jesus Gallego Arias <[email protected]>
1 parent d1a4553 commit 079eda9

File tree

79 files changed

+637
-100
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+637
-100
lines changed

src/dune_rules/rocq/rocq_lib.ml

Lines changed: 97 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,18 @@ and Dune : sig
8181
; implicit : bool (* Only useful for the stdlib *)
8282
; use_stdlib : bool
8383
(* whether this theory uses the stdlib, eventually set to false for all libs *)
84-
; src_root : Path.Build.t
85-
; obj_root : Path.Build.t
84+
; src_root : (Path.Build.t, Path.t list) Either.t (* Right: list of source files *)
85+
; obj_root : (Path.Build.t, Path.t) Either.t
86+
(* Left: local library. Right: installed library. *)
8687
; theories : (Loc.t * R.t) list Resolve.t
8788
; libraries : (Loc.t * Lib.t) list Resolve.t
8889
; theories_closure : R.t list Resolve.t Lazy.t
89-
; package : Package.t option
90+
; package : [ `Private | `Local of Package.t | `Dependency ]
9091
}
9192

9293
val to_dyn : t -> Dyn.t
93-
val src_root : t -> Path.Build.t
94-
val obj_root : t -> Path.Build.t
94+
val src_root : t -> (Path.Build.t, Path.t list) Either.t
95+
val obj_root : t -> (Path.Build.t, Path.t) Either.t
9596
val implicit : t -> bool
9697

9798
(** ML libraries *)
@@ -104,12 +105,13 @@ end = struct
104105
; implicit : bool (* Only useful for the stdlib *)
105106
; use_stdlib : bool
106107
(* whether this theory uses the stdlib, eventually set to false for all libs *)
107-
; src_root : Path.Build.t
108-
; obj_root : Path.Build.t
108+
; src_root : (Path.Build.t, Path.t list) Either.t (* Right: list of source files *)
109+
; obj_root : (Path.Build.t, Path.t) Either.t
110+
(* Left: local library. Right: installed library. *)
109111
; theories : (Loc.t * R.t) list Resolve.t
110112
; libraries : (Loc.t * Lib.t) list Resolve.t
111113
; theories_closure : R.t list Resolve.t Lazy.t
112-
; package : Package.t option
114+
; package : [ `Private | `Local of Package.t | `Dependency ]
113115
}
114116

115117
let to_dyn
@@ -133,14 +135,18 @@ end = struct
133135
; "id", Id.to_dyn id
134136
; "implicit", Bool.to_dyn implicit
135137
; "use_stdlib", Bool.to_dyn use_stdlib
136-
; "src_root", Path.Build.to_dyn src_root
137-
; "obj_root", Path.Build.to_dyn obj_root
138+
; "src_root", Either.to_dyn Path.Build.to_dyn (list Path.to_dyn) src_root
139+
; "obj_root", Either.to_dyn Path.Build.to_dyn Path.to_dyn obj_root
138140
; "theories", Resolve.to_dyn (Dyn.list (Dyn.pair Loc.to_dyn R.to_dyn)) theories
139141
; ( "libraries"
140142
, Resolve.to_dyn (Dyn.list (Dyn.pair Loc.to_dyn Lib.to_dyn)) libraries )
141143
; ( "theories_closure"
142144
, Resolve.to_dyn (Dyn.list R.to_dyn) (Lazy.force theories_closure) )
143-
; "package", Dyn.option Package.to_dyn package
145+
; ( "package"
146+
, match package with
147+
| `Private -> Dyn.variant "Private" []
148+
| `Local pkg -> Dyn.variant "Local" [ Package.to_dyn pkg ]
149+
| `Dependency -> Dyn.variant "Dependency" [] )
144150
])
145151
;;
146152

@@ -205,7 +211,7 @@ let name = function
205211
;;
206212

207213
let obj_root = function
208-
| Dune t -> Dune.obj_root t |> Path.build
214+
| Dune t -> Dune.obj_root t |> Either.map ~l:Path.build ~r:Fun.id
209215
| Legacy t -> Legacy.installed_root t
210216
;;
211217

@@ -338,8 +344,8 @@ module DB = struct
338344
;;
339345

340346
module rec R : sig
341-
val resolve_boot : t -> (Loc.t * lib) option Resolve.Memo.t
342-
val resolve : t -> Loc.t * Rocq_lib_name.t -> lib Resolve.Memo.t
347+
val resolve_boot : db:Lib.DB.t -> t -> (Loc.t * lib) option Resolve.Memo.t
348+
val resolve : db:Lib.DB.t -> t -> Loc.t * Rocq_lib_name.t -> lib Resolve.Memo.t
343349
end = struct
344350
open R
345351

@@ -394,79 +400,104 @@ module DB = struct
394400
else theories
395401
;;
396402

397-
let resolve_boot ~rocq_db (boot_id : Id.t option) =
403+
let resolve_boot ~db ~rocq_db (boot_id : Id.t option) =
398404
match boot_id with
399405
| Some boot_id ->
400406
let open Resolve.Memo.O in
401-
let+ lib = resolve rocq_db (boot_id.loc, boot_id.name) in
407+
let+ lib = resolve ~db rocq_db (boot_id.loc, boot_id.name) in
402408
Some (boot_id.loc, lib)
403409
| None -> Resolve.Memo.return None
404410
;;
405411

406-
let resolve_theory ~allow_private_deps ~rocq_db ~boot_id (loc, theory_name) =
412+
let resolve_theory ~db ~allow_private_deps ~rocq_db ~boot_id (loc, theory_name) =
407413
let open Resolve.Memo.O in
408-
let* theory = resolve rocq_db (loc, theory_name) in
414+
let* theory = resolve ~db rocq_db (loc, theory_name) in
409415
let* () = Resolve.Memo.lift @@ check_boot ~boot_id theory in
410416
let+ () =
411417
if allow_private_deps
412418
then Resolve.Memo.return ()
413419
else (
414420
match theory with
415-
| Dune { package = None; _ } -> Error.private_deps_not_allowed ~loc theory_name
421+
| Dune { package = `Private; _ } ->
422+
Error.private_deps_not_allowed ~loc theory_name
416423
| Legacy _ | Dune _ -> Resolve.Memo.return ())
417424
in
418425
loc, theory
419426
;;
420427

421-
let resolve_theories ~allow_private_deps ~rocq_db ~boot_id theories =
422-
let f = resolve_theory ~allow_private_deps ~rocq_db ~boot_id in
428+
let resolve_theories ~db ~allow_private_deps ~rocq_db ~boot_id theories =
429+
let f = resolve_theory ~db ~allow_private_deps ~rocq_db ~boot_id in
423430
Resolve.Memo.List.map theories ~f
424431
;;
425432

426-
let create_from_stanza_impl (rocq_db, db, dir, (s : Rocq_stanza.Theory.t)) =
433+
let create_from_rocq_package_impl
434+
( rocq_db
435+
, db
436+
, (s : (Path.Build.t * Rocq_stanza.Theory.t, Rocq_package.t) Either.t) )
437+
=
438+
let of_package = function
439+
| None -> `Private
440+
| Some pkg -> `Local pkg
441+
in
442+
let path, package, s =
443+
match s with
444+
| Left (dir, s) -> Left dir, of_package s.package, Rocq_package.of_stanza s
445+
| Right p -> Right (Rocq_package.path p), `Dependency, Rocq_package.meta p
446+
in
427447
let name = s.name in
428-
let id = Id.create ~path:(Path.build dir) ~name in
448+
let id = Id.create ~path:(Either.map ~l:Path.build ~r:Fun.id path) ~name in
429449
let open Memo.O in
430450
let boot_id = if s.boot then None else boot_library_id rocq_db in
431-
let allow_private_deps = Option.is_none s.package in
432-
let use_stdlib = s.buildable.use_stdlib in
433-
let+ libraries =
434-
resolve_plugins ~db ~allow_private_deps ~name:(snd name) s.buildable.plugins
451+
let allow_private_deps =
452+
match package with
453+
| `Private -> true
454+
| _ -> false
455+
in
456+
let use_stdlib = s.use_stdlib in
457+
let+ libraries = resolve_plugins ~db ~allow_private_deps ~name:(snd name) s.plugins
435458
and+ theories =
436-
resolve_theories ~rocq_db ~allow_private_deps ~boot_id s.buildable.theories
437-
and+ boot = resolve_boot ~rocq_db boot_id in
459+
resolve_theories ~db ~rocq_db ~allow_private_deps ~boot_id s.theories
460+
and+ boot = resolve_boot ~db ~rocq_db boot_id in
438461
let theories = maybe_add_boot ~boot ~use_stdlib ~is_boot:s.boot theories in
439462
let map_error x =
440463
let human_readable_description () = Id.pp id in
441464
Resolve.push_stack_frame ~human_readable_description x
442465
in
443466
let theories = map_error theories in
444467
let libraries = map_error libraries in
445-
{ Dune.loc = s.buildable.loc
468+
let src_root =
469+
Either.map ~l:(fun dir -> Left dir) ~r:(fun _path -> Right []) path
470+
in
471+
{ Dune.loc = s.loc
446472
; boot_id
447473
; id
448474
; use_stdlib
449475
; implicit = s.boot
450-
; obj_root = dir
451-
; src_root = dir
476+
; obj_root = path
477+
; src_root
452478
; theories
453479
; libraries
454480
; theories_closure =
455481
lazy
456482
(Resolve.bind theories ~f:(fun theories ->
457483
List.map theories ~f:snd |> top_closure))
458-
; package = s.package
484+
; package
459485
}
460486
;;
461487

462488
module Input = struct
463-
type nonrec t = t * Lib.DB.t * Path.Build.t * Rocq_stanza.Theory.t
489+
type nonrec t =
490+
t * Lib.DB.t * (Path.Build.t * Rocq_stanza.Theory.t, Rocq_package.t) Either.t
464491

465-
let equal (rocq_db, ml_db, path, stanza) (rocq_db', ml_db', path', stanza') =
492+
let equal (rocq_db, ml_db, s) (rocq_db', ml_db', s') =
466493
phys_equal rocq_db rocq_db'
467494
&& phys_equal ml_db ml_db'
468-
&& Path.Build.equal path path'
469-
&& phys_equal stanza stanza'
495+
&&
496+
match s, s' with
497+
| Left (path, s), Left (path', s') ->
498+
Path.Build.equal path path' && phys_equal s s'
499+
| Right s, Right s' -> phys_equal s s'
500+
| _, _ -> false
470501
;;
471502

472503
let hash = Poly.hash
@@ -476,25 +507,41 @@ module DB = struct
476507
let memo =
477508
Memo.create
478509
"create-from-stanza"
479-
~human_readable_description:(fun (_, _, path, theory) ->
480-
Id.pp (Id.create ~path:(Path.build path) ~name:theory.name))
510+
~human_readable_description:(fun (_, _, theory) ->
511+
let path, name =
512+
match theory with
513+
| Left (dir, stanza) -> Path.build dir, stanza.name
514+
| Right p -> Rocq_package.path p, (Rocq_package.meta p).name
515+
in
516+
Id.pp (Id.create ~path ~name))
481517
~input:(module Input)
482-
create_from_stanza_impl
518+
create_from_rocq_package_impl
483519
;;
484520

485-
let create_from_stanza rocq_db db dir stanza =
486-
Memo.exec memo (rocq_db, db, dir, stanza)
521+
let create_from_rocq_package ~db rocq_db pkg = Memo.exec memo (rocq_db, db, Right pkg)
522+
523+
let create_from_stanza ~db ~dir rocq_db stanza =
524+
Memo.exec memo (rocq_db, db, Left (dir, stanza))
487525
;;
488526

489527
(* XXX: Memoize? This is pretty cheap so not sure worth the cost,
490528
still called too much I have observed, suspicious! *)
491-
let create_from_rocqpath ~boot_id cp =
529+
let create_from_rocqpath_legacy ~boot_id cp =
492530
let name = Rocq_path.name cp in
493531
let installed_root = Rocq_path.path cp in
494532
let implicit = Rocq_path.corelib cp in
495533
let vo = Rocq_path.vo cp in
496534
let id = Id.create ~path:installed_root ~name:(Loc.none, name) in
497-
Resolve.Memo.return { Legacy.boot_id; id; implicit; installed_root; vo }
535+
Resolve.Memo.return (Legacy { Legacy.boot_id; id; implicit; installed_root; vo })
536+
;;
537+
538+
let create_from_rocqpath ~db rocq_db = function
539+
| Rocq_path.Rocq_package pkg ->
540+
Memo.map (create_from_rocq_package ~db rocq_db pkg) ~f:(fun dune ->
541+
Resolve.return (Dune dune))
542+
| Rocq_path.Legacy _ as cp ->
543+
let boot_id = rocq_db.boot_id in
544+
create_from_rocqpath_legacy ~boot_id cp
498545
;;
499546

500547
module Resolve_result_no_redirect = struct
@@ -533,26 +580,22 @@ module DB = struct
533580

534581
(** Our final final resolve is used externally, and should return the
535582
library data found from the previous iterations. *)
536-
let resolve rocq_db (loc, name) =
583+
let resolve ~db rocq_db (loc, name) =
537584
match find rocq_db name with
538585
| Not_found -> Error.theory_not_found ~loc name
539586
| Found_stanza (db, dir, stanza) ->
540587
let open Memo.O in
541-
let+ theory = create_from_stanza rocq_db db dir stanza in
588+
let+ theory = create_from_stanza ~db ~dir rocq_db stanza in
542589
let open Resolve.O in
543590
let* (_ : (Loc.t * Lib.t) list) = theory.libraries in
544591
let+ (_ : (Loc.t * lib) list) = theory.theories in
545592
Dune theory
546-
| Found_path cp ->
547-
let open Resolve.Memo.O in
548-
let boot_id = rocq_db.boot_id in
549-
let+ theory = create_from_rocqpath ~boot_id cp in
550-
Legacy theory
593+
| Found_path cp -> create_from_rocqpath ~db rocq_db cp
551594
;;
552595

553-
let resolve_boot rocq_db =
596+
let resolve_boot ~db rocq_db =
554597
let boot_id = boot_library_id rocq_db in
555-
resolve_boot ~rocq_db boot_id
598+
resolve_boot ~db ~rocq_db boot_id
556599
;;
557600
end
558601

@@ -642,7 +685,7 @@ module DB = struct
642685
;;
643686

644687
(* Resolve helpers *)
645-
let find_many t theories = Resolve.Memo.List.map theories ~f:(resolve t)
688+
let find_many t theories ~db = Resolve.Memo.List.map theories ~f:(resolve ~db t)
646689
end
647690

648691
let theories_closure = function

src/dune_rules/rocq/rocq_lib.mli

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module Dune : sig
2121
type t
2222

2323
(** Source directory *)
24-
val src_root : t -> Path.Build.t
24+
val src_root : t -> (Path.Build.t, Path.t list) Either.t
2525

2626
(** ML libraries *)
2727
val libraries : t -> (Loc.t * Lib.t) list Resolve.t
@@ -42,7 +42,6 @@ module Legacy : sig
4242
In the case of a [Dune.t] lib, this list is obtained from the [src_root],
4343
via [Dir_contents.rocq], maybe we should move that function here and make
4444
it common.
45-
4645
*)
4746

4847
(** List of vo files *)
@@ -86,7 +85,12 @@ module DB : sig
8685
libraries are installed, we would infer the right amount of information. *)
8786
val create_from_rocqpaths : Rocq_path.t list -> t
8887

89-
val find_many : t -> (Loc.t * Rocq_lib_name.t) list -> lib list Resolve.Memo.t
90-
val resolve_boot : t -> (Loc.t * lib) option Resolve.Memo.t
91-
val resolve : t -> Loc.t * Rocq_lib_name.t -> lib Resolve.Memo.t
88+
val find_many
89+
: t
90+
-> (Loc.t * Rocq_lib_name.t) list
91+
-> db:Lib.DB.t
92+
-> lib list Resolve.Memo.t
93+
94+
val resolve_boot : db:Lib.DB.t -> t -> (Loc.t * lib) option Resolve.Memo.t
95+
val resolve : db:Lib.DB.t -> t -> Loc.t * Rocq_lib_name.t -> lib Resolve.Memo.t
9296
end

0 commit comments

Comments
 (0)