From: Gabriel Scherer <gabriel.scherer@gmail.com>
To: "François Pottier" <francois.pottier@inria.fr>
Cc: caml users <caml-list@inria.fr>, github@mjambon.com
Subject: Re: [Caml-list] cppo, ocamlbuild, and dependencies
Date: Wed, 1 Feb 2017 11:19:44 +0100 [thread overview]
Message-ID: <CAPFanBH-yhmSVUrob1pWh2iE=buetsND=0921UQfow2YseXDcw@mail.gmail.com> (raw)
In-Reply-To: <58910692.1060706@inria.fr>
Yes, the cppo ocamlbuild plugin
https://github.com/mjambon/cppo/blob/master/ocamlbuild_plugin/ocamlbuild_cppo.ml
does not currently perform any kind of dynamic dependency computation.
I think the best way for this to be implemented would be at the level
of cppo, have a kind of -list-includes flag that would run on a
.cppo.* file and return the list of includes. Then you could easily
change the cppo rule to call this first, dynamically build all these
dependencies, and proceed with normal cppo processing. (I believe this
is roughly how `gcc -M` works.)
In the meantime, I implemented an amusing hack at the ocamlbuild level
which is to simply parse the failure message and, if it complains
about a missing file, recursively build that file as a dynamic
dependency. It seems to work.
(The code below is just a change over the main function of cppo's
ocamlbuild plugin. To use it in your program, copy the cppo's
ocamlbuild source in your myocamlbuild.ml, replace the relevant
function, and at the end add "let () = dispatch dispatcher" or
whatever dispatch logic you wish.)
let cppo_rules ext =
let dep = "%(name).cppo"-.-ext
and prod1 = "%(name: <*> and not <*.cppo>)"-.-ext
and prod2 = "%(name: <**/*> and not <**/*.cppo>)"-.-ext in
let cppo_rule prod env build =
let dep = env dep in
let prod = env prod in
let tags = tags_of_pathname prod ++ "cppo" in
let cppo = S[A "cppo"; T tags; S [A "-o"; Px prod]; P dep] in
let rec retry tmp =
let cppo_to_tmp = S[cppo; Sh "2>"; P tmp ] in
let cppo_cmd = Command.to_string (Cmd cppo_to_tmp) in
match Sys.command cppo_cmd with
| 0 -> Nop
| _ ->
let cppo_result = read_file tmp in
let error = Str.regexp
{|Error: Cannot find included file "\([^"]*\)"|} in
(* If we cannot find the dependency,
or if building the dependency fails,
we return the original cppo command.
This will do a bit of useless work but give a better error
message than having the rule raise an exception here, as it
will present the failure in terms of the cppo error message
the user knows about, instead of backtracking in other
rules. *)
match Str.search_forward error cppo_result 0 with
| exception Not_found -> Cmd cppo
| _pos ->
let dep = Str.matched_group 1 cppo_result in
match build [[dep]] with
| [Outcome.Good _dep] -> retry tmp
| _ -> Cmd cppo
in
with_temp_file "ocamlbuild_cppo" "stderr" retry
in
rule ("cppo: *.cppo."-.-ext^" -> *."-.-ext)
~dep ~prod:prod1 (cppo_rule prod1);
rule ("cppo: **/*.cppo."-.-ext^" -> **/*."-.-ext)
~dep ~prod:prod2 (cppo_rule prod2)
P.S.: Upon sending this message, GMail says:
> It seems like you forgot to attach a file.
> You wrote "find included" in your message, but there are no files attached.
> Send anyway?
On Tue, Jan 31, 2017 at 10:50 PM, François Pottier
<francois.pottier@inria.fr> wrote:
>
> Dear OCaml users,
>
> I am trying to use cppo and ocamlbuild together.
>
> Suppose the file a.cppo.ml contains the line:
> #include "b.cppo.ml".
>
> Then, the build fails. As far as I understand, ocamlbuild is not aware of
> the
> dependency a.cppo.ml -> b.cppo.ml, so the source file b.cppo.ml is not even
> copied to the _build directory.
>
> I am using the build rules bundled with cppo (in the module
> Ocamlbuild_cppo).
>
> Shouldn't these build rules be improved so as to perform a genuine
> dependency
> computation? Has anyone run into this issue?
>
> Thanks,
>
> --
> François Pottier
> francois.pottier@inria.fr
> http://gallium.inria.fr/~fpottier/
next prev parent reply other threads:[~2017-02-01 10:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-31 21:50 François Pottier
2017-02-01 10:19 ` Gabriel Scherer [this message]
2017-02-01 13:40 ` François Pottier
2017-02-01 17:10 ` Gabriel Scherer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAPFanBH-yhmSVUrob1pWh2iE=buetsND=0921UQfow2YseXDcw@mail.gmail.com' \
--to=gabriel.scherer@gmail.com \
--cc=caml-list@inria.fr \
--cc=francois.pottier@inria.fr \
--cc=github@mjambon.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox