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:
|
||||
|
||||
- ``@`` 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
|
||||
dependencies
|
||||
- ``^`` expands to the list of dependencies, separated by spaces
|
||||
- ``!^`` same as ``^`` but with a split semantic (see below)
|
||||
- ``path:<path>`` expands to ``<path>``
|
||||
- ``exe:<path>`` is the same as ``<path>``, except when cross-compiling, in
|
||||
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 ``${^}``.
|
||||
|
||||
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
|
||||
--------------------
|
||||
|
||||
|
|
|
@ -3,10 +3,12 @@ open Sexp.Of_sexp
|
|||
|
||||
module Env_var_map = Context.Env_var_map
|
||||
|
||||
type split_or_concat = Split | Concat
|
||||
|
||||
type var_expansion =
|
||||
| Not_found
|
||||
| Path of Path.t
|
||||
| Paths of Path.t list
|
||||
| Paths of Path.t list * split_or_concat
|
||||
| Str of string
|
||||
|
||||
let expand_str ~dir ~f template =
|
||||
|
@ -14,9 +16,21 @@ let expand_str ~dir ~f template =
|
|||
match f var with
|
||||
| Not_found -> None
|
||||
| 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)
|
||||
|
||||
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 =
|
||||
match String_with_vars.just_a_var template with
|
||||
| None -> expand_str ~dir ~f template |> Path.relative dir
|
||||
|
@ -24,9 +38,9 @@ let expand_path ~dir ~f template =
|
|||
match f v with
|
||||
| Not_found -> expand_str ~dir ~f template |> Path.relative dir
|
||||
| Path p
|
||||
| Paths [p] -> p
|
||||
| Paths ([p], _) -> p
|
||||
| Str s -> Path.relative dir s
|
||||
| Paths l ->
|
||||
| Paths (l, _) ->
|
||||
List.map l ~f:(Path.reach ~from:dir)
|
||||
|> String.concat ~sep:" "
|
||||
|> Path.relative dir
|
||||
|
@ -41,17 +55,19 @@ let expand_prog ctx ~dir ~f template =
|
|||
| None -> Utils.program_not_found ~context:ctx.name s
|
||||
in
|
||||
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 ->
|
||||
match f v with
|
||||
| Not_found -> resolve (expand_str ~dir ~f template)
|
||||
| Not_found -> (resolve (expand_str ~dir ~f template), [])
|
||||
| Path p
|
||||
| Paths [p] -> p
|
||||
| Str s -> resolve s
|
||||
| Paths l ->
|
||||
List.map l ~f:(Path.reach ~from:dir)
|
||||
|> String.concat ~sep:" "
|
||||
|> resolve
|
||||
| Paths ([p], _) -> (p, [])
|
||||
| Str s -> (resolve s, [])
|
||||
| Paths (p :: args, Split) -> (p, List.map args ~f:(Path.reach ~from:dir))
|
||||
| Paths (l, _) ->
|
||||
(List.map l ~f:(Path.reach ~from:dir)
|
||||
|> String.concat ~sep:" "
|
||||
|> resolve,
|
||||
[])
|
||||
|
||||
module Outputs = struct
|
||||
include Action_intf.Outputs
|
||||
|
@ -197,8 +213,9 @@ module Unexpanded = struct
|
|||
let rec expand ctx dir t ~f : action =
|
||||
match t with
|
||||
| Run (prog, args) ->
|
||||
Run (expand_prog ctx ~dir ~f prog,
|
||||
List.map args ~f:(fun arg -> expand_str ~dir ~f arg))
|
||||
let prog, more_args = expand_prog ctx ~dir ~f prog in
|
||||
Run (prog,
|
||||
more_args @ List.concat_map args ~f:(expand_str_split ~dir ~f))
|
||||
| Chdir (fn, t) ->
|
||||
let fn = expand_path ~dir ~f fn in
|
||||
Chdir (fn, expand ctx fn t ~f)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
open! Import
|
||||
|
||||
type split_or_concat = Split | Concat
|
||||
|
||||
type var_expansion =
|
||||
| Not_found
|
||||
| Path of Path.t
|
||||
| Paths of Path.t list
|
||||
| Paths of Path.t list * split_or_concat
|
||||
| Str of string
|
||||
|
||||
module Outputs : module type of struct include Action_intf.Outputs end
|
||||
|
|
|
@ -550,13 +550,14 @@ module Action = struct
|
|||
| Some exp -> exp
|
||||
| None ->
|
||||
match var_name with
|
||||
| "@" -> Action.Paths targets
|
||||
| "@" -> Action.Paths (targets, Concat)
|
||||
| "!@" -> Action.Paths (targets, Split)
|
||||
| "<" ->
|
||||
(match deps with
|
||||
| [] -> Str "" (* CR-someday jdimino: this should be an error *)
|
||||
| dep :: _ -> Path dep)
|
||||
| "^" ->
|
||||
Paths deps
|
||||
| "^" -> Paths (deps, Concat)
|
||||
| "!^" -> Paths (deps, Split)
|
||||
| "ROOT" -> Path sctx.context.build_dir
|
||||
| var ->
|
||||
match expand_var_no_root sctx var with
|
||||
|
@ -574,7 +575,7 @@ module Action = struct
|
|||
~f:(fun ~key:_ ~data:exp acc ->
|
||||
match exp with
|
||||
| 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))
|
||||
>>>
|
||||
Build.arr (fun paths -> ((), paths))
|
||||
|
|
Loading…
Reference in New Issue