Distinguish rule dependencies from action dependencies
This commit is contained in:
parent
b7ad08df84
commit
be3593e449
|
@ -4,7 +4,44 @@ open Build.Repr
|
|||
module Pset = Path.Set
|
||||
module Pmap = Path.Map
|
||||
|
||||
let deps t ~all_targets_by_dir =
|
||||
let rule_deps t ~all_targets_by_dir =
|
||||
let rec loop : type a b. (a, b) t -> Pset.t -> Pset.t = fun t acc ->
|
||||
match t with
|
||||
| Arr _ -> acc
|
||||
| Compose (a, b) -> loop a (loop b acc)
|
||||
| First t -> loop t acc
|
||||
| Second t -> loop t acc
|
||||
| Split (a, b) -> loop a (loop b acc)
|
||||
| Fanout (a, b) -> loop a (loop b acc)
|
||||
| Paths _ -> acc
|
||||
| Paths_glob _ -> acc
|
||||
| If_file_exists (p, state) -> begin
|
||||
match !state with
|
||||
| Decided (_, t) -> loop t acc
|
||||
| Undecided (then_, else_) ->
|
||||
let dir = Path.parent p in
|
||||
let targets =
|
||||
Option.value (Pmap.find dir (Lazy.force all_targets_by_dir))
|
||||
~default:Pset.empty
|
||||
in
|
||||
if Pset.mem p targets then begin
|
||||
state := Decided (true, then_);
|
||||
loop then_ acc
|
||||
end else begin
|
||||
state := Decided (false, else_);
|
||||
loop else_ acc
|
||||
end
|
||||
end
|
||||
| Dyn_paths t -> loop t acc
|
||||
| Contents p -> Pset.add p acc
|
||||
| Lines_of p -> Pset.add p acc
|
||||
| Record_lib_deps _ -> acc
|
||||
| Fail _ -> acc
|
||||
| Memo m -> loop m.t acc
|
||||
in
|
||||
loop (Build.repr t) Pset.empty
|
||||
|
||||
let static_action_deps t ~all_targets_by_dir =
|
||||
let rec loop : type a b. (a, b) t -> Pset.t -> Pset.t = fun t acc ->
|
||||
match t with
|
||||
| Arr _ -> acc
|
||||
|
@ -22,26 +59,10 @@ let deps t ~all_targets_by_dir =
|
|||
Re.execp re (Path.basename path))
|
||||
|> Pset.union acc
|
||||
end
|
||||
| If_file_exists (p, state) -> begin
|
||||
match !state with
|
||||
| Decided (exists, t) -> loop t (if exists then Pset.add p acc else acc)
|
||||
| Undecided (then_, else_) ->
|
||||
let dir = Path.parent p in
|
||||
let targets =
|
||||
Option.value (Pmap.find dir (Lazy.force all_targets_by_dir))
|
||||
~default:Pset.empty
|
||||
in
|
||||
if Pset.mem p targets then begin
|
||||
state := Decided (true, then_);
|
||||
loop then_ (Pset.add p acc)
|
||||
end else begin
|
||||
state := Decided (false, else_);
|
||||
loop else_ acc
|
||||
end
|
||||
end
|
||||
| If_file_exists (_, state) -> loop (get_if_file_exists_exn state) acc
|
||||
| Dyn_paths t -> loop t acc
|
||||
| Contents p -> Pset.add p acc
|
||||
| Lines_of p -> Pset.add p acc
|
||||
| Contents _ -> acc
|
||||
| Lines_of _ -> acc
|
||||
| Record_lib_deps _ -> acc
|
||||
| Fail _ -> acc
|
||||
| Memo m -> loop m.t acc
|
||||
|
|
|
@ -10,7 +10,13 @@ module Rule : sig
|
|||
val make : ?sandbox:bool -> targets:Path.t list -> (unit, Action.t) Build.t -> t
|
||||
end
|
||||
|
||||
val deps
|
||||
(* must be called first *)
|
||||
val rule_deps
|
||||
: (_, _) Build.t
|
||||
-> all_targets_by_dir:Path.Set.t Path.Map.t Lazy.t
|
||||
-> Path.Set.t
|
||||
|
||||
val static_action_deps
|
||||
: (_, _) Build.t
|
||||
-> all_targets_by_dir:Path.Set.t Path.Map.t Lazy.t
|
||||
-> Path.Set.t
|
||||
|
|
|
@ -19,7 +19,8 @@ end
|
|||
|
||||
module Rule = struct
|
||||
type t =
|
||||
{ deps : Pset.t
|
||||
{ rule_deps : Pset.t
|
||||
; static_deps : Pset.t
|
||||
; targets : Pset.t
|
||||
; build : (unit, Action.t) Build.t
|
||||
; mutable exec : Exec_status.t
|
||||
|
@ -276,7 +277,8 @@ let sandbox_dir = Path.of_string "_build/.sandbox"
|
|||
|
||||
let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
|
||||
let { Pre_rule. build; targets; sandbox } = pre_rule in
|
||||
let deps = Build_interpret.deps build ~all_targets_by_dir in
|
||||
let rule_deps = Build_interpret.rule_deps build ~all_targets_by_dir in
|
||||
let static_deps = Build_interpret.static_action_deps build ~all_targets_by_dir in
|
||||
|
||||
if !Clflags.debug_rules then begin
|
||||
let f set =
|
||||
|
@ -284,6 +286,7 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
|
|||
|> List.map ~f:Path.to_string
|
||||
|> String.concat ~sep:", "
|
||||
in
|
||||
let deps = Pset.union rule_deps static_deps in
|
||||
let lib_deps = Build_interpret.lib_deps build in
|
||||
if Pmap.is_empty lib_deps then
|
||||
Printf.eprintf "{%s} -> {%s}\n" (f deps) (f targets)
|
||||
|
@ -303,12 +306,16 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
|
|||
|
||||
let exec = Exec_status.Not_started (fun ~targeting ->
|
||||
make_local_parent_dirs t targets ~map_path:(fun x -> x);
|
||||
wait_for_deps t deps ~targeting
|
||||
>>= fun () ->
|
||||
let action, dyn_deps = Build_exec.exec build () in
|
||||
wait_for_deps t ~targeting (Pset.diff dyn_deps deps)
|
||||
>>= fun () ->
|
||||
let all_deps = Pset.union deps dyn_deps in
|
||||
Future.both
|
||||
(wait_for_deps t static_deps ~targeting)
|
||||
(wait_for_deps t rule_deps ~targeting
|
||||
>>= fun () ->
|
||||
let action, dyn_deps = Build_exec.exec build () in
|
||||
wait_for_deps t ~targeting (Pset.diff dyn_deps static_deps)
|
||||
>>| fun () ->
|
||||
(action, dyn_deps))
|
||||
>>= fun ((), (action, dyn_deps)) ->
|
||||
let all_deps = Pset.union static_deps dyn_deps in
|
||||
if !Clflags.debug_actions then
|
||||
Format.eprintf "@{<debug>Action@}: %s@."
|
||||
(Sexp.to_string (Action.sexp_of_t action));
|
||||
|
@ -407,8 +414,9 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
|
|||
) in
|
||||
let rule =
|
||||
{ Rule.
|
||||
deps = deps
|
||||
; targets = targets
|
||||
static_deps
|
||||
; rule_deps
|
||||
; targets
|
||||
; build
|
||||
; exec
|
||||
}
|
||||
|
@ -566,7 +574,8 @@ module File_closure =
|
|||
type graph = t
|
||||
type t = Path.t * Rule.t
|
||||
let key (path, _) = path
|
||||
let deps (_, rule) bs = rules_for_files bs (Pset.elements rule.Rule.deps)
|
||||
let deps (_, rule) bs =
|
||||
rules_for_files bs (Pset.elements (Pset.union rule.Rule.static_deps rule.Rule.rule_deps))
|
||||
end)
|
||||
|
||||
let rules_for_targets t targets =
|
||||
|
|
Loading…
Reference in New Issue