114 lines
3.0 KiB
OCaml
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
|