Version française
Home     About     Download     Resources     Contact us    
Browse thread
Ocamlbuild plugins
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Nicolas Pouillard <nicolas.pouillard@g...>
Subject: Re: [Caml-list] Ocamlbuild plugins
Excerpts from Dario Teixeira's message of Mon Nov 05 21:34:09 +0100 2007:
> Hi,
> 
> (I sent a similar message to this ocaml-beginner's list, but I have the
> feeling this will require the assistance of some heavy-weights...)
> 
> First, -- and sorry if the answer is obvious -- I still haven't been able
> to find Ocamlbuild's documentation about the construction of plugins.  All
> I discovered about Ocamlbuild is a brief presentation, the (incomplete)
> user manual, and the wiki, which are found at the following addresses:
> 
> http://gallium.inria.fr/~pouillar/ocamlbuild/ocamlbuild-presentation.html
> http://gallium.inria.fr/~pouillar/ocamlbuild/ocamlbuild-user-guide.html
> http://brion.inria.fr/gallium/index.php/Ocamlbuild

On  my  page [1] there is also a plugin example [2] and the API [3], where the
module  signature [4] can be a good starting point about what tools we have in
an ocamlbuild plugin.

[1]: http://gallium.inria.fr/~pouillar
[2]: http://gallium.inria.fr/~pouillar/ocamlbuild/plugin_example.html 
[3]: http://gallium.inria.fr/~pouillar/ocamlbuild/html
[4]: http://gallium.inria.fr/~pouillar/ocamlbuild/html/Signatures.html

> Now, the wiki has a few example plugins, and I've tried to dissect
> them, but I still have this nagging feeling there must be somewhere
> some documentation that introduces how these plugins work.  I've been
> cursing at google for a while now, so I am asking directly on this
> list -- where are those missing pieces?  (It's okay if they're not
> in English)

There  is  certainly  some  missing pieces. Roughly an ocamlbuild plugin is an
OCaml  module  called  Myocamlbuild  that should take place a the root of your
project  (myocamlbuild.ml).  Automatically  ocamlbuild will take care of it by
compiling  it  and  by  making  a  myocamlbuild  binary  that is the classical
ocamlbuild plus your module.

With  this  module  you can make effects on the ocamlbuild engine by extending
rules,  flag  injectors, dependencies injectors, libraries declarations... You
can  also  change  default  options  of  ocamlbuild  to  avoid giving flags to
ocamlbuild itself.

In  order  to  properly sequence your effects ocamlbuild tells you to register
your  effects  using  the  `dispatch'  function  that  you will found in every
ocamlbuild  plugin.  This  function receive an argument that is an event, like
After_rules that means that rules of the standard library have been setup.

> Anyway, what I intend to do is actually very simple.  In "classic"
> makefile notation it is expressed as follows:  (note the use of findlib)
> 
> database.cmo: database.ml
>         PGDATABASE=lambdium ocamlfind ocamlc -package
> threads,pgocaml.statements -syntax camlp4o -thread -c $<

Here you follow the make convention that says :

"when you have an exception to a rule, provide another rule more precise"

In  ocamlbuild  that's  still feasible but we tend to avoid it in order to not
rely  on  rules  directly. This facilitate having rules in a library. To do so
ocamlbuild provide another way to specify exceptions to a rule.

This  mechanism  allow  to inject flags (-syntax ... -thread) precisely where
they are needed.

Firstly since you want to use ocamlfind you should start with this plugin [5].

Then  since  -thread  is  a  standard  thing you can use the tag "thread" (and
remove threads from the list of package).

For -syntax you should add your own declaration like in [6] but using -package:

let flags in = S[A"-package"; A"pgocaml.statements"; A"-syntax"; A"camlp4o"] in
flag ["ocaml"; "compile"; "use_pgocaml_statements"];
flag ["ocaml"; "ocamldep"; "use_pgocaml_statements"];

You can then tag your files in the _tags file:

"database.ml": use_pgocaml_statements, thread

[5]: http://brion.inria.fr/gallium/index.php/Using_ocamlfind_with_ocamlbuild
[6]: http://brion.inria.fr/gallium/index.php/A_plugin_for_camlp4_syntax_extension_%28pa_openin%29

> So basically I declare an environment variable PGDATABASE, and
> invoke the compiler (via findlib) with a Camlp4 preprocessing stage.
> (The pgocaml.statements package instructs findlib about the module to
> use for Camlp4; the contents of findlib's META file are listed at the
> end of this message).

The  non-handled part is the PGDATABASE env var. To do so you can fall back to
writing  your  specific  rule  with  ocamlbuild (the rule function), however I
don't  recommend  that.  The  second  solution should be give this argument to
ocamlbuild itself.

> I've been looking at how to encode this in Ocamlbuild but I've tripped
> over some basic problems.  First, how are plugins invoked?  Second,
> I cannot find the "Ocamlbuild_plugin" module that is opened by all the
> examples (I am using GODI).  Third, how do I even start to implement
> the Ocamlbuild code to compile the code above?

I don't know if GODI properly install as many things as ocamlbuild needs.

-- 
Nicolas Pouillard aka Ertai