MPR#5285: ocamlbuild: provide a way to run some rules in source directory
PR transferred from https://caml.inria.fr/mantis/view.php?id=5285 [original reporter: @ygrek]
Sometimes it is desirable to keep generated files (e.g. some source-to-source transformation or code generation by third-party tools) in VCS and hence in source directory, not in _build. But all custom myocamlbuild rules get executed in _build and the result is also stored there. Moreover, copying result to the source directory prevents ocamlbuild from rebuilding it on the next run.
Currently I am using extra rules in Makefile to generate such files.
I wish I could specify these rules in myocamlbuild (maybe some per-rule flag to run it in source directory (but that would probably break parallel building because of process-wide chdir effect). Any ideas?
I don't really understand what the intended semantics is: if we copy the produced target to the source directory then, sure, ocamlbuild will copy it to _build instead of rebuilding next time, unless a stamp rule is used to force rerunning the command (this is what I do in my rule to update parser.messages with Menhir's .messages file, which contain a mix of parser-generated and human-edited contents, see at the end of this message.).
A priori I would prefer to keep the design where all build commands are run in _build, with people having the freedom to specify things that touch the source directly in myocamlbuild.ml (but this should almost never be used). I am not sure what ocamlbuild change would improve the situation here.
(* when running `ocamlbuild foo.messages.update`,
this rule will update the "foo.messages" file in the repository
with the result of `menhir foo.mly --update-errors foo.messages`;
this rule by itself does not copy the resulting `_build/foo.messages`
back in the source directory, this is the user's responsibility. *)
let menhir_update_messages env build =
let mly = env "%.mly" in
let messages = env "%.messages" in
let tmp = Filename.temp_file "menhir" ".messages" in
Seq [
Cmd(S[menhir (); T (menhir_tags mly); P mly;
A "--update-errors"; P messages;
Sh ">"; P tmp]);
Cmd(S[A "mv"; P tmp; P messages]);
]