diff --git a/lib/build.ml b/lib/build.ml index e9d4272..75e2cb6 100644 --- a/lib/build.ml +++ b/lib/build.ml @@ -112,8 +112,11 @@ let of_project p = List.iter (fun r -> let cmd = Array.of_list r.rcmd in + (* a tool the rule runs is an input like any other, so building it first is + ordering and rebuilding it is invalidation *) + let tools = List.filter_map (fun u -> Option.map (out_of p) (find p u)) r.ruses in add - (Graph.make ~id:!n ~tag:"gen" ~label:r.rdesc ~cmd ~outs:r.routs ~ins:r.rin ())) + (Graph.make ~id:!n ~tag:"gen" ~label:r.rdesc ~cmd ~outs:r.routs ~ins:(r.rin @ tools) ())) p.rules; let outputs = Hashtbl.create 16 in List.iter diff --git a/lib/resolve.ml b/lib/resolve.ml index 8de7b97..ada0cf7 100644 --- a/lib/resolve.ml +++ b/lib/resolve.ml @@ -5,7 +5,7 @@ let target_fields = [ "srcs"; "include"; "use"; "cflags"; "cxxflags"; "ldflags"; "define"; "pkg"; "install"; "soname"; "args" ] -let rule_fields = [ "inputs"; "outputs"; "command"; "description" ] +let rule_fields = [ "inputs"; "outputs"; "use"; "command"; "description" ] let install_fields = [ "files"; "to" ] let script_fields = [ "use"; "command" ] @@ -75,6 +75,7 @@ let rules_of blocks = { rname = b.bname; rin = [ f ]; + ruses = texts (get b "use"); routs; rcmd = List.map (subst table) command; rdesc = subst table descr; @@ -230,6 +231,16 @@ let project (env : Eval.env) = | Some _ -> ()) t.uses) targets; + List.iter + (fun (r : rule) -> + List.iter + (fun u -> + if find p u = None then + Diag.error ~span:r.rspan + ~hint:(Suggest.hint u (List.map (fun (x : target) -> x.name) targets)) + "rule %s uses %S, which is not a target" r.rname u) + r.ruses) + p.rules; let seen_runs = Hashtbl.create 4 in List.iter (fun (s : script) -> diff --git a/lib/types.ml b/lib/types.ml index 532d3d4..f28be30 100644 --- a/lib/types.ml +++ b/lib/types.ml @@ -24,6 +24,7 @@ type target = { type rule = { rname : string; rin : string list; + ruses : string list; routs : string list; rcmd : string list; rdesc : string;