514 lines
18 KiB
OCaml
514 lines
18 KiB
OCaml
(***********************************************************************)
|
|
(* ocamlbuild *)
|
|
(* *)
|
|
(* Nicolas Pouillard, Berke Durak, projet Gallium, INRIA Rocquencourt *)
|
|
(* *)
|
|
(* Copyright 2007 Institut National de Recherche en Informatique et *)
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
(* under the terms of the Q Public License version 1.0. *)
|
|
(* *)
|
|
(***********************************************************************)
|
|
|
|
(* $Id$ *)
|
|
(* Original author: Nicolas Pouillard *)
|
|
(** This module contains all module signatures that the user
|
|
could use to build an ocamlbuild plugin. *)
|
|
|
|
module type OrderedTypePrintable = sig
|
|
type t
|
|
val compare : t -> t -> int
|
|
val print : Format.formatter -> t -> unit
|
|
end
|
|
|
|
module type SET = sig
|
|
include Set.S
|
|
val find : (elt -> bool) -> t -> elt
|
|
val map : (elt -> elt) -> t -> t
|
|
val of_list : elt list -> t
|
|
val print : Format.formatter -> t -> unit
|
|
end
|
|
|
|
module type LIST = sig
|
|
(* Added functions *)
|
|
val print : (Format.formatter -> 'a -> 'b) -> Format.formatter -> 'a list -> unit
|
|
val filter_opt : ('a -> 'b option) -> 'a list -> 'b list
|
|
val union : 'a list -> 'a list -> 'a list
|
|
|
|
(* Original functions *)
|
|
include Std_signatures.LIST
|
|
end
|
|
|
|
module type STRING = sig
|
|
val print : Format.formatter -> string -> unit
|
|
val chomp : string -> string
|
|
|
|
(** [before s n] returns the substring of all characters of [s]
|
|
that precede position [n] (excluding the character at
|
|
position [n]).
|
|
This is the same function as {!Str.string_before}. *)
|
|
val before : string -> int -> string
|
|
|
|
(** [after s n] returns the substring of all characters of [s]
|
|
that follow position [n] (including the character at
|
|
position [n]).
|
|
This is the same function as {!Str.string_after}. *)
|
|
val after : string -> int -> string
|
|
|
|
val first_chars : string -> int -> string
|
|
(** [first_chars s n] returns the first [n] characters of [s].
|
|
This is the same function as {!before} ant {!Str.first_chars}. *)
|
|
|
|
val last_chars : string -> int -> string
|
|
(** [last_chars s n] returns the last [n] characters of [s].
|
|
This is the same function as {!Str.last_chars}. *)
|
|
|
|
val eq_sub_strings : string -> int -> string -> int -> int -> bool
|
|
|
|
(** [is_prefix u v] is v a prefix of u ? *)
|
|
val is_prefix : string -> string -> bool
|
|
(** [is_suffix u v] : is v a suffix of u ? *)
|
|
val is_suffix : string -> string -> bool
|
|
|
|
(** [contains_string s1 p2 s2] Search in [s1] starting from [p1] if it
|
|
contains the [s2] string. Returns [Some position] where [position]
|
|
is the begining of the string [s2] in [s1], [None] otherwise. *)
|
|
val contains_string : string -> int -> string -> int option
|
|
|
|
(** [subst patt repl text] *)
|
|
val subst : string -> string -> string -> string
|
|
|
|
(** [tr patt repl text] *)
|
|
val tr : char -> char -> string -> string
|
|
|
|
val rev : string -> string
|
|
|
|
(** The following are original functions from the [String] module. *)
|
|
include Std_signatures.STRING
|
|
end
|
|
|
|
module type TAGS = sig
|
|
include Set.S with type elt = string
|
|
val of_list : string list -> t
|
|
val print : Format.formatter -> t -> unit
|
|
val does_match : t -> t -> bool
|
|
module Operators : sig
|
|
val ( ++ ) : t -> elt -> t
|
|
val ( -- ) : t -> elt -> t
|
|
val ( +++ ) : t -> elt option -> t
|
|
val ( --- ) : t -> elt option -> t
|
|
end
|
|
end
|
|
|
|
module type PATHNAME = sig
|
|
type t = string
|
|
val concat : t -> t -> t
|
|
val compare : t -> t -> int
|
|
val equal : t -> t -> bool
|
|
val exists : t -> bool
|
|
val mk : string -> t
|
|
val define_context : string -> string list -> unit
|
|
val include_dirs_of : string -> string list
|
|
val copy : t -> t -> unit
|
|
val to_string : t -> string
|
|
val print : Format.formatter -> t -> unit
|
|
val current_dir_name : t
|
|
val parent_dir_name : t
|
|
val read : t -> string
|
|
val same_contents : t -> t -> bool
|
|
val basename : t -> t
|
|
val dirname : t -> t
|
|
val is_relative : t -> bool
|
|
val readlink : t -> t
|
|
val readdir : t -> t array
|
|
val is_link : t -> bool
|
|
val is_directory : t -> bool
|
|
|
|
val add_extension : string -> t -> t
|
|
val check_extension : t -> string -> bool
|
|
|
|
val get_extension : t -> string
|
|
val remove_extension : t -> t
|
|
val update_extension : string -> t -> t
|
|
|
|
val get_extensions : t -> string
|
|
val remove_extensions : t -> t
|
|
val update_extensions : string -> t -> t
|
|
|
|
val print_path_list : Format.formatter -> t list -> unit
|
|
val pwd : t
|
|
val parent : t -> t
|
|
(** [is_prefix x y] is [x] a pathname prefix of [y] *)
|
|
val is_prefix : t -> t -> bool
|
|
val is_implicit : t -> bool
|
|
module Operators : sig
|
|
val ( / ) : t -> t -> t
|
|
val ( -.- ) : t -> string -> t
|
|
end
|
|
end
|
|
|
|
(** Provides an abstract type for easily building complex shell commands without making
|
|
quotation mistakes. *)
|
|
module type COMMAND = sig
|
|
type tags
|
|
|
|
(** The type [t] is basically a sequence of command specifications. This avoids having to
|
|
flatten lists of lists. *)
|
|
type t = Seq of t list | Cmd of spec | Nop
|
|
|
|
(** The type for command specifications. *)
|
|
and spec =
|
|
| N (** No operation. *)
|
|
| S of spec list (** A sequence. This gets flattened in the last stages *)
|
|
| A of string (** An atom. *)
|
|
| P of string (** A pathname. *)
|
|
| Px of string (** A pathname, that will also be given to the call_with_target hook. *)
|
|
| Sh of string (** A bit of raw shell code, that will not be escaped. *)
|
|
| T of tags (** A set of tags, that describe properties and some semantics
|
|
information about the command, afterward these tags will be
|
|
replaced by command [spec]s (flags for instance). *)
|
|
| V of string (** A virtual command, that will be resolved at execution using [resolve_virtuals] *)
|
|
| Quote of spec (** A string that should be quoted like a filename but isn't really one. *)
|
|
|
|
(*type v = [ `Seq of v list | `Cmd of vspec | `Nop ]
|
|
and vspec =
|
|
[ `N
|
|
| `S of vspec list
|
|
| `A of string
|
|
| `P of string (* Pathname.t *)
|
|
| `Px of string (* Pathname.t *)
|
|
| `Sh of string
|
|
| `Quote of vspec ]
|
|
|
|
val spec_of_vspec : vspec -> spec
|
|
val vspec_of_spec : spec -> vspec
|
|
val t_of_v : v -> t
|
|
val v_of_t : t -> v*)
|
|
|
|
(** Will convert a string list to a list of atoms by adding [A] constructors. *)
|
|
val atomize : string list -> spec
|
|
|
|
(** Will convert a string list to a list of paths by adding [P] constructors. *)
|
|
val atomize_paths : string list -> spec
|
|
|
|
(** Run the command. *)
|
|
val execute : ?quiet:bool -> ?pretend:bool -> t -> unit
|
|
|
|
(** Run the commands in the given list, if possible in parallel.
|
|
See the module [Executor]. *)
|
|
val execute_many : ?quiet:bool -> ?pretend:bool -> t list -> (bool list * exn) option
|
|
|
|
(** [setup_virtual_command_solver virtual_command solver]
|
|
the given solver can raise Not_found if it fails to find a valid
|
|
command for this virtual command. *)
|
|
val setup_virtual_command_solver : string -> (unit -> spec) -> unit
|
|
|
|
(** Search the given command in the command path and return its absolute
|
|
pathname. *)
|
|
val search_in_path : string -> string
|
|
|
|
(** Simplify a command by flattening the sequences and resolving the tags
|
|
into command-line options. *)
|
|
val reduce : spec -> spec
|
|
|
|
(** Print a command. *)
|
|
val print : Format.formatter -> t -> unit
|
|
|
|
(** Convert a command to a string. *)
|
|
val to_string : t -> string
|
|
|
|
(** Build a string representation of a command that can be passed to the
|
|
system calls. *)
|
|
val string_of_command_spec : spec -> string
|
|
end
|
|
|
|
(** A self-contained module implementing extended shell glob patterns who have an expressive power
|
|
equal to boolean combinations of regular expressions. *)
|
|
module type GLOB = sig
|
|
|
|
(** A globber is a boolean combination of basic expressions indented to work on
|
|
pathnames. Known operators
|
|
are [or], [and] and [not], which may also be written [|], [&] and [~]. There are
|
|
also constants [true] and [false] (or [1] and [0]). Expression can be grouped
|
|
using parentheses.
|
|
- [true] matches anything,
|
|
- [false] matches nothing,
|
|
- {i basic} [or] {i basic} matches strings matching either one of the basic expressions,
|
|
- {i basic} [and] {i basic} matches strings matching both basic expressions,
|
|
- not {i basic} matches string that don't match the basic expression,
|
|
- {i basic} matches strings that match the basic expression.
|
|
|
|
A basic expression can be a constant string enclosed in double quotes, in which
|
|
double quotes must be preceded by backslashes, or a glob pattern enclosed between a [<] and a [>],
|
|
- ["]{i string}["] matches the literal string {i string},
|
|
- [<]{i glob}[>] matches the glob pattern {i glob}.
|
|
|
|
A glob pattern is an anchored regular expression in a shell-like syntax. Most characters stand for themselves.
|
|
Character ranges are given in usual shell syntax between brackets. The star [*] stands for any sequence of
|
|
characters. The joker '?' stands for exactly one, unspecified character. Alternation is achieved using braces [{].
|
|
- {i glob1}{i glob2} matches strings who have a prefix matching {i glob1} and the corresponding suffix
|
|
matching {i glob2}.
|
|
- [a] matches the string consisting of the single letter [a].
|
|
- [{]{i glob1},{i glob2}[}] matches strings matching {i glob1} or {i glob2}.
|
|
- [*] matches all strings, including the empty one.
|
|
- [?] matches strings of length 1.
|
|
- [\[]{i c1}-{i c2}{i c3}-{i c4}...[\]] matches characters in the range {i c1} to {i c2} inclusive,
|
|
or in the range {i c3} to {i c4} inclusive. For instance [\[a-fA-F0-9\]] matches hexadecimal digits.
|
|
To match the dash, put it at the end.
|
|
*)
|
|
|
|
(** The type representing globbers. Do not attempt to compare them, as they get on-the-fly optimizations. *)
|
|
type globber
|
|
|
|
(** [parse ~dir pattern] will parse the globber pattern [pattern], optionally prefixing its patterns with [dir]. *)
|
|
val parse : ?dir:string -> string -> globber
|
|
|
|
(** A descriptive exception raised when an invalid glob pattern description is given. *)
|
|
exception Parse_error of string
|
|
|
|
(** [eval g u] returns [true] if and only if the string [u] matches the given glob expression. Avoid reparsing
|
|
the same pattern, since the automaton implementing the pattern is optimized on the fly. The first few evaluations
|
|
are done using a time-inefficient but memory-efficient algorithm. It then compiles the pattern into an efficient
|
|
but more memory-hungry data structure. *)
|
|
val eval : globber -> string -> bool
|
|
end
|
|
|
|
(** Module for modulating the logging output with the logging level. *)
|
|
module type LOG = sig
|
|
(** Current logging (debugging) level. *)
|
|
val level : int ref
|
|
|
|
(** [dprintf level fmt args...] formats the logging information [fmt]
|
|
with the arguments [args...] on the logging output if the logging
|
|
level is greater than or equal to [level]. The default level is 1.
|
|
More obscure debugging information should have a higher logging
|
|
level. Youre formats are wrapped inside these two formats
|
|
["@\[<2>"] and ["@\]@."]. *)
|
|
val dprintf : int -> ('a, Format.formatter, unit) format -> 'a
|
|
|
|
(** Equivalent to calling [dprintf] with a level [< 0]. *)
|
|
val eprintf : ('a, Format.formatter, unit) format -> 'a
|
|
|
|
(** Same as dprintf but without the format wrapping. *)
|
|
val raw_dprintf : int -> ('a, Format.formatter, unit) format -> 'a
|
|
end
|
|
|
|
module type OUTCOME = sig
|
|
type ('a,'b) t =
|
|
| Good of 'a
|
|
| Bad of 'b
|
|
|
|
val wrap : ('a -> 'b) -> 'a -> ('b, exn) t
|
|
val ignore_good : ('a, exn) t -> unit
|
|
val good : ('a, exn) t -> 'a
|
|
end
|
|
|
|
module type MISC = sig
|
|
val opt_print :
|
|
(Format.formatter -> 'a -> unit) -> Format.formatter -> 'a option -> unit
|
|
val the : 'a option -> 'a
|
|
val getenv : ?default:string -> string -> string
|
|
val with_input_file : ?bin:bool -> string -> (in_channel -> 'a) -> 'a
|
|
val with_output_file : ?bin:bool -> string -> (out_channel -> 'a) -> 'a
|
|
val with_temp_file : string -> string -> (string -> 'a) -> 'a
|
|
val read_file : string -> string
|
|
val copy_chan : in_channel -> out_channel -> unit
|
|
val copy_file : string -> string -> unit
|
|
val print_string_list : Format.formatter -> string list -> unit
|
|
val ( !* ) : 'a Lazy.t -> 'a
|
|
|
|
(** [r @:= l] is equivalent to [r := !r @ l] *)
|
|
val ( @:= ) : 'a list ref -> 'a list -> unit
|
|
|
|
val memo : ('a -> 'b) -> ('a -> 'b)
|
|
end
|
|
|
|
module type OPTIONS = sig
|
|
type command_spec
|
|
|
|
val build_dir : string ref
|
|
val include_dirs : string list ref
|
|
val exclude_dirs : string list ref
|
|
val nothing_should_be_rebuilt : bool ref
|
|
val ocamlc : command_spec ref
|
|
val ocamlopt : command_spec ref
|
|
val ocamldep : command_spec ref
|
|
val ocamldoc : command_spec ref
|
|
val ocamlyacc : command_spec ref
|
|
val ocamllex : command_spec ref
|
|
val ocamlrun : command_spec ref
|
|
val ocamlmklib : command_spec ref
|
|
val ocamlmktop : command_spec ref
|
|
val hygiene : bool ref
|
|
val sterilize : bool ref
|
|
val sterilization_script : string ref
|
|
val ignore_auto : bool ref
|
|
val plugin : bool ref
|
|
val just_plugin : bool ref
|
|
val native_plugin : bool ref
|
|
val make_links : bool ref
|
|
val nostdlib : bool ref
|
|
val program_to_execute : bool ref
|
|
val must_clean : bool ref
|
|
val internal_log_file : string option ref
|
|
val use_menhir : bool ref
|
|
|
|
val targets : string list ref
|
|
val ocaml_libs : string list ref
|
|
val ocaml_cflags : string list ref
|
|
val ocaml_lflags : string list ref
|
|
val ocaml_ppflags : string list ref
|
|
val ocaml_yaccflags : string list ref
|
|
val ocaml_lexflags : string list ref
|
|
val program_args : string list ref
|
|
val ignore_list : string list ref
|
|
val tags : string list ref
|
|
|
|
val ext_obj : string ref
|
|
val ext_lib : string ref
|
|
val ext_dll : string ref
|
|
end
|
|
|
|
module type ARCH = sig
|
|
type 'a arch = private
|
|
| Arch_dir of string * 'a * 'a arch list
|
|
| Arch_dir_pack of string * 'a * 'a arch list
|
|
| Arch_file of string * 'a
|
|
|
|
val dir : string -> unit arch list -> unit arch
|
|
val dir_pack : string -> unit arch list -> unit arch
|
|
val file : string -> unit arch
|
|
|
|
type info = private {
|
|
current_path : string;
|
|
include_dirs : string list;
|
|
for_pack : string;
|
|
}
|
|
|
|
val annotate : 'a arch -> info arch
|
|
|
|
val print : (Format.formatter -> 'a -> unit) -> Format.formatter -> 'a arch -> unit
|
|
val print_include_dirs : Format.formatter -> string list -> unit
|
|
val print_info : Format.formatter -> info -> unit
|
|
|
|
val iter_info : ('a -> unit) -> 'a arch -> unit
|
|
val fold_info : ('a -> 'b -> 'b) -> 'a arch -> 'b -> 'b
|
|
|
|
val iter_include_dirs : info arch -> (string -> unit) -> unit
|
|
|
|
val mk_tables :
|
|
info arch -> (string, string list) Hashtbl.t * (string, string) Hashtbl.t
|
|
val print_table :
|
|
(Format.formatter -> 'a -> unit) -> Format.formatter -> (string, 'a) Hashtbl.t -> unit
|
|
end
|
|
|
|
(** This module contains the functions and values that can be used by plugins. *)
|
|
module type PLUGIN = sig
|
|
module Pathname : PATHNAME
|
|
module Tags : TAGS
|
|
module Command : COMMAND with type tags = Tags.t
|
|
module Outcome : OUTCOME
|
|
module String : STRING
|
|
module List : LIST
|
|
module StringSet : Set.S with type elt = String.t
|
|
module Options : OPTIONS with type command_spec = Command.spec
|
|
module Arch : ARCH
|
|
include MISC
|
|
|
|
val ( / ) : Pathname.t -> Pathname.t -> Pathname.t
|
|
val ( -.- ) : Pathname.t -> string -> Pathname.t
|
|
|
|
val ( ++ ) : Tags.t -> Tags.elt -> Tags.t
|
|
val ( -- ) : Tags.t -> Tags.elt -> Tags.t
|
|
val ( +++ ) : Tags.t -> Tags.elt option -> Tags.t
|
|
val ( --- ) : Tags.t -> Tags.elt option -> Tags.t
|
|
|
|
type env = Pathname.t -> Pathname.t
|
|
type builder = Pathname.t list list -> (Pathname.t, exn) Outcome.t list
|
|
type action = env -> builder -> Command.t
|
|
|
|
val rule : string ->
|
|
?tags:string list ->
|
|
?prods:string list ->
|
|
?deps:string list ->
|
|
?prod:string ->
|
|
?dep:string ->
|
|
?insert:[`top | `before of string | `after of string | `bottom] ->
|
|
action -> unit
|
|
|
|
val file_rule : string ->
|
|
?tags:string list ->
|
|
prod:string ->
|
|
?deps:string list ->
|
|
?dep:string ->
|
|
?insert:[`top | `before of string | `after of string | `bottom] ->
|
|
cache:(env -> string) ->
|
|
(env -> out_channel -> unit) -> unit
|
|
|
|
val custom_rule : string ->
|
|
?tags:string list ->
|
|
?prods:string list ->
|
|
?prod:string ->
|
|
?deps:string list ->
|
|
?dep:string ->
|
|
?insert:[`top | `before of string | `after of string | `bottom] ->
|
|
cache:(env -> string) ->
|
|
(env -> cached:bool -> unit) -> unit
|
|
|
|
(** [copy_rule name ?insert source destination] *)
|
|
val copy_rule : string ->
|
|
?insert:[`top | `before of string | `after of string | `bottom] ->
|
|
string -> string -> unit
|
|
|
|
(** [dep tags deps] Will build [deps] when [tags] will be activated. *)
|
|
val dep : Tags.elt list -> Pathname.t list -> unit
|
|
|
|
val flag : Tags.elt list -> Command.spec -> unit
|
|
|
|
(** [non_dependency module_path module_name]
|
|
Example:
|
|
[non_dependency "foo/bar/baz" "Goo"]
|
|
Says that the module [Baz] in the file [foo/bar/baz.*] does not depend on [Goo]. *)
|
|
val non_dependency : Pathname.t -> string -> unit
|
|
|
|
(** [use_lib module_path lib_path]*)
|
|
val use_lib : Pathname.t -> Pathname.t -> unit
|
|
|
|
val expand_module :
|
|
Pathname.t list -> Pathname.t -> string list -> Pathname.t list
|
|
|
|
val string_list_of_file : Pathname.t -> string list
|
|
|
|
val module_name_of_pathname : Pathname.t -> string
|
|
|
|
val mv : Pathname.t -> Pathname.t -> Command.t
|
|
val cp : Pathname.t -> Pathname.t -> Command.t
|
|
val ln_f : Pathname.t -> Pathname.t -> Command.t
|
|
val ln_s : Pathname.t -> Pathname.t -> Command.t
|
|
val rm_f : Pathname.t -> Command.t
|
|
val touch : Pathname.t -> Command.t
|
|
val chmod : Command.spec -> Pathname.t -> Command.t
|
|
val cmp : Pathname.t -> Pathname.t -> Command.t
|
|
|
|
(** [hide_package_contents pack_name]
|
|
Don't treat the given package as an open package.
|
|
So a module will not be replaced during linking by
|
|
this package even if it contains that module. *)
|
|
val hide_package_contents : string -> unit
|
|
|
|
val tag_file : Pathname.t -> Tags.elt list -> unit
|
|
|
|
val tag_any : Tags.elt list -> unit
|
|
|
|
val tags_of_pathname : Pathname.t -> Tags.t
|
|
|
|
type hook =
|
|
| Before_hygiene
|
|
| After_hygiene
|
|
| Before_options
|
|
| After_options
|
|
| Before_rules
|
|
| After_rules
|
|
|
|
val dispatch : (hook -> unit) -> unit
|
|
end
|