Resolve path properly in actions
This commit is contained in:
parent
643e43158e
commit
157ecaab60
66
src/build.ml
66
src/build.ml
|
@ -182,29 +182,39 @@ module Shexp = struct
|
||||||
open Future
|
open Future
|
||||||
open Action.Mini_shexp
|
open Action.Mini_shexp
|
||||||
|
|
||||||
let rec exec t ~dir ~env ~env_extra ~stdout_to ~tail =
|
let run ~dir ~env ~env_extra ~stdout_to ~tail prog args =
|
||||||
|
let stdout_to : Future.stdout_to =
|
||||||
|
match stdout_to with
|
||||||
|
| None -> Terminal
|
||||||
|
| Some (fn, oc) -> Opened_file { filename = fn; tail; desc = Channel oc }
|
||||||
|
in
|
||||||
|
let env = Context.extend_env ~vars:env_extra ~env in
|
||||||
|
Future.run Strict ~dir:(Path.to_string dir) ~env ~stdout_to prog args
|
||||||
|
|
||||||
|
let rec exec t ~dir ~env ~env_extra ~stdout_to ~tail ~f =
|
||||||
match t with
|
match t with
|
||||||
| Run (prog, args) ->
|
| Run (prog, args) ->
|
||||||
let stdout_to : Future.stdout_to =
|
let prog = f ~dir prog in
|
||||||
match stdout_to with
|
let args = List.map args ~f:(f ~dir) in
|
||||||
| None -> Terminal
|
run ~dir ~env ~env_extra ~stdout_to ~tail prog args
|
||||||
| Some (fn, oc) -> Opened_file { filename = fn; tail; desc = Channel oc }
|
|
||||||
in
|
|
||||||
let env = Context.extend_env ~vars:env_extra ~env in
|
|
||||||
Future.run Strict ~dir:(Path.to_string dir) ~env ~stdout_to prog args
|
|
||||||
| Chdir (fn, t) ->
|
| Chdir (fn, t) ->
|
||||||
exec t ~env ~env_extra ~stdout_to ~tail ~dir:(Path.relative dir fn)
|
let fn = f ~dir fn in
|
||||||
|
exec t ~env ~env_extra ~stdout_to ~tail ~dir:(Path.relative dir fn) ~f
|
||||||
| Setenv (var, value, t) ->
|
| Setenv (var, value, t) ->
|
||||||
exec t ~dir ~env ~stdout_to ~tail
|
let var = f ~dir var in
|
||||||
|
let value = f ~dir value in
|
||||||
|
exec t ~dir ~env ~stdout_to ~tail ~f
|
||||||
~env_extra:(String_map.add env_extra ~key:var ~data:value)
|
~env_extra:(String_map.add env_extra ~key:var ~data:value)
|
||||||
| With_stdout_to (fn, t) ->
|
| With_stdout_to (fn, t) ->
|
||||||
|
let fn = f ~dir fn in
|
||||||
if tail then Option.iter stdout_to ~f:(fun (_, oc) -> close_out oc);
|
if tail then Option.iter stdout_to ~f:(fun (_, oc) -> close_out oc);
|
||||||
let fn = Path.to_string (Path.relative dir fn) in
|
let fn = Path.to_string (Path.relative dir fn) in
|
||||||
exec t ~dir ~env ~env_extra ~tail
|
exec t ~dir ~env ~env_extra ~tail ~f
|
||||||
~stdout_to:(Some (fn, open_out_bin fn))
|
~stdout_to:(Some (fn, open_out_bin fn))
|
||||||
| Progn l ->
|
| Progn l ->
|
||||||
exec_list l ~dir ~env ~env_extra ~stdout_to ~tail
|
exec_list l ~dir ~env ~env_extra ~stdout_to ~tail ~f
|
||||||
| Echo str ->
|
| Echo str ->
|
||||||
|
let str = f ~dir str in
|
||||||
return
|
return
|
||||||
(match stdout_to with
|
(match stdout_to with
|
||||||
| None -> print_string str; flush stdout
|
| None -> print_string str; flush stdout
|
||||||
|
@ -212,6 +222,7 @@ module Shexp = struct
|
||||||
output_string oc str;
|
output_string oc str;
|
||||||
if tail then close_out oc)
|
if tail then close_out oc)
|
||||||
| Cat fn ->
|
| Cat fn ->
|
||||||
|
let fn = f ~dir fn in
|
||||||
let fn = Path.to_string (Path.relative dir fn) in
|
let fn = Path.to_string (Path.relative dir fn) in
|
||||||
with_file_in fn ~f:(fun ic ->
|
with_file_in fn ~f:(fun ic ->
|
||||||
match stdout_to with
|
match stdout_to with
|
||||||
|
@ -221,8 +232,8 @@ module Shexp = struct
|
||||||
if tail then close_out oc);
|
if tail then close_out oc);
|
||||||
return ()
|
return ()
|
||||||
| Copy_and_add_line_directive (src, dst) ->
|
| Copy_and_add_line_directive (src, dst) ->
|
||||||
let src = Path.relative dir src in
|
let src = Path.relative dir (f ~dir src) in
|
||||||
let dst = Path.relative dir dst in
|
let dst = Path.relative dir (f ~dir dst) in
|
||||||
with_file_in (Path.to_string src) ~f:(fun ic ->
|
with_file_in (Path.to_string src) ~f:(fun ic ->
|
||||||
with_file_out (Path.to_string dst) ~f:(fun oc ->
|
with_file_out (Path.to_string dst) ~f:(fun oc ->
|
||||||
let fn =
|
let fn =
|
||||||
|
@ -234,38 +245,39 @@ module Shexp = struct
|
||||||
copy_channels ic oc));
|
copy_channels ic oc));
|
||||||
return ()
|
return ()
|
||||||
| System cmd ->
|
| System cmd ->
|
||||||
|
let cmd = f ~dir cmd in
|
||||||
let path, arg, err =
|
let path, arg, err =
|
||||||
Utils.system_shell ~needed_to:"interpret (system ...) actions"
|
Utils.system_shell ~needed_to:"interpret (system ...) actions"
|
||||||
in
|
in
|
||||||
match err with
|
match err with
|
||||||
| Some err -> err.fail ()
|
| Some err -> err.fail ()
|
||||||
| None ->
|
| None ->
|
||||||
exec ~dir ~env ~env_extra ~stdout_to ~tail
|
run ~dir ~env ~env_extra ~stdout_to ~tail
|
||||||
(Run (Path.to_string path, [arg; cmd]))
|
(Path.to_string path) [arg; cmd]
|
||||||
|
|
||||||
and exec_list l ~dir ~env ~env_extra ~stdout_to ~tail =
|
and exec_list l ~dir ~env ~env_extra ~stdout_to ~tail ~f =
|
||||||
match l with
|
match l with
|
||||||
| [] ->
|
| [] ->
|
||||||
if tail then Option.iter stdout_to ~f:(fun (_, oc) -> close_out oc);
|
if tail then Option.iter stdout_to ~f:(fun (_, oc) -> close_out oc);
|
||||||
Future.return ()
|
Future.return ()
|
||||||
| [t] ->
|
| [t] ->
|
||||||
exec t ~dir ~env ~env_extra ~stdout_to ~tail
|
exec t ~dir ~env ~env_extra ~stdout_to ~tail ~f
|
||||||
| t :: rest ->
|
| t :: rest ->
|
||||||
exec t ~dir ~env ~env_extra ~stdout_to ~tail:false >>= fun () ->
|
exec t ~dir ~env ~env_extra ~stdout_to ~tail:false ~f >>= fun () ->
|
||||||
exec_list rest ~dir ~env ~env_extra ~stdout_to ~tail
|
exec_list rest ~dir ~env ~env_extra ~stdout_to ~tail ~f
|
||||||
|
|
||||||
let exec t ~dir ~env =
|
let exec t ~dir ~env ~f =
|
||||||
exec t ~dir ~env ~env_extra:String_map.empty ~stdout_to:None ~tail:true
|
exec t ~dir ~env ~env_extra:String_map.empty ~stdout_to:None ~tail:true ~f
|
||||||
end
|
end
|
||||||
|
|
||||||
let action ~dir ~env ~targets =
|
let action action ~dir ~env ~targets =
|
||||||
prim ~targets (fun action ->
|
prim ~targets (fun f ->
|
||||||
match (action : string Action.t) with
|
match (action : _ Action.t) with
|
||||||
| Bash cmd ->
|
| Bash cmd ->
|
||||||
Future.run Strict ~dir:(Path.to_string dir) ~env
|
Future.run Strict ~dir:(Path.to_string dir) ~env
|
||||||
"/bin/bash" ["-e"; "-u"; "-o"; "pipefail"; "-c"; cmd]
|
"/bin/bash" ["-e"; "-u"; "-o"; "pipefail"; "-c"; f ~dir cmd]
|
||||||
| Shexp shexp ->
|
| Shexp shexp ->
|
||||||
Shexp.exec ~dir ~env shexp)
|
Shexp.exec ~dir ~env ~f shexp)
|
||||||
|
|
||||||
let echo fn =
|
let echo fn =
|
||||||
create_file ~target:fn (fun data ->
|
create_file ~target:fn (fun data ->
|
||||||
|
|
|
@ -79,10 +79,11 @@ val run_capture_lines
|
||||||
-> ('a, string list) t
|
-> ('a, string list) t
|
||||||
|
|
||||||
val action
|
val action
|
||||||
: dir:Path.t
|
: 'a Action.t
|
||||||
|
-> dir:Path.t
|
||||||
-> env:string array
|
-> env:string array
|
||||||
-> targets:Path.t list
|
-> targets:Path.t list
|
||||||
-> (string Action.t, unit) t
|
-> (dir:Path.t -> 'a -> string, unit) t
|
||||||
|
|
||||||
(** Create a file with the given contents. *)
|
(** Create a file with the given contents. *)
|
||||||
val echo : Path.t -> (string, unit) t
|
val echo : Path.t -> (string, unit) t
|
||||||
|
|
|
@ -1270,21 +1270,26 @@ module Gen(P : Params) = struct
|
||||||
+-----------------------------------------------------------------+ *)
|
+-----------------------------------------------------------------+ *)
|
||||||
|
|
||||||
module Action_interpret : sig
|
module Action_interpret : sig
|
||||||
|
type expander
|
||||||
|
|
||||||
val expand
|
val expand
|
||||||
: Action.Unexpanded.t
|
: Action.Unexpanded.t
|
||||||
-> dir:Path.t
|
-> dir:Path.t
|
||||||
-> dep_kind:Build.lib_dep_kind
|
-> dep_kind:Build.lib_dep_kind
|
||||||
-> targets:string list
|
-> targets:Path.t list
|
||||||
-> deps:Dep_conf.t list
|
-> deps:Dep_conf.t list
|
||||||
-> (unit, string Action.t) Build.t
|
-> (unit, expander) Build.t
|
||||||
|
|
||||||
val run
|
val run
|
||||||
: dir:Path.t
|
: Action.Unexpanded.t
|
||||||
|
-> dir:Path.t
|
||||||
-> targets:Path.t list
|
-> targets:Path.t list
|
||||||
-> (string Action.t, unit) Build.t
|
-> (expander, unit) Build.t
|
||||||
end = struct
|
end = struct
|
||||||
module U = Action.Unexpanded
|
module U = Action.Unexpanded
|
||||||
|
|
||||||
|
type expander = dir:Path.t -> String_with_vars.t -> string
|
||||||
|
|
||||||
type artefact =
|
type artefact =
|
||||||
| Direct of Path.t
|
| Direct of Path.t
|
||||||
| Dyn of (unit, Path.t) Build.t
|
| Dyn of (unit, Path.t) Build.t
|
||||||
|
@ -1301,31 +1306,36 @@ module Gen(P : Params) = struct
|
||||||
String_map.add acc ~key:var ~data:(Dyn (N.in_findlib ~dir ~dep_kind s))
|
String_map.add acc ~key:var ~data:(Dyn (N.in_findlib ~dir ~dep_kind s))
|
||||||
| _ -> acc)
|
| _ -> acc)
|
||||||
|
|
||||||
let expand t ~artifact_map ~dir ~targets ~deps =
|
let expand_string_with_vars ~artifact_map ~targets ~deps : expander =
|
||||||
let dep_exn name = function
|
let dep_exn ~dir name = function
|
||||||
| Some dep -> dep
|
| Some dep -> Path.reach ~from:dir dep
|
||||||
| None -> die "cannot use ${%s} with files_recursively_in" name
|
| None -> die "cannot use ${%s} with files_recursively_in" name
|
||||||
in
|
in
|
||||||
let lookup var_name =
|
let lookup ~dir var_name =
|
||||||
match String_map.find var_name artifact_map with
|
match String_map.find var_name artifact_map with
|
||||||
| Some path -> Some (Path.reach ~from:dir path)
|
| Some path -> Some (Path.reach ~from:dir path)
|
||||||
| None ->
|
| None ->
|
||||||
match var_name with
|
match var_name with
|
||||||
| "@" -> Some (String.concat ~sep:" " targets)
|
| "@" -> Some (String.concat ~sep:" " (List.map targets ~f:(Path.reach ~from:dir)))
|
||||||
| "<" -> Some (match deps with [] -> "" | dep1::_ -> dep_exn var_name dep1)
|
| "<" -> Some (match deps with [] -> "" | dep1::_ -> dep_exn ~dir var_name dep1)
|
||||||
| "^" ->
|
| "^" ->
|
||||||
let deps = List.map deps ~f:(dep_exn var_name) in
|
let deps = List.map deps ~f:(dep_exn ~dir var_name) in
|
||||||
Some (String.concat ~sep:" " deps)
|
Some (String.concat ~sep:" " deps)
|
||||||
| _ -> root_var_lookup ~dir var_name
|
| _ -> root_var_lookup ~dir var_name
|
||||||
in
|
in
|
||||||
U.expand t ~f:lookup
|
fun ~dir str ->
|
||||||
|
String_with_vars.expand str ~f:(lookup ~dir)
|
||||||
|
|
||||||
let expand t ~dir ~dep_kind ~targets ~deps =
|
let expand t ~dir ~dep_kind ~targets ~deps =
|
||||||
let deps = List.map deps ~f:(Dep_conf_interpret.only_plain_file ~dir) in
|
let deps =
|
||||||
|
List.map deps ~f:(fun dep ->
|
||||||
|
Option.map (Dep_conf_interpret.only_plain_file ~dir dep)
|
||||||
|
~f:(Path.relative dir))
|
||||||
|
in
|
||||||
let needed_artifacts = extract_artifacts ~dir ~dep_kind t in
|
let needed_artifacts = extract_artifacts ~dir ~dep_kind t in
|
||||||
if String_map.is_empty needed_artifacts then
|
if String_map.is_empty needed_artifacts then
|
||||||
let s = expand t ~dir ~artifact_map:String_map.empty ~targets ~deps in
|
let expand = expand_string_with_vars ~artifact_map:String_map.empty ~targets ~deps in
|
||||||
Build.return s
|
Build.return expand
|
||||||
else begin
|
else begin
|
||||||
let directs, dyns =
|
let directs, dyns =
|
||||||
String_map.bindings needed_artifacts
|
String_map.bindings needed_artifacts
|
||||||
|
@ -1347,11 +1357,11 @@ module Gen(P : Params) = struct
|
||||||
let artifact_map =
|
let artifact_map =
|
||||||
String_map.of_alist_exn (List.rev_append directs artifacts)
|
String_map.of_alist_exn (List.rev_append directs artifacts)
|
||||||
in
|
in
|
||||||
expand t ~dir ~artifact_map ~targets ~deps)
|
expand_string_with_vars ~artifact_map ~targets ~deps)
|
||||||
end
|
end
|
||||||
|
|
||||||
let run ~dir ~targets =
|
let run action ~dir ~targets =
|
||||||
Build.action ~dir ~env:ctx.env ~targets
|
Build.action action ~dir ~env:ctx.env ~targets
|
||||||
end
|
end
|
||||||
|
|
||||||
(* +-----------------------------------------------------------------+
|
(* +-----------------------------------------------------------------+
|
||||||
|
@ -1367,10 +1377,11 @@ module Gen(P : Params) = struct
|
||||||
rule.action
|
rule.action
|
||||||
~dir
|
~dir
|
||||||
~dep_kind:Required
|
~dep_kind:Required
|
||||||
~targets:rule.targets
|
~targets
|
||||||
~deps:rule.deps
|
~deps:rule.deps
|
||||||
>>>
|
>>>
|
||||||
Action_interpret.run
|
Action_interpret.run
|
||||||
|
rule.action
|
||||||
~dir
|
~dir
|
||||||
~targets)
|
~targets)
|
||||||
|
|
||||||
|
@ -1402,7 +1413,7 @@ module Gen(P : Params) = struct
|
||||||
~dep_kind:Required
|
~dep_kind:Required
|
||||||
~targets:[]
|
~targets:[]
|
||||||
~deps:alias_conf.deps
|
~deps:alias_conf.deps
|
||||||
>>> Action_interpret.run ~dir ~targets:[] in
|
>>> Action_interpret.run action ~dir ~targets:[] in
|
||||||
add_rule (deps >>> dummy)
|
add_rule (deps >>> dummy)
|
||||||
|
|
||||||
(* +-----------------------------------------------------------------+
|
(* +-----------------------------------------------------------------+
|
||||||
|
|
Loading…
Reference in New Issue