I'm trying to write an ocamlbuild plugin. The goal is to build Qt apps (without OCaml code for the time being). To handle the final linking phase, I have written the list of objs, mocs, uis and rcs in a .qtobjs file (like a .itarget), and the list of Qt libs in a .qtpackages file. The rule that applies to these files parses these lists and dynamically builds the objects, mocs and so on before linking everything.
The problem is that I would like not to dynamically build the targets that have not changed. See the rule below:
rule "Link a c++ executable that uses Qt."
~deps:["%.qtobjs"; "%.qtpackages"]
~prod:"%.cxxnative"
(fun env build ->
let dir = Pathname.dirname (env "%.qtobjs") in
let output = env "%.cxxnative" in
let objlist = pwd / (env "%.qtobjs") in
let liblist = pwd / (env "%.qtpackages") in
let packages = read_lines liblist in
let lflags = List.map (fun p -> "-l"^p) packages
@ find_all "lflags" in
let objs = List.map (fun o -> dir / o) (read_lines objlist) in
(* Here, I would like to forget the targets that have not changed *)
let objs_to_build = List.filter
(fun target ->
(* something to tell if "target" has to be rebuilt *))
objs in
(* This is where I build the dependencies : *)
let success_builds = build
(List.map (fun o -> [o])
objs_to_build) in
let objects = filter_map
(function
| Outcome.Good x when get_extension x = "opp" ->
Some (pwd / "_build" / (update_extension "o" x))
| Outcome.Good _ -> None
(* Because I don't want to link the ui.h file generated by uic *)
| Outcome.Bad exn -> raise exn)
success_builds in
let tags_objs = tags_of_pathname (env "%.qtobjs") ++ "link" in
let tags_packs = tags_of_pathname (env "%.qtpackages") in
Cmd (S [A (find_one "cxx"); T tags_objs; T tags_packs; Command.atomize lflags;
A "-o"; P output; Command.atomize objects]));
I would like not to call "build" when it's not necessary.
NB: a function
newer_than: Pathname.t -> Pathname.t -> bool
could solve my problem.