Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a [coq.extraction] stanza #3299

Merged
merged 27 commits into from
Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
706cf31
[coq] Introduce a coq.extract stanza
rgrinberg Feb 25, 2020
5d5418f
[coq] Add support for libraries coq.extract
rgrinberg Mar 27, 2020
b7f1c0c
[coq] use lowercase names in extraction
rgrinberg Mar 27, 2020
7e1f5ee
[coq] Add external dep to coq.extract tests
rgrinberg Mar 27, 2020
da47a0d
[coq] Share common fields between extract and theory
rgrinberg Mar 27, 2020
cef9f7f
[coq] handle extract targets centrally
rgrinberg Mar 27, 2020
e0a5aed
[coq] Use DuneExtraction as the dummy wrapper name
rgrinberg Mar 27, 2020
0f14b16
Factor out flag handling
rgrinberg Mar 27, 2020
6b4847f
[coq] move bootstrap to own module
rgrinberg Mar 27, 2020
9c388ec
[coq] move stanzas to [Coq_stanza]
rgrinberg Mar 27, 2020
1cce500
[coq] document coq.extract
rgrinberg Mar 27, 2020
2dd4000
[coq] Introduce Coq.Context
rgrinberg Mar 27, 2020
04b9b19
[coq] Add coq flags to Context
rgrinberg Mar 27, 2020
991ed95
[coq] Add more fields to Coq_rules.Context
rgrinberg Mar 27, 2020
e32d2fd
[coq] treat extracted list of strings
rgrinberg Mar 28, 2020
10557f8
[coq] update docs
rgrinberg Mar 28, 2020
7ca5339
[coq] Move boot_type to context
rgrinberg Mar 28, 2020
4888857
[coq] little re-org
rgrinberg Mar 28, 2020
3a27436
[coq] Use correct dir for ml_target_names
rgrinberg Mar 28, 2020
9dac391
Simplify build_dir handling
rgrinberg Mar 28, 2020
4222b58
[coq] move source_rule to own function
rgrinberg Mar 28, 2020
8e0e8b0
[coq] improve coqdep errors
rgrinberg Mar 28, 2020
ee74014
[coq] run coqdep out of correct dir
rgrinberg Mar 28, 2020
e50324d
[coq] make coq.extract use coqdep
rgrinberg Mar 28, 2020
584d082
[coq] rename extract to extraction
rgrinberg Mar 28, 2020
9b11e6e
Update CHANGES
rgrinberg Mar 29, 2020
2ca3397
[coq] change dir of coqc depending on purpose
rgrinberg Mar 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ Unreleased

- Allow per-package `version` in generated `opam` files (#3287, @toots)

- [coq] Introduce the `coq.extraction` stanza. It can be used to extract OCaml
sources (#3299, fixes #2178, @rgrinberg)

2.4.0 (06/03/2020)
------------------

Expand Down
25 changes: 25 additions & 0 deletions doc/dune-files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,31 @@ which for each ``g_mod`` in ``<mlg_list>`` is equivalent to:
(deps (:mlg-file g_mod.mlg))
(action (run coqpp %{mlg-file})))

coq.extraction
--------------

Coq may be instructed to *extract* OCaml sources as part of the compilation
process. This is done using the ``coq.extraction`` stanza:

.. code:: lisp

(coq.extraction
(prelude <name>)
(extracted_modules <names>)
<optional-fields>)

- ``(prelude <name>)`` refers to the coq source that contains the extraction
commands.

- ``(extraced_modules <names>)`` is an exhaustive list of OCaml modules
extracted.

- ``<optional-fields>`` are ``flags``, ``theories``, and ``libraries``. All of
these fields have the same meaning as in the ``coq.theory`` stanza.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO it would be worth nothing that the extracted modules will become usable from a regular (library ,...) stanza; quite a few users of this feature will be new to Dune and this will not be obvious to them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. By the way, what do you think of introducing coq.rst for all coq related documentation? That page would include a tutorial style introduction and a reference of all the coq related stanzas.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍
It used to exist but was removed in the recent refactoring of the refman. But it would be great if it was reintroduced.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it used to be its own, self-contained section; but was removed in favor of merging into the general stanza file. Personally I think it makes more sense the old way, so I'm all for it.

Old chapter can be seen here https://github.com/ocaml/dune/blob/1.11.4/doc/coq.rst

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Was there a discussion regarding this change? I’d like to see the arguments for keeping everything in one place.

The extracted sources can then be used in ``executable`` or ``library`` stanzas
as any other sources.

.. _dune-workspace:

mdx (since 2.4)
Expand Down
2 changes: 2 additions & 0 deletions src/dune/build.ml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ module With_targets = struct
; targets : Path.Build.Set.t
}

let map_build t ~f = { t with build = f t.build }

let return x = { build = Pure x; targets = Path.Build.Set.empty }

let add t ~targets =
Expand Down
5 changes: 5 additions & 0 deletions src/dune/build.mli
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ open! Import
type 'a t

module With_targets : sig
type 'a build

type nonrec 'a t =
{ build : 'a t
; targets : Path.Build.Set.t
}

val map_build : 'a t -> f:('a build -> 'b build) -> 'b t

val return : 'a -> 'a t

val add : 'a t -> targets:Path.Build.t list -> 'a t
Expand Down Expand Up @@ -38,6 +42,7 @@ module With_targets : sig
val ( and+ ) : 'a t -> 'b t -> ('a * 'b) t
end
end
with type 'a build := 'a t

(** This function should be called before analysing build expressions using
[static_deps], [lib_deps] or [exec], which all require some file system
Expand Down
63 changes: 40 additions & 23 deletions src/dune/coq_lib.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module Error = struct
Error (User_error.E (User_error.make ?loc ?hints paragraphs))

let duplicate_theory_name theory =
let loc, name = theory.Dune_file.Coq.name in
let loc, name = theory.Coq_stanza.Theory.name in
let name = Coq_lib_name.to_string name in
make ~loc [ Pp.textf "Duplicate theory name: %s" name ]

Expand All @@ -56,7 +56,9 @@ module Error = struct
]

let duplicate_boot_lib ~loc boot_theory =
let name = Coq_lib_name.to_string (snd boot_theory.Dune_file.Coq.name) in
let name =
Coq_lib_name.to_string (snd boot_theory.Coq_stanza.Theory.name)
in
make ~loc [ Pp.textf "Cannot have more than one boot library: %s)" name ]

let cycle_found ~loc cycle =
Expand All @@ -77,15 +79,15 @@ module DB = struct

let boot_library { boot; _ } = boot

let create_from_stanza ((dir, s) : Path.Build.t * Dune_file.Coq.t) =
let create_from_stanza ((dir, s) : Path.Build.t * Coq_stanza.Theory.t) =
let name = snd s.name in
( name
, { name = s.name
; wrapper = Coq_lib_name.wrapper name
; obj_root = dir
; src_root = dir
; theories = s.theories
; libraries = s.libraries
; theories = s.buildable.theories
; libraries = s.buildable.libraries
; package = s.package
} )

Expand All @@ -98,11 +100,11 @@ module DB = struct
Result.ok_exn (Error.duplicate_theory_name w2)
in
let boot =
match List.find_all ~f:(fun (_, s) -> s.Dune_file.Coq.boot) sl with
match List.find_all ~f:(fun (_, s) -> s.Coq_stanza.Theory.boot) sl with
| [] -> None
| [ l ] -> Some ((snd l).loc, snd (create_from_stanza l))
| [ l ] -> Some ((snd l).buildable.loc, snd (create_from_stanza l))
| _ :: (_, s2) :: _ ->
Result.ok_exn (Error.duplicate_boot_lib ~loc:s2.loc s2)
Result.ok_exn (Error.duplicate_boot_lib ~loc:s2.buildable.loc s2)
in
{ boot; libs }

Expand All @@ -119,26 +121,41 @@ module DB = struct

module Coq_lib_closure = Top_closure.Make (String.Set) (Or_exn)

let requires db t : lib list Or_exn.t =
let theories =
match db.boot with
| None -> t.theories
(* XXX: Note that this means that we will prefix Coq with -Q, not sure we
want to do that (yet), but seems like good practice. *)
| Some (loc, stdlib) -> (loc, snd stdlib.name) :: t.theories
in
let add_boot db theories =
match db.boot with
| None -> theories
(* XXX: Note that this means that we will prefix Coq with -Q, not sure we
want to do that (yet), but seems like good practice. *)
| Some (loc, stdlib) -> (loc, snd stdlib.name) :: theories

let top_closure db theories ~allow_private_deps ~loc =
let open Result.O in
let allow_private_deps = Option.is_none t.package in
let* theories =
Result.List.map ~f:(resolve ~allow_private_deps db) theories
add_boot db theories
|> Result.List.map ~f:(resolve ~allow_private_deps db)
in
let key t = Coq_lib_name.to_string (snd t.name) in
let deps t =
let key (t : lib) = Coq_lib_name.to_string (snd t.name) in
let deps (t : lib) =
Result.List.map ~f:(resolve ~allow_private_deps db) t.theories
in
Result.bind (Coq_lib_closure.top_closure theories ~key ~deps) ~f:(function
| Ok libs -> Ok libs
| Error cycle -> Error.cycle_found ~loc:(location t) cycle)
match Coq_lib_closure.top_closure theories ~key ~deps with
| Ok (Ok s) -> Ok s
| Ok (Error cycle) -> Error.cycle_found ~loc cycle
| Error exn -> Error exn

let requires db (t : lib) : lib list Or_exn.t =
let allow_private_deps = Option.is_none t.package in
let loc = location t in
top_closure db t.theories ~loc ~allow_private_deps

let requires_for_user_written db = function
| [] -> Ok []
| start :: xs as theories ->
let loc =
let stop = Option.value (List.last xs) ~default:start in
Loc.span (fst start) (fst stop)
in
top_closure db theories ~loc ~allow_private_deps:true

let resolve db l = resolve db l
end
6 changes: 5 additions & 1 deletion src/dune/coq_lib.mli
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ module DB : sig

type t

val create_from_coqlib_stanzas : (Path.Build.t * Dune_file.Coq.t) list -> t
val create_from_coqlib_stanzas :
(Path.Build.t * Coq_stanza.Theory.t) list -> t

val find_many : t -> loc:Loc.t -> Coq_lib_name.t list -> lib list Or_exn.t

Expand All @@ -35,5 +36,8 @@ module DB : sig

(** Return the list of dependencies needed for compiling this library *)
val requires : t -> lib -> lib list Or_exn.t

val requires_for_user_written :
t -> (Loc.t * Coq_lib_name.t) list -> lib list Or_exn.t
end
with type lib := t
4 changes: 4 additions & 0 deletions src/dune/coq_module.ml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ module Name = struct

let compare = String.compare

let equal = String.equal

let to_dyn s = Dyn.String s

let to_string s = s
end

(* We keep prefix and name separated as the handling of `From Foo Require Bar.`
Expand Down
6 changes: 5 additions & 1 deletion src/dune/coq_module.mli
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ module Name : sig

val compare : t -> t -> Ordering.t

val equal : t -> t -> bool

val to_dyn : t -> Dyn.t

val to_string : t -> string
end

type t
Expand All @@ -30,7 +34,7 @@ val source : t -> Path.Build.t

val prefix : t -> string list

val name : t -> string
val name : t -> Name.t

val dep_file : obj_dir:Path.Build.t -> t -> Path.Build.t

Expand Down
Loading