2016-12-02 13:54:32 +00:00
|
|
|
(** Build rules *)
|
|
|
|
|
2016-12-15 13:00:30 +00:00
|
|
|
open! Import
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2016-12-15 11:20:46 +00:00
|
|
|
type t
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-02-06 14:39:03 +00:00
|
|
|
(** {1 Setup} *)
|
|
|
|
|
|
|
|
(** {2 Creation} *)
|
2018-01-19 08:50:06 +00:00
|
|
|
|
2018-02-07 11:38:21 +00:00
|
|
|
type hook =
|
|
|
|
| Rule_started
|
|
|
|
| Rule_completed
|
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
(** Create a new build system. [file_tree] represent the source
|
|
|
|
tree. *)
|
2017-02-26 21:49:41 +00:00
|
|
|
val create
|
|
|
|
: contexts:Context.t list
|
|
|
|
-> file_tree:File_tree.t
|
2018-02-07 11:38:21 +00:00
|
|
|
-> hook:(hook -> unit)
|
2017-02-26 21:49:41 +00:00
|
|
|
-> t
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
type extra_sub_directories_to_keep =
|
|
|
|
| All
|
2018-04-23 05:08:09 +00:00
|
|
|
| These of String.Set.t
|
2018-01-19 08:50:06 +00:00
|
|
|
|
|
|
|
(** Set the rule generators callback. There must be one callback per
|
|
|
|
build context name.
|
|
|
|
|
|
|
|
Each callback is used to generate the rules for a given directory
|
|
|
|
in the corresponding build context. It receive the directory for
|
|
|
|
which to generate the rules and the splitted part of the path after
|
|
|
|
the build context. It must return an additional list of
|
|
|
|
sub-directories to keep. This is in addition to the ones that are
|
|
|
|
present in the source tree and the ones that already contain rules.
|
|
|
|
|
|
|
|
It is expected that [f] only generate rules whose targets are
|
|
|
|
descendant of [dir]. *)
|
2018-04-23 05:43:20 +00:00
|
|
|
val set_rule_generators : t -> (dir:Path.t -> string list -> extra_sub_directories_to_keep) String.Map.t -> unit
|
2018-01-19 08:50:06 +00:00
|
|
|
|
2018-02-06 14:39:03 +00:00
|
|
|
(** All other functions in this section must be called inside the rule generator
|
|
|
|
callback. *)
|
|
|
|
|
|
|
|
(** {2 Primitive for rule generations} *)
|
2018-01-19 08:50:06 +00:00
|
|
|
|
|
|
|
(** Add a rule to the system. This function must be called from the [gen_rules]
|
|
|
|
callback. All the target of the rule must be in the same directory.
|
|
|
|
|
|
|
|
Assuming that [gen_rules ~dir:a] calls [add_rule r] where [r.dir] is [Some b], one of
|
|
|
|
the following assumption must hold:
|
|
|
|
|
|
|
|
- [a] and [b] are the same
|
|
|
|
- [gen_rules ~dir:b] calls [load_dir ~dir:a]
|
|
|
|
|
|
|
|
The call to [load_dir ~dir:a] from [gen_rules ~dir:b] declares a directory dependency
|
|
|
|
from [b] to [a]. There must be no cyclic directory dependencies.
|
|
|
|
*)
|
|
|
|
val add_rule : t -> Build_interpret.Rule.t -> unit
|
|
|
|
|
2018-02-05 10:38:42 +00:00
|
|
|
(** [prefix_rules t prefix ~f] Runs [f] and adds [prefix] as a dependency to all
|
|
|
|
the rules generated by [f] *)
|
|
|
|
val prefix_rules : t -> (unit, unit) Build.t -> f:(unit -> 'a) -> 'a
|
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
(** [eval_glob t ~dir re ~f] returns the list of files in [dir] that matches [re] to
|
|
|
|
[f]. The list of files includes the list of targets. *)
|
|
|
|
val eval_glob : t -> dir:Path.t -> Re.re -> string list
|
|
|
|
|
|
|
|
(** Returns the set of targets in the given directory. *)
|
|
|
|
val targets_of : t -> dir:Path.t -> Path.Set.t
|
|
|
|
|
|
|
|
(** Load the rules for this directory. *)
|
|
|
|
val load_dir : t -> dir:Path.t -> unit
|
|
|
|
|
|
|
|
(** [on_load_dir ~dir ~f] remembers to run [f] when loading the rules for [dir]. *)
|
|
|
|
val on_load_dir : t -> dir:Path.t -> f:(unit -> unit) -> unit
|
|
|
|
|
|
|
|
(** Stamp file that depends on all files of [dir] with extension [ext]. *)
|
|
|
|
val stamp_file_for_files_of : t -> dir:Path.t -> ext:string -> Path.t
|
|
|
|
|
2018-03-15 19:56:03 +00:00
|
|
|
(** Sets the package this file is part of *)
|
|
|
|
val set_package : t -> Path.t -> Package.Name.t -> unit
|
|
|
|
|
2018-03-18 10:38:17 +00:00
|
|
|
(** Assuming [files] is the list of files in [_build/install] that
|
|
|
|
belong to package [pkg], [package_deps t pkg files] is the set of
|
|
|
|
direct package dependencies of [package]. *)
|
2018-03-15 19:50:02 +00:00
|
|
|
val package_deps
|
|
|
|
: t
|
2018-03-18 10:38:17 +00:00
|
|
|
-> Package.Name.t
|
2018-03-15 19:50:02 +00:00
|
|
|
-> Path.Set.t
|
|
|
|
-> (unit, Package.Name.Set.t) Build.t
|
|
|
|
|
2018-02-06 14:39:03 +00:00
|
|
|
(** {2 Aliases} *)
|
2018-01-19 08:50:06 +00:00
|
|
|
|
|
|
|
module Alias : sig
|
|
|
|
type build_system = t
|
|
|
|
type t
|
|
|
|
|
|
|
|
val pp : t Fmt.t
|
|
|
|
|
|
|
|
val make : string -> dir:Path.t -> t
|
|
|
|
|
|
|
|
val of_path : Path.t -> t
|
|
|
|
|
|
|
|
(** The following always holds:
|
|
|
|
|
|
|
|
{[
|
|
|
|
make (name t) ~dir:(dir t) = t
|
|
|
|
]}
|
|
|
|
*)
|
|
|
|
val name : t -> string
|
|
|
|
val dir : t -> Path.t
|
|
|
|
|
|
|
|
val fully_qualified_name : t -> Path.t
|
|
|
|
|
2018-02-16 09:22:28 +00:00
|
|
|
val default : dir:Path.t -> t
|
|
|
|
val runtest : dir:Path.t -> t
|
|
|
|
val install : dir:Path.t -> t
|
|
|
|
val doc : dir:Path.t -> t
|
|
|
|
val private_doc : dir:Path.t -> t
|
|
|
|
val lint : dir:Path.t -> t
|
2018-01-19 08:50:06 +00:00
|
|
|
|
2018-03-15 17:42:56 +00:00
|
|
|
(** Alias for all the files in [_build/install] that belong to this
|
|
|
|
package *)
|
2018-03-15 17:35:19 +00:00
|
|
|
val package_install : context:Context.t -> pkg:Package.Name.t -> t
|
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
(** Return the underlying stamp file *)
|
|
|
|
val stamp_file : t -> Path.t
|
|
|
|
|
|
|
|
(** [dep t = Build.path (stamp_file t)] *)
|
|
|
|
val dep : t -> ('a, 'a) Build.t
|
|
|
|
|
|
|
|
(** Implements [(alias_rec ...)] in dependency specification *)
|
|
|
|
val dep_rec
|
|
|
|
: t
|
|
|
|
-> loc:Loc.t
|
|
|
|
-> file_tree:File_tree.t
|
|
|
|
-> (unit, unit) Build.t
|
|
|
|
|
|
|
|
(** Implements [@alias] on the command line *)
|
|
|
|
val dep_rec_multi_contexts
|
|
|
|
: dir:Path.t
|
|
|
|
-> name:string
|
|
|
|
-> file_tree:File_tree.t
|
|
|
|
-> contexts:string list
|
|
|
|
-> (unit, unit) Build.t
|
|
|
|
|
2018-03-15 21:13:41 +00:00
|
|
|
(** [add_deps store alias ?dyn_deps deps] arrange things so that all
|
|
|
|
[dyn_deps] and [deps] are built as part of the build of alias
|
|
|
|
[alias]. *)
|
|
|
|
val add_deps
|
|
|
|
: build_system
|
|
|
|
-> t
|
2018-03-15 21:22:13 +00:00
|
|
|
-> ?dyn_deps:(unit, Path.Set.t) Build.t
|
|
|
|
-> Path.Set.t
|
2018-03-15 21:13:41 +00:00
|
|
|
-> unit
|
2018-01-19 08:50:06 +00:00
|
|
|
|
|
|
|
(** [add_action store alias ~stamp action] arrange things so that
|
|
|
|
[action] is executed as part of the build of alias
|
|
|
|
[alias]. [stamp] is any S-expression that is unique and
|
|
|
|
persistent S-expression.
|
|
|
|
*)
|
|
|
|
val add_action
|
|
|
|
: build_system
|
|
|
|
-> t
|
2018-03-15 10:19:20 +00:00
|
|
|
-> context:Context.t
|
2018-01-19 08:50:06 +00:00
|
|
|
-> ?locks:Path.t list
|
|
|
|
-> stamp:Sexp.t
|
|
|
|
-> (unit, Action.t) Build.t
|
|
|
|
-> unit
|
|
|
|
end with type build_system := t
|
|
|
|
|
|
|
|
(** {1 Building} *)
|
2017-02-23 10:03:35 +00:00
|
|
|
|
2018-02-06 14:39:03 +00:00
|
|
|
(** ALl the functions in this section must be called outside the rule generator
|
|
|
|
callback. *)
|
2016-12-02 13:54:32 +00:00
|
|
|
|
|
|
|
(** Do the actual build *)
|
2017-09-29 15:06:29 +00:00
|
|
|
val do_build
|
|
|
|
: t
|
2018-05-04 15:49:25 +00:00
|
|
|
-> request:(unit, 'a) Build.t
|
|
|
|
-> 'a Fiber.t
|
2016-12-02 13:54:32 +00:00
|
|
|
|
2018-02-06 14:39:03 +00:00
|
|
|
(** {2 Other queries} *)
|
2018-01-19 08:50:06 +00:00
|
|
|
|
2018-03-10 23:00:24 +00:00
|
|
|
(** File for the [(universe)] dependency. *)
|
|
|
|
val universe_file : Path.t
|
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
val is_target : t -> Path.t -> bool
|
|
|
|
|
2017-09-29 15:06:29 +00:00
|
|
|
(** Return all the library dependencies (as written by the user)
|
|
|
|
needed to build this request *)
|
|
|
|
val all_lib_deps
|
|
|
|
: t
|
|
|
|
-> request:(unit, unit) Build.t
|
|
|
|
-> Build.lib_deps Path.Map.t
|
2017-03-01 19:19:43 +00:00
|
|
|
|
2017-09-29 15:06:29 +00:00
|
|
|
(** Return all the library dependencies required to build this
|
|
|
|
request, by context name *)
|
|
|
|
val all_lib_deps_by_context
|
|
|
|
: t
|
|
|
|
-> request:(unit, unit) Build.t
|
2018-04-23 05:43:20 +00:00
|
|
|
-> Build.lib_deps String.Map.t
|
2017-04-25 15:22:17 +00:00
|
|
|
|
|
|
|
(** List of all buildable targets *)
|
|
|
|
val all_targets : t -> Path.t list
|
2017-05-18 18:05:01 +00:00
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
(** Return the list of files that were created in the source tree and
|
|
|
|
needs to be deleted *)
|
|
|
|
val files_in_source_tree_to_delete
|
|
|
|
: unit
|
|
|
|
-> Path.t list
|
|
|
|
|
2018-02-06 14:39:03 +00:00
|
|
|
(** {2 Build rules} *)
|
2018-01-19 08:50:06 +00:00
|
|
|
|
2017-05-18 18:05:01 +00:00
|
|
|
(** A fully built rule *)
|
|
|
|
module Rule : sig
|
|
|
|
module Id : sig
|
|
|
|
type t
|
|
|
|
val to_int : t -> int
|
2018-02-25 16:35:25 +00:00
|
|
|
val compare : t -> t -> Ordering.t
|
2017-05-18 18:05:01 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
type t =
|
|
|
|
{ id : Id.t
|
|
|
|
; deps : Path.Set.t
|
|
|
|
; targets : Path.Set.t
|
2017-05-27 23:48:48 +00:00
|
|
|
; context : Context.t option
|
2017-05-18 18:05:01 +00:00
|
|
|
; action : Action.t
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2017-05-18 23:16:48 +00:00
|
|
|
(** Return the list of rules used to build the given targets. If
|
|
|
|
[recursive] is [true], return all the rules needed to build the
|
|
|
|
given targets and their transitive dependencies. *)
|
|
|
|
val build_rules
|
2017-09-29 15:06:29 +00:00
|
|
|
: ?recursive:bool (* default false *)
|
|
|
|
-> t
|
|
|
|
-> request:(unit, unit) Build.t
|
2018-02-06 14:39:03 +00:00
|
|
|
-> Rule.t list Fiber.t
|
2017-05-26 10:32:32 +00:00
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
(** {1 Misc} *)
|
2017-08-04 07:59:35 +00:00
|
|
|
|
2018-01-19 08:50:06 +00:00
|
|
|
(** Dump various databases on disk *)
|
|
|
|
val finalize : t -> unit
|