dune/src/build_interpret.ml

114 lines
3.0 KiB
OCaml

open Import
open Build.Repr
module Pset = Path.Set
module Pmap = Path.Map
module Vspec = Build.Vspec
module Target = struct
type t =
| Normal of Path.t
| Vfile : _ Vspec.t -> t
let path = function
| Normal p -> p
| Vfile (Vspec.T (p, _)) -> p
let paths ts =
List.fold_left ts ~init:Pset.empty ~f:(fun acc t ->
Pset.add (path t) acc)
end
let 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
| Targets _ -> acc
| Store_vfile _ -> 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 fns -> Pset.union fns acc
| Vpath (Vspec.T (fn, _)) -> Pset.add fn acc
| Paths_glob (dir, re) -> begin
match Pmap.find dir (Lazy.force all_targets_by_dir) with
| None -> acc
| Some targets ->
Pset.filter targets ~f:(fun path ->
Re.execp re (Path.basename path))
|> Pset.union acc
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
in
loop (Build.repr t) Pset.empty
let lib_deps =
let rec loop : type a b. (a, b) t -> Build.lib_deps Pmap.t -> Build.lib_deps Pmap.t
= fun t acc ->
match t with
| Arr _ -> acc
| Targets _ -> acc
| Store_vfile _ -> 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
| Vpath _ -> acc
| Paths_glob _ -> acc
| Dyn_paths t -> loop t acc
| Contents _ -> acc
| Lines_of _ -> acc
| Record_lib_deps (dir, deps) ->
let data =
match Pmap.find dir acc with
| None -> deps
| Some others -> Build.merge_lib_deps deps others
in
Pmap.add acc ~key:dir ~data
| Fail _ -> acc
in
fun t -> loop (Build.repr t) Pmap.empty
let targets =
let rec loop : type a b. (a, b) t -> Target.t list -> Target.t list = fun t acc ->
match t with
| Arr _ -> acc
| Targets targets ->
List.fold_left targets ~init:acc ~f:(fun acc fn -> Target.Normal fn :: acc)
| Store_vfile spec -> Vfile spec :: 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
| Vpath _ -> acc
| Paths_glob _ -> acc
| Dyn_paths t -> loop t acc
| Contents _ -> acc
| Lines_of _ -> acc
| Record_lib_deps _ -> acc
| Fail _ -> acc
in
fun t -> loop (Build.repr t) []
module Rule = struct
type t =
{ build : (unit, Action.t) Build.t
; targets : Target.t list
}
let make build =
{ build
; targets = targets build
}
end