summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Clerc <xavier.clerc@inria.fr>2010-01-22 14:36:57 +0000
committerXavier Clerc <xavier.clerc@inria.fr>2010-01-22 14:36:57 +0000
commitbcdf4082cf3c3d2fc0ba5c4b10ee9d192b22c066 (patch)
treec5f7f8c99991fcf2b4df40b4debe9733f3883390
parent04b1656222698bd7e92f213e9a718b7a4185643a (diff)
Support for parametrized tags (N. Pouillard et al.)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@9548 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--ocamlbuild/_tags2
-rw-r--r--ocamlbuild/command.ml4
-rw-r--r--ocamlbuild/command.mli2
-rw-r--r--ocamlbuild/configuration.ml29
-rw-r--r--ocamlbuild/configuration.mli5
-rw-r--r--ocamlbuild/flags.ml10
-rw-r--r--ocamlbuild/flags.mli2
-rw-r--r--ocamlbuild/lexers.mli10
-rw-r--r--ocamlbuild/lexers.mll30
-rw-r--r--ocamlbuild/main.ml2
-rw-r--r--ocamlbuild/ocaml_compiler.ml22
-rw-r--r--ocamlbuild/ocaml_specific.ml15
-rw-r--r--ocamlbuild/ocaml_tools.ml31
-rw-r--r--ocamlbuild/ocaml_utils.ml5
-rw-r--r--ocamlbuild/ocaml_utils.mli2
-rw-r--r--ocamlbuild/ocamlbuild_pack.mlpack1
-rw-r--r--ocamlbuild/ocamlbuild_plugin.ml3
-rw-r--r--ocamlbuild/ocamlbuild_unix_plugin.ml3
-rw-r--r--ocamlbuild/signatures.mli24
-rwxr-xr-xocamlbuild/start.sh8
-rw-r--r--ocamlbuild/tools.ml1
-rw-r--r--ocamlbuild/tools.mli1
22 files changed, 135 insertions, 77 deletions
diff --git a/ocamlbuild/_tags b/ocamlbuild/_tags
index d0d8028ae..48081d073 100644
--- a/ocamlbuild/_tags
+++ b/ocamlbuild/_tags
@@ -6,5 +6,5 @@ true: debug
<*.byte> or <*.native> or <*.top>: use_unix
"ocamlbuildlight.byte": -use_unix
<*.cmx>: for-pack(Ocamlbuild_pack)
-<{ocamlbuild_{pack,plugin},my_unix_with_unix,ppcache,executor}{,.p}.cmx>: -for-pack(Ocamlbuild_pack)
+<{ocamlbuild_{pack,unix_plugin,plugin,executor},ppcache}{,.p}.cmx>: -for-pack(Ocamlbuild_pack)
"doc": not_hygienic
diff --git a/ocamlbuild/command.ml b/ocamlbuild/command.ml
index 2653116ec..b5488eb5f 100644
--- a/ocamlbuild/command.ml
+++ b/ocamlbuild/command.ml
@@ -365,6 +365,10 @@ let set_deps_of_tags tags deps =
let dep tags deps = set_deps_of_tags (Tags.of_list tags) deps
+let pdep tags ptag deps =
+ Param_tags.declare ptag
+ (fun param -> dep (Param_tags.make ptag param :: tags) (deps param))
+
(*
let to_string_for_digest x =
let rec cmd_of_spec =
diff --git a/ocamlbuild/command.mli b/ocamlbuild/command.mli
index 337762ba8..0cdc602c8 100644
--- a/ocamlbuild/command.mli
+++ b/ocamlbuild/command.mli
@@ -42,3 +42,5 @@ val deps_of_tags : Tags.t -> pathname list
(** [dep tags deps] Will build [deps] when [tags] will be activated. *)
val dep : Tags.elt list -> pathname list -> unit
+
+val pdep : Tags.elt list -> Tags.elt -> (string -> pathname list) -> unit
diff --git a/ocamlbuild/configuration.ml b/ocamlbuild/configuration.ml
index c4903caea..23e95963e 100644
--- a/ocamlbuild/configuration.ml
+++ b/ocamlbuild/configuration.ml
@@ -15,15 +15,21 @@ open My_std
open Log
open Lexers
-type flag_list = (string * string) list
-
type t = Lexers.conf
+let acknowledge_config config =
+ List.iter
+ (fun (_, config) -> List.iter Param_tags.acknowledge config.plus_tags)
+ config
+
let cache = Hashtbl.create 107
let (configs, add_config) =
let configs = ref [] in
(fun () -> !configs),
- (fun config -> configs := config :: !configs; Hashtbl.clear cache)
+ (fun config ->
+ acknowledge_config config;
+ configs := config :: !configs;
+ Hashtbl.clear cache)
let parse_string s =
let conf = Lexers.conf_lines None 1 (Printf.sprintf "string: %S" s) (Lexing.from_string s) in
@@ -38,28 +44,21 @@ let parse_file ?dir file =
let key_match = Glob.eval
let apply_config s (config : t) init =
- List.fold_left begin fun (tags, flags as acc) (key, v) ->
+ List.fold_left begin fun tags (key, v) ->
if key_match key s then
- (List.fold_right Tags.add v.plus_tags (List.fold_right Tags.remove v.minus_tags tags),
- List.fold_right Flags.add v.plus_flags (List.fold_right Flags.remove v.minus_flags flags))
- else acc
+ List.fold_right Tags.add v.plus_tags (List.fold_right Tags.remove v.minus_tags tags)
+ else tags
end init config
-let apply_configs s =
- let (tags, flags) =
- List.fold_right (apply_config s) (configs ()) (Tags.empty, [])
- in (tags, Flags.to_spec flags)
+let apply_configs s = List.fold_right (apply_config s) (configs ()) Tags.empty
-let tags_and_flags_of_filename s =
+let tags_of_filename s =
try Hashtbl.find cache s
with Not_found ->
let res = apply_configs s in
let () = Hashtbl.replace cache s res in
res
-let tags_of_filename x = fst (tags_and_flags_of_filename x)
-let flags_of_filename x = snd (tags_and_flags_of_filename x)
-
let has_tag tag = Tags.mem tag (tags_of_filename "")
let tag_file file tags =
diff --git a/ocamlbuild/configuration.mli b/ocamlbuild/configuration.mli
index 8ee2f42bb..745dcc269 100644
--- a/ocamlbuild/configuration.mli
+++ b/ocamlbuild/configuration.mli
@@ -15,8 +15,6 @@
(** Handles the "_tags" file mechanism. *)
-type flag_list = (string * string) list
-
(** Incorporate a newline-separated configuration string into the current configuration.
Will usually raising an [Invalid_arg] with an appropriately explicit message in case of error. *)
val parse_string : string -> unit
@@ -28,9 +26,6 @@ val parse_file : ?dir:string -> string -> unit
(** Return the set of tags that apply to a given filename under the current configuration. *)
val tags_of_filename : string -> Tags.t
-(** Return the set of flags that apply to a given filename under the current configuration. *)
-val flags_of_filename : string -> Command.spec
-
val has_tag : string -> bool
(** [tag_file filename tag_list] Tag the given filename with all given tags. *)
diff --git a/ocamlbuild/flags.ml b/ocamlbuild/flags.ml
index bdf4fc6f8..0423ec43a 100644
--- a/ocamlbuild/flags.ml
+++ b/ocamlbuild/flags.ml
@@ -33,13 +33,11 @@ let set_flags tags flags =
let flag tags flags = set_flags (Tags.of_list tags) flags
+let pflag tags ptag flags =
+ Param_tags.declare ptag
+ (fun param -> flag (Param_tags.make ptag param :: tags) (flags param))
+
let add x xs = x :: xs
let remove me = List.filter (fun x -> me <> x)
-let to_spec l =
- S begin
- List.fold_right begin fun (x, y) acc ->
- A ("-"^x) :: A y :: acc
- end l []
- end
let get_flags () = !all_flags
diff --git a/ocamlbuild/flags.mli b/ocamlbuild/flags.mli
index 941a75b77..5e0e637df 100644
--- a/ocamlbuild/flags.mli
+++ b/ocamlbuild/flags.mli
@@ -14,9 +14,9 @@
val of_tags : Tags.t -> Command.spec
val of_tag_list : Tags.elt list -> Command.spec
val flag : Tags.elt list -> Command.spec -> unit
+val pflag : Tags.elt list -> string -> (string -> Command.spec) -> unit
val add : 'a -> 'a list -> 'a list
val remove : 'a -> 'a list -> 'a list
-val to_spec : (string * string) list -> Command.spec
(** For system use only *)
diff --git a/ocamlbuild/lexers.mli b/ocamlbuild/lexers.mli
index 472a3cacd..5fc1d9283 100644
--- a/ocamlbuild/lexers.mli
+++ b/ocamlbuild/lexers.mli
@@ -15,9 +15,7 @@ exception Error of string
type conf_values =
{ plus_tags : string list;
- minus_tags : string list;
- plus_flags : (string * string) list;
- minus_flags : (string * string) list }
+ minus_tags : string list }
type conf = (Glob.globber * conf_values) list
@@ -26,6 +24,7 @@ val space_sep_strings : Lexing.lexbuf -> string list
val blank_sep_strings : Lexing.lexbuf -> string list
val comma_sep_strings : Lexing.lexbuf -> string list
val comma_or_blank_sep_strings : Lexing.lexbuf -> string list
+val trim_blanks : Lexing.lexbuf -> string
(* Parse a colon separated string.
Note: successive colons are ignored.
@@ -37,3 +36,8 @@ val path_scheme : bool -> Lexing.lexbuf ->
[ `Word of string
| `Var of (string * Glob.globber)
] list
+
+val ocamlfind_query : Lexing.lexbuf ->
+ string * string * string * string * string * string
+
+val tag_gen : Lexing.lexbuf -> string * string option
diff --git a/ocamlbuild/lexers.mll b/ocamlbuild/lexers.mll
index 67fa1e601..97240d9c1 100644
--- a/ocamlbuild/lexers.mll
+++ b/ocamlbuild/lexers.mll
@@ -17,13 +17,11 @@ open Glob_ast
type conf_values =
{ plus_tags : string list;
- minus_tags : string list;
- plus_flags : (string * string) list;
- minus_flags : (string * string) list }
+ minus_tags : string list }
type conf = (Glob.globber * conf_values) list
-let empty = { plus_flags = []; minus_flags = []; plus_tags = []; minus_tags = [] }
+let empty = { plus_tags = []; minus_tags = [] }
}
let newline = ('\n' | '\r' | "\r\n")
@@ -36,9 +34,7 @@ let not_newline = [^ '\n' '\r' ]
let not_newline_nor_colon = [^ '\n' '\r' ':' ]
let normal_flag_value = [^ '(' ')' '\n' '\r']
let normal = [^ ':' ',' '(' ')' ''' ' ' '\n' '\r']
-let tag = normal+ | ( normal+ ':' normal+ )
-let flag_name = normal+
-let flag_value = normal_flag_value+
+let tag = normal+ | ( normal+ ':' normal+ ) | normal+ '(' [^ ')' ]* ')'
let variable = [ 'a'-'z' 'A'-'Z' '_' '-' '0'-'9' ]*
let pattern = ([^ '(' ')' '\\' ] | '\\' [ '(' ')' ])*
@@ -110,8 +106,6 @@ and conf_lines dir pos err = parse
| _ { raise (Error(Printf.sprintf "Bad key in configuration line at line %d (from %s)" pos err)) }
and conf_value pos err x = parse
- | '-' (flag_name as t1) '(' (flag_value as t2) ')' { { (x) with minus_flags = (t1, t2) :: x.minus_flags } }
- | '+'? (flag_name as t1) '(' (flag_value as t2) ')' { { (x) with plus_flags = (t1, t2) :: x.plus_flags } }
| '-' (tag as tag) { { (x) with minus_tags = tag :: x.minus_tags } }
| '+'? (tag as tag) { { (x) with plus_tags = tag :: x.plus_tags } }
| (_ | eof) { raise (Error(Printf.sprintf "Bad value in configuration line at line %d (from %s)" pos err)) }
@@ -143,3 +137,21 @@ and unescape = parse
| '\\' (['(' ')'] as c) { c :: unescape lexbuf }
| _ as c { c :: unescape lexbuf }
| eof { [] }
+
+and ocamlfind_query = parse
+ | newline*
+ "package:" space* (not_newline* as n) newline+
+ "description:" space* (not_newline* as d) newline+
+ "version:" space* (not_newline* as v) newline+
+ "archive(s):" space* (not_newline* as a) newline+
+ "linkopts:" space* (not_newline* as lo) newline+
+ "location:" space* (not_newline* as l) newline+
+ { n, d, v, a, lo, l }
+ | _ { raise (Error "Bad ocamlfind query") }
+
+and trim_blanks = parse
+ | blank* (not_blank* as word) blank* { word }
+ | _ { raise (Error "Bad input for trim_blanks") }
+
+and tag_gen = parse
+ | (normal+ as name) ('(' ([^')']* as param) ')')? { name, param }
diff --git a/ocamlbuild/main.ml b/ocamlbuild/main.ml
index 5b9a04d6b..53ab4dc91 100644
--- a/ocamlbuild/main.ml
+++ b/ocamlbuild/main.ml
@@ -142,6 +142,8 @@ let proceed () =
Ocaml_specific.init ();
Hooks.call_hook Hooks.After_rules;
+ Param_tags.init ();
+
Sys.chdir newpwd;
(*let () = dprintf 0 "source_dir_path_set:@ %a" StringSet.print source_dir_path_set*)
diff --git a/ocamlbuild/ocaml_compiler.ml b/ocamlbuild/ocaml_compiler.ml
index 1d736c09d..de3cd3953 100644
--- a/ocamlbuild/ocaml_compiler.ml
+++ b/ocamlbuild/ocaml_compiler.ml
@@ -31,23 +31,22 @@ let forpack_flags arg tags =
let ocamlc_c tags arg out =
let tags = tags++"ocaml"++"byte" in
Cmd (S [!Options.ocamlc; A"-c"; T(tags++"compile");
- ocaml_ppflags tags; flags_of_pathname arg;
- ocaml_include_flags arg; A"-o"; Px out; P arg])
+ ocaml_ppflags tags; ocaml_include_flags arg; A"-o"; Px out; P arg])
let ocamlc_link flag tags deps out =
Cmd (S [!Options.ocamlc; flag; T tags;
- atomize_paths deps; flags_of_pathname out; A"-o"; Px out])
+ atomize_paths deps; A"-o"; Px out])
let ocamlc_link_lib = ocamlc_link (A"-a")
let ocamlc_link_prog = ocamlc_link N
let ocamlmklib tags deps out =
Cmd (S [!Options.ocamlmklib; T tags;
- atomize_paths deps; flags_of_pathname out; A"-o"; Px (Pathname.remove_extensions out)])
+ atomize_paths deps; A"-o"; Px (Pathname.remove_extensions out)])
let ocamlmktop tags deps out =
- Cmd( S [!Options.ocamlmktop; T tags;
- atomize_paths deps; flags_of_pathname out; A"-o"; Px out])
+ Cmd( S [!Options.ocamlmktop; T (tags++"mktop");
+ atomize_paths deps; A"-o"; Px out])
let byte_lib_linker tags =
if Tags.mem "ocamlmklib" tags then
@@ -59,18 +58,17 @@ let byte_lib_linker_tags tags = tags++"ocaml"++"link"++"byte"++"library"
let ocamlc_p tags deps out =
Cmd (S [!Options.ocamlc; A"-pack"; T tags;
- atomize_paths deps; flags_of_pathname out; A"-o"; Px out])
+ atomize_paths deps; A"-o"; Px out])
let ocamlopt_c tags arg out =
let tags = tags++"ocaml"++"native" in
Cmd (S [!Options.ocamlopt; A"-c"; Ocaml_arch.forpack_flags_of_pathname arg;
- T(tags++"compile"); ocaml_ppflags tags; flags_of_pathname arg;
- flags_of_pathname out; ocaml_include_flags arg;
+ T(tags++"compile"); ocaml_ppflags tags; ocaml_include_flags arg;
A"-o"; Px out (* FIXME ocamlopt bug -o cannot be after the input file *); P arg])
let ocamlopt_link flag tags deps out =
Cmd (S [!Options.ocamlopt; flag; forpack_flags out tags; T tags;
- atomize_paths deps; flags_of_pathname out; A"-o"; Px out])
+ atomize_paths deps; A"-o"; Px out])
let ocamlopt_link_lib = ocamlopt_link (A"-a")
let ocamlopt_link_prog = ocamlopt_link N
@@ -81,7 +79,7 @@ let ocamlopt_p tags deps out =
let mli = Pathname.update_extensions "mli" out in
let cmd =
S [!Options.ocamlopt; A"-pack"; forpack_flags out tags; T tags;
- S include_flags; atomize_paths deps; flags_of_pathname out;
+ S include_flags; atomize_paths deps;
A"-o"; Px out] in
if (*FIXME true ||*) Pathname.exists mli then Cmd cmd
else
@@ -151,7 +149,7 @@ let native_compile_ocaml_implem ?tag ?(cmx_ext="cmx") ml env build =
let cmi = Pathname.update_extensions "cmi" ml in
let cmx = Pathname.update_extensions cmx_ext ml in
prepare_link cmx cmi [cmx_ext; "cmi"] build;
- ocamlopt_c (tags_of_pathname ml++"implem"+++tag) ml cmx
+ ocamlopt_c (Tags.union (tags_of_pathname ml) (tags_of_pathname cmx)++"implem"+++tag) ml cmx
let libs_of_use_lib tags =
Tags.fold begin fun tag acc ->
diff --git a/ocamlbuild/ocaml_specific.ml b/ocamlbuild/ocaml_specific.ml
index f37f52cac..749a6b640 100644
--- a/ocamlbuild/ocaml_specific.ml
+++ b/ocamlbuild/ocaml_specific.ml
@@ -357,6 +357,21 @@ flag ["ocaml"; "native"; "link"] begin
S (List.map (fun x -> A (x^".cmxa")) !Options.ocaml_libs)
end;;
+(* parameterized tags *)
+let () =
+ pflag ["ocaml"; "native"; "compile"] "for-pack"
+ (fun param -> S [A "-for-pack"; A param]);
+ pflag ["ocaml"; "compile"] "inline"
+ (fun param -> S [A "-inline"; A param]);
+ pflag ["ocaml"; "compile"] "pp"
+ (fun param -> S [A "-pp"; A param]);
+ pflag ["ocaml"; "ocamldep"] "pp"
+ (fun param -> S [A "-pp"; A param]);
+ pflag ["ocaml"; "doc"] "pp"
+ (fun param -> S [A "-pp"; A param]);
+ pflag ["ocaml"; "infer_interface"] "pp"
+ (fun param -> S [A "-pp"; A param])
+
let camlp4_flags camlp4s =
List.iter begin fun camlp4 ->
flag ["ocaml"; "pp"; camlp4] (A camlp4)
diff --git a/ocamlbuild/ocaml_tools.ml b/ocamlbuild/ocaml_tools.ml
index 179199218..f66c127c3 100644
--- a/ocamlbuild/ocaml_tools.ml
+++ b/ocamlbuild/ocaml_tools.ml
@@ -20,22 +20,20 @@ open Ocaml_utils
let add_suffix s = List.map (fun x -> x -.- s) ;;
-let ocamldep_command' tags spec =
+let ocamldep_command' tags =
let tags' = tags++"ocaml"++"ocamldep" in
- S [!Options.ocamldep; T tags'; ocaml_ppflags (tags++"pp:dep");
- spec; A "-modules"]
+ S [!Options.ocamldep; T tags'; ocaml_ppflags (tags++"pp:dep"); A "-modules"]
-let menhir_ocamldep_command' tags ~menhir_spec ~ocamldep_spec out =
+let menhir_ocamldep_command' tags ~menhir_spec out =
let menhir = if !Options.ocamlyacc = N then V"MENHIR" else !Options.ocamlyacc in
Cmd(S[menhir; T tags; A"--raw-depend";
- A"--ocamldep"; Quote (ocamldep_command' tags ocamldep_spec);
+ A"--ocamldep"; Quote (ocamldep_command' tags);
menhir_spec ; Sh ">"; Px out])
let menhir_ocamldep_command arg out env _build =
let arg = env arg and out = env out in
let tags = tags_of_pathname arg++"ocaml"++"menhir_ocamldep" in
- let ocamldep_spec = flags_of_pathname arg in
- menhir_ocamldep_command' tags ~menhir_spec:(P arg) ~ocamldep_spec out
+ menhir_ocamldep_command' tags ~menhir_spec:(P arg) out
let import_mlypack build mlypack =
let tags1 = tags_of_pathname mlypack in
@@ -60,8 +58,7 @@ let menhir_modular_ocamldep_command mlypack out env build =
let tags = tags++"ocaml"++"menhir_ocamldep" in
let menhir_base = Pathname.remove_extensions mlypack in
let menhir_spec = S[A "--base" ; P menhir_base ; atomize_paths files] in
- let ocamldep_spec = N in
- menhir_ocamldep_command' tags ~menhir_spec ~ocamldep_spec out
+ menhir_ocamldep_command' tags ~menhir_spec out
let menhir_modular menhir_base mlypack mlypack_depends env build =
let menhir = if !Options.ocamlyacc = N then V"MENHIR" else !Options.ocamlyacc in
@@ -75,25 +72,21 @@ let menhir_modular menhir_base mlypack mlypack_depends env build =
let tags = tags++"ocaml"++"parser"++"menhir" in
Cmd(S[menhir ;
A "--ocamlc"; Quote(S[!Options.ocamlc; T ocamlc_tags; ocaml_include_flags mlypack]);
- T tags ; A "--infer" ; flags_of_pathname mlypack ;
- A "--base" ; Px menhir_base ; atomize_paths files])
+ T tags ; A "--infer" ; A "--base" ; Px menhir_base ; atomize_paths files])
let ocamldep_command arg out env _build =
let arg = env arg and out = env out in
- let spec = flags_of_pathname arg in
let tags = tags_of_pathname arg in
- Cmd(S[ocamldep_command' tags spec; P arg; Sh ">"; Px out])
+ Cmd(S[ocamldep_command' tags; P arg; Sh ">"; Px out])
let ocamlyacc mly env _build =
let mly = env mly in
let ocamlyacc = if !Options.ocamlyacc = N then V"OCAMLYACC" else !Options.ocamlyacc in
- Cmd(S[ocamlyacc; T(tags_of_pathname mly++"ocaml"++"parser"++"ocamlyacc");
- flags_of_pathname mly; Px mly])
+ Cmd(S[ocamlyacc; T(tags_of_pathname mly++"ocaml"++"parser"++"ocamlyacc"); Px mly])
let ocamllex mll env _build =
let mll = env mll in
- Cmd(S[!Options.ocamllex; T(tags_of_pathname mll++"ocaml"++"lexer"++"ocamllex");
- flags_of_pathname mll; Px mll])
+ Cmd(S[!Options.ocamllex; T(tags_of_pathname mll++"ocaml"++"lexer"++"ocamllex"); Px mll])
let infer_interface ml mli env build =
let ml = env ml and mli = env mli in
@@ -109,12 +102,12 @@ let menhir mly env build =
Cmd(S[menhir;
A"--ocamlc"; Quote(S[!Options.ocamlc; ocaml_include_flags mly]);
T(tags_of_pathname mly++"ocaml"++"parser"++"menhir");
- A"--infer"; flags_of_pathname mly; Px mly])
+ A"--infer"; Px mly])
let ocamldoc_c tags arg odoc =
let tags = tags++"ocaml" in
Cmd (S [!Options.ocamldoc; A"-dump"; Px odoc; T(tags++"doc");
- ocaml_ppflags (tags++"pp:doc"); flags_of_pathname arg;
+ ocaml_ppflags (tags++"pp:doc");
ocaml_include_flags arg; P arg])
let ocamldoc_l_dir tags deps _docout docdir =
diff --git a/ocamlbuild/ocaml_utils.ml b/ocamlbuild/ocaml_utils.ml
index 449328ce6..3dafe25a4 100644
--- a/ocamlbuild/ocaml_utils.ml
+++ b/ocamlbuild/ocaml_utils.ml
@@ -35,6 +35,11 @@ let stdlib_dir = lazy begin
String.chomp (read_file ocamlc_where)
end
+let pflag_and_dep tags ptag cmd_spec =
+ Param_tags.declare ptag
+ (fun param ->
+ flag_and_dep (Param_tags.make ptag param :: tags) (cmd_spec param))
+
let module_name_of_filename f = String.capitalize (Pathname.remove_extensions f)
let module_name_of_pathname x =
module_name_of_filename (Pathname.to_string (Pathname.basename x))
diff --git a/ocamlbuild/ocaml_utils.mli b/ocamlbuild/ocaml_utils.mli
index 660e27b9b..259a527f5 100644
--- a/ocamlbuild/ocaml_utils.mli
+++ b/ocamlbuild/ocaml_utils.mli
@@ -26,6 +26,8 @@ val use_lib : Pathname.t -> Pathname.t -> unit
val cmi_of : Pathname.t -> Pathname.t
val ocaml_add_include_flag : string -> Command.spec list -> Command.spec list
val flag_and_dep : Tags.elt list -> Command.spec -> unit
+val pflag_and_dep : Tags.elt list -> Tags.elt -> (string -> Command.spec) ->
+ unit
exception Ocamldep_error of string
diff --git a/ocamlbuild/ocamlbuild_pack.mlpack b/ocamlbuild/ocamlbuild_pack.mlpack
index 92b16c7c9..96a1b0c5f 100644
--- a/ocamlbuild/ocamlbuild_pack.mlpack
+++ b/ocamlbuild/ocamlbuild_pack.mlpack
@@ -38,3 +38,4 @@ Ocaml_compiler
Ocaml_dependencies
Exit_codes
Digest_cache
+Param_tags
diff --git a/ocamlbuild/ocamlbuild_plugin.ml b/ocamlbuild/ocamlbuild_plugin.ml
index 2aadca173..6171e6ad7 100644
--- a/ocamlbuild/ocamlbuild_plugin.ml
+++ b/ocamlbuild/ocamlbuild_plugin.ml
@@ -33,10 +33,13 @@ type action = env -> builder -> Command.t
let rule = Rule.rule
let clear_rules = Rule.clear_rules
let dep = Command.dep
+let pdep = Command.pdep
let copy_rule = Rule.copy_rule
let ocaml_lib = Ocamlbuild_pack.Ocaml_utils.ocaml_lib
let flag = Ocamlbuild_pack.Flags.flag
+let pflag = Ocamlbuild_pack.Flags.pflag
let flag_and_dep = Ocamlbuild_pack.Ocaml_utils.flag_and_dep
+let pflag_and_dep = Ocamlbuild_pack.Ocaml_utils.pflag_and_dep
let non_dependency = Ocamlbuild_pack.Ocaml_utils.non_dependency
let use_lib = Ocamlbuild_pack.Ocaml_utils.use_lib
let module_name_of_pathname = Ocamlbuild_pack.Ocaml_utils.module_name_of_pathname
diff --git a/ocamlbuild/ocamlbuild_unix_plugin.ml b/ocamlbuild/ocamlbuild_unix_plugin.ml
index c562d4288..3eaaf1743 100644
--- a/ocamlbuild/ocamlbuild_unix_plugin.ml
+++ b/ocamlbuild/ocamlbuild_unix_plugin.ml
@@ -58,7 +58,8 @@ let run_and_open s kont =
in close (); res
let stdout_isatty () =
- Unix.isatty Unix.stdout
+ Unix.isatty Unix.stdout &&
+ try Unix.getenv "TERM" <> "dumb" with Not_found -> true
let execute_many =
let exit i = raise (My_std.Exit_with_code i) in
diff --git a/ocamlbuild/signatures.mli b/ocamlbuild/signatures.mli
index cddc0f588..1c57e970a 100644
--- a/ocamlbuild/signatures.mli
+++ b/ocamlbuild/signatures.mli
@@ -527,10 +527,29 @@ module type PLUGIN = sig
(** [dep tags deps] Will build [deps] when all [tags] will be activated. *)
val dep : Tags.elt list -> Pathname.t list -> unit
+ (** [pdep tags ptag deps] is equivalent to [dep tags deps], with an additional
+ parameterized tag [ptag]. [deps] is now a function which takes the
+ parameter of the tag [ptag] as an argument.
+
+ Example:
+ [pdep ["ocaml"; "compile"] "autodep" (fun param -> param)]
+ says that the tag [autodep(file)] can now be used to automatically
+ add [file] as a dependency when compiling an OCaml program. *)
+ val pdep : Tags.elt list -> Tags.elt -> (string -> Pathname.t list) -> unit
+
(** [flag tags command_spec] Will inject the given piece of command
([command_spec]) when all [tags] will be activated. *)
val flag : Tags.elt list -> Command.spec -> unit
+ (** Allows to use [flag] with a parameterized tag (as [pdep] for [dep]).
+
+ Example:
+ [pflag ["ocaml"; "compile"] "inline"
+ (fun count -> S [A "-inline"; A count])]
+ says that command line option ["-inline 42"] should be added
+ when compiling files tagged with tag ["inline(42)"]. *)
+ val pflag : Tags.elt list -> Tags.elt -> (string -> Command.spec) -> unit
+
(** [flag_and_dep tags command_spec]
Combines [flag] and [dep] function.
Basically it calls [flag tags command_spec], and calls [dep tags files]
@@ -539,6 +558,11 @@ module type PLUGIN = sig
pathname argument of builtins like [Echo]. *)
val flag_and_dep : Tags.elt list -> Command.spec -> unit
+ (** Allows to use [flag_and_dep] with a parameterized tag
+ (as [pdep] for [dep]). *)
+ val pflag_and_dep : Tags.elt list -> Tags.elt ->
+ (string -> Command.spec) -> unit
+
(** [non_dependency module_path module_name]
Example:
[non_dependency "foo/bar/baz" "Goo"]
diff --git a/ocamlbuild/start.sh b/ocamlbuild/start.sh
index 742e81ad9..498e91d0d 100755
--- a/ocamlbuild/start.sh
+++ b/ocamlbuild/start.sh
@@ -66,6 +66,10 @@ ocamlc -c plugin.mli
ocamlc -c plugin.ml
ocamlc -c ocaml_dependencies.ml
ocamlc -c exit_codes.ml
+ocamllex lexers.mll
+ocamlc -c lexers.ml
+ocamlc -c param_tags.mli
+ocamlc -c param_tags.ml
ocamlc -c main.ml
ocamlc -c ocaml_specific.ml
ocamlc -c display.ml
@@ -82,8 +86,6 @@ ocamlc -c ocaml_utils.ml
ocamlc -c ocaml_tools.ml
ocamlc -c ocaml_compiler.ml
ocamlc -c hooks.ml
-ocamllex lexers.mll
-ocamlc -c lexers.ml
ocamllex glob_lexer.mll
ocamlc -c glob_lexer.ml
ocamlc -c bool.ml
@@ -100,7 +102,7 @@ ocamlc -c rule.ml
ocamlc -c report.ml
ocamlc -c solver.ml
ocamlc -c ocamlbuildlight.mli
-ocamlc -pack discard_printf.cmo my_std.cmo bool.cmo glob_ast.cmo glob_lexer.cmo glob.cmo lexers.cmo my_unix.cmo tags.cmo display.cmo log.cmo shell.cmo slurp.cmo ocamlbuild_where.cmo command.cmo options.cmo pathname.cmo digest_cache.cmo resource.cmo rule.cmo flags.cmo solver.cmo report.cmo ocaml_arch.cmo hygiene.cmo configuration.cmo tools.cmo fda.cmo plugin.cmo ocaml_utils.cmo ocaml_dependencies.cmo ocaml_compiler.cmo ocaml_tools.cmo hooks.cmo ocaml_specific.cmo exit_codes.cmo main.cmo -o ocamlbuild_pack.cmo
+ocamlc -pack discard_printf.cmo my_std.cmo bool.cmo glob_ast.cmo glob_lexer.cmo glob.cmo lexers.cmo my_unix.cmo tags.cmo display.cmo log.cmo param_tags.cmo shell.cmo slurp.cmo ocamlbuild_where.cmo command.cmo options.cmo pathname.cmo digest_cache.cmo resource.cmo rule.cmo flags.cmo solver.cmo report.cmo ocaml_arch.cmo hygiene.cmo configuration.cmo tools.cmo fda.cmo plugin.cmo ocaml_utils.cmo ocaml_dependencies.cmo ocaml_compiler.cmo ocaml_tools.cmo hooks.cmo ocaml_specific.cmo exit_codes.cmo main.cmo -o ocamlbuild_pack.cmo
ocamlc -c ocamlbuildlight.ml
ocamlc ocamlbuild_pack.cmo ocamlbuildlight.cmo -o ../ocamlbuild.byte.start
cd ..
diff --git a/ocamlbuild/tools.ml b/ocamlbuild/tools.ml
index 69a011b54..d72278e7c 100644
--- a/ocamlbuild/tools.ml
+++ b/ocamlbuild/tools.ml
@@ -26,7 +26,6 @@ let tags_of_pathname p =
Configuration.tags_of_filename (Pathname.to_string p)
++("file:"^p)
++("extension:"^Pathname.get_extension p)
-let flags_of_pathname p = Configuration.flags_of_filename (Pathname.to_string p)
let opt_print elt ppf =
function
diff --git a/ocamlbuild/tools.mli b/ocamlbuild/tools.mli
index 6c4b6f3ee..974ff1adb 100644
--- a/ocamlbuild/tools.mli
+++ b/ocamlbuild/tools.mli
@@ -14,6 +14,5 @@
(* Tools *)
val tags_of_pathname : Pathname.t -> Tags.t
-val flags_of_pathname : Pathname.t -> Command.spec
val path_and_context_of_string : Pathname.t -> Pathname.t list
val pp_l : Format.formatter -> string list -> unit