Add ${!^} and ${!@} and document them
This commit is contained in:
parent
3241026fff
commit
a8a43e4b22
|
@ -523,9 +523,11 @@ Jbuilder supports the following variables:
|
||||||
In addition, ``(action ...)`` fields support the following special variables:
|
In addition, ``(action ...)`` fields support the following special variables:
|
||||||
|
|
||||||
- ``@`` expands to the list of target, separated by spaces
|
- ``@`` expands to the list of target, separated by spaces
|
||||||
|
- ``!@`` same as ``@`` but with a split semantic (see below)
|
||||||
- ``<`` expands to the first dependency, or the empty string if there are no
|
- ``<`` expands to the first dependency, or the empty string if there are no
|
||||||
dependencies
|
dependencies
|
||||||
- ``^`` expands to the list of dependencies, separated by spaces
|
- ``^`` expands to the list of dependencies, separated by spaces
|
||||||
|
- ``!^`` same as ``^`` but with a split semantic (see below)
|
||||||
- ``path:<path>`` expands to ``<path>``
|
- ``path:<path>`` expands to ``<path>``
|
||||||
- ``exe:<path>`` is the same as ``<path>``, except when cross-compiling, in
|
- ``exe:<path>`` is the same as ``<path>``, except when cross-compiling, in
|
||||||
which case it will expand to ``<path>`` from the host build context
|
which case it will expand to ``<path>`` from the host build context
|
||||||
|
@ -558,6 +560,39 @@ transparently whether things are installed or not.
|
||||||
|
|
||||||
Note that aliases are ignored by both ``${<}`` and ``${^}``.
|
Note that aliases are ignored by both ``${<}`` and ``${^}``.
|
||||||
|
|
||||||
|
Moreover ``${^}`` and ``${@}`` will always expand to a single
|
||||||
|
string. For instance in:
|
||||||
|
|
||||||
|
.. code:: scheme
|
||||||
|
|
||||||
|
(run foo ${^})
|
||||||
|
|
||||||
|
even if there are two dependencies ``a`` and ``b``, the produced
|
||||||
|
command will be equivalent to the shell command:
|
||||||
|
|
||||||
|
.. code:: shell
|
||||||
|
|
||||||
|
$ foo "a b"
|
||||||
|
|
||||||
|
In order to *split* them, you can use ``${!^}`` and ``${!@}``. These
|
||||||
|
two forms are only available in ``(run ...)`` forms and can only be
|
||||||
|
used as a whole atom, i.e. they can't be used inside a quoted
|
||||||
|
atom. Replacing ``${^}`` by ``${!^}`` in the previous example would
|
||||||
|
produce a command equivalent to this shell command:
|
||||||
|
|
||||||
|
.. code:: shell
|
||||||
|
|
||||||
|
$ foo "a" "b"
|
||||||
|
|
||||||
|
You can also use ``${!^}`` as program name, for instance:
|
||||||
|
|
||||||
|
.. code:: scheme
|
||||||
|
|
||||||
|
(rule
|
||||||
|
((targets (result.txt))
|
||||||
|
(deps (foo.exe (glob_files *.txt)))
|
||||||
|
(action (run ${!^}))))
|
||||||
|
|
||||||
Library dependencies
|
Library dependencies
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ open Sexp.Of_sexp
|
||||||
|
|
||||||
module Env_var_map = Context.Env_var_map
|
module Env_var_map = Context.Env_var_map
|
||||||
|
|
||||||
|
type split_or_concat = Split | Concat
|
||||||
|
|
||||||
type var_expansion =
|
type var_expansion =
|
||||||
| Not_found
|
| Not_found
|
||||||
| Path of Path.t
|
| Path of Path.t
|
||||||
| Paths of Path.t list
|
| Paths of Path.t list * split_or_concat
|
||||||
| Str of string
|
| Str of string
|
||||||
|
|
||||||
let expand_str ~dir ~f template =
|
let expand_str ~dir ~f template =
|
||||||
|
@ -14,9 +16,21 @@ let expand_str ~dir ~f template =
|
||||||
match f var with
|
match f var with
|
||||||
| Not_found -> None
|
| Not_found -> None
|
||||||
| Path path -> Some (Path.reach ~from:dir path)
|
| Path path -> Some (Path.reach ~from:dir path)
|
||||||
| Paths l -> Some (List.map l ~f:(Path.reach ~from:dir) |> String.concat ~sep:" ")
|
| Paths (l, _) -> Some (List.map l ~f:(Path.reach ~from:dir) |> String.concat ~sep:" ")
|
||||||
| Str s -> Some s)
|
| Str s -> Some s)
|
||||||
|
|
||||||
|
let expand_str_split ~dir ~f template =
|
||||||
|
match String_with_vars.just_a_var template with
|
||||||
|
| None -> [expand_str ~dir ~f template]
|
||||||
|
| Some var ->
|
||||||
|
match f var with
|
||||||
|
| Not_found -> [expand_str ~dir ~f template]
|
||||||
|
| Path path -> [Path.reach ~from:dir path]
|
||||||
|
| Str s -> [s]
|
||||||
|
| Paths (l, Concat) ->
|
||||||
|
[List.map l ~f:(Path.reach ~from:dir) |> String.concat ~sep:" "]
|
||||||
|
| Paths (l, Split) -> List.map l ~f:(Path.reach ~from:dir)
|
||||||
|
|
||||||
let expand_path ~dir ~f template =
|
let expand_path ~dir ~f template =
|
||||||
match String_with_vars.just_a_var template with
|
match String_with_vars.just_a_var template with
|
||||||
| None -> expand_str ~dir ~f template |> Path.relative dir
|
| None -> expand_str ~dir ~f template |> Path.relative dir
|
||||||
|
@ -24,9 +38,9 @@ let expand_path ~dir ~f template =
|
||||||
match f v with
|
match f v with
|
||||||
| Not_found -> expand_str ~dir ~f template |> Path.relative dir
|
| Not_found -> expand_str ~dir ~f template |> Path.relative dir
|
||||||
| Path p
|
| Path p
|
||||||
| Paths [p] -> p
|
| Paths ([p], _) -> p
|
||||||
| Str s -> Path.relative dir s
|
| Str s -> Path.relative dir s
|
||||||
| Paths l ->
|
| Paths (l, _) ->
|
||||||
List.map l ~f:(Path.reach ~from:dir)
|
List.map l ~f:(Path.reach ~from:dir)
|
||||||
|> String.concat ~sep:" "
|
|> String.concat ~sep:" "
|
||||||
|> Path.relative dir
|
|> Path.relative dir
|
||||||
|
@ -41,17 +55,19 @@ let expand_prog ctx ~dir ~f template =
|
||||||
| None -> Utils.program_not_found ~context:ctx.name s
|
| None -> Utils.program_not_found ~context:ctx.name s
|
||||||
in
|
in
|
||||||
match String_with_vars.just_a_var template with
|
match String_with_vars.just_a_var template with
|
||||||
| None -> resolve (expand_str ~dir ~f template)
|
| None -> (resolve (expand_str ~dir ~f template), [])
|
||||||
| Some v ->
|
| Some v ->
|
||||||
match f v with
|
match f v with
|
||||||
| Not_found -> resolve (expand_str ~dir ~f template)
|
| Not_found -> (resolve (expand_str ~dir ~f template), [])
|
||||||
| Path p
|
| Path p
|
||||||
| Paths [p] -> p
|
| Paths ([p], _) -> (p, [])
|
||||||
| Str s -> resolve s
|
| Str s -> (resolve s, [])
|
||||||
| Paths l ->
|
| Paths (p :: args, Split) -> (p, List.map args ~f:(Path.reach ~from:dir))
|
||||||
List.map l ~f:(Path.reach ~from:dir)
|
| Paths (l, _) ->
|
||||||
|> String.concat ~sep:" "
|
(List.map l ~f:(Path.reach ~from:dir)
|
||||||
|> resolve
|
|> String.concat ~sep:" "
|
||||||
|
|> resolve,
|
||||||
|
[])
|
||||||
|
|
||||||
module Outputs = struct
|
module Outputs = struct
|
||||||
include Action_intf.Outputs
|
include Action_intf.Outputs
|
||||||
|
@ -197,8 +213,9 @@ module Unexpanded = struct
|
||||||
let rec expand ctx dir t ~f : action =
|
let rec expand ctx dir t ~f : action =
|
||||||
match t with
|
match t with
|
||||||
| Run (prog, args) ->
|
| Run (prog, args) ->
|
||||||
Run (expand_prog ctx ~dir ~f prog,
|
let prog, more_args = expand_prog ctx ~dir ~f prog in
|
||||||
List.map args ~f:(fun arg -> expand_str ~dir ~f arg))
|
Run (prog,
|
||||||
|
more_args @ List.concat_map args ~f:(expand_str_split ~dir ~f))
|
||||||
| Chdir (fn, t) ->
|
| Chdir (fn, t) ->
|
||||||
let fn = expand_path ~dir ~f fn in
|
let fn = expand_path ~dir ~f fn in
|
||||||
Chdir (fn, expand ctx fn t ~f)
|
Chdir (fn, expand ctx fn t ~f)
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
open! Import
|
open! Import
|
||||||
|
|
||||||
|
type split_or_concat = Split | Concat
|
||||||
|
|
||||||
type var_expansion =
|
type var_expansion =
|
||||||
| Not_found
|
| Not_found
|
||||||
| Path of Path.t
|
| Path of Path.t
|
||||||
| Paths of Path.t list
|
| Paths of Path.t list * split_or_concat
|
||||||
| Str of string
|
| Str of string
|
||||||
|
|
||||||
module Outputs : module type of struct include Action_intf.Outputs end
|
module Outputs : module type of struct include Action_intf.Outputs end
|
||||||
|
|
|
@ -550,13 +550,14 @@ module Action = struct
|
||||||
| Some exp -> exp
|
| Some exp -> exp
|
||||||
| None ->
|
| None ->
|
||||||
match var_name with
|
match var_name with
|
||||||
| "@" -> Action.Paths targets
|
| "@" -> Action.Paths (targets, Concat)
|
||||||
|
| "!@" -> Action.Paths (targets, Split)
|
||||||
| "<" ->
|
| "<" ->
|
||||||
(match deps with
|
(match deps with
|
||||||
| [] -> Str "" (* CR-someday jdimino: this should be an error *)
|
| [] -> Str "" (* CR-someday jdimino: this should be an error *)
|
||||||
| dep :: _ -> Path dep)
|
| dep :: _ -> Path dep)
|
||||||
| "^" ->
|
| "^" -> Paths (deps, Concat)
|
||||||
Paths deps
|
| "!^" -> Paths (deps, Split)
|
||||||
| "ROOT" -> Path sctx.context.build_dir
|
| "ROOT" -> Path sctx.context.build_dir
|
||||||
| var ->
|
| var ->
|
||||||
match expand_var_no_root sctx var with
|
match expand_var_no_root sctx var with
|
||||||
|
@ -574,7 +575,7 @@ module Action = struct
|
||||||
~f:(fun ~key:_ ~data:exp acc ->
|
~f:(fun ~key:_ ~data:exp acc ->
|
||||||
match exp with
|
match exp with
|
||||||
| Action.Path p -> Path.Set.add p acc
|
| Action.Path p -> Path.Set.add p acc
|
||||||
| Paths ps -> Path.Set.union acc (Path.Set.of_list ps)
|
| Paths (ps, _) -> Path.Set.union acc (Path.Set.of_list ps)
|
||||||
| Not_found | Str _ -> acc))
|
| Not_found | Str _ -> acc))
|
||||||
>>>
|
>>>
|
||||||
Build.arr (fun paths -> ((), paths))
|
Build.arr (fun paths -> ((), paths))
|
||||||
|
|
Loading…
Reference in New Issue