+(* Goals uses the goal (name + parameters) as the key to
+ * ensure you cannot have two jobs running at the same time
+ * which would interfere with each other by trying to build
+ * the same target.
+ *)
+module Jobs = Jobs.Make (
+ struct
+ type t = string * Ast.expr list
+ let compare = compare
+ let to_string (name, args) =
+ sprintf "%s (%s)" name
+ (String.concat ", " (List.map (Ast.string_expr ()) args))
+ end
+)
+
+let stop_all = Jobs.stop_all
+
+(* Starts the target expressions running and waits for them to complete. *)
+let rec run_targets_to_completion env exprs =
+ let group = Jobs.new_group () in
+ run_targets group env exprs;
+ Jobs.wait group
+
+(* This starts the targets, adding them to the jobs group, but does not
+ * wait for them to complete.
+ *)
+and run_targets group env exprs =
+ List.iter (run_target group env) exprs