Working on dependent projects with ocamlbuild
If you are on a file system that supports symbolic links, the following
setup allows to work simultaneously on a base project and two
independent projects p1 and p2 that depend on base. The setup is
very simple and any change to the sources of base automatically gets
propagated in the builds of p1 and p2.
Suppose the sources are distributed as follows :
base/src
p1/src
p2/src
Simply create these symbolic links :
ln -s ../base/src p1/base
ln -s ../base/src p2/base
and modify p1 and p2's _tags files as follows :
echo "<base>: include" >> p1/_tags
echo "<base>: include" >> p2/_tags
The rest will be sorted out by ocamlbuild. When a change is done in
base/src nothing needs to be recompiled there: new builds of p1 or
p2 will automatically use the latest version of base's sources.
Internal and external project interface
Sometimes in the base project you want to have both an internal and an
external interface for module definitions. For example in the following
layout assume b.ml accesses definitions in a.ml that clients of the
base project should not see.
base/src/a.ml
base/src/b.ml
In order to do this, adjust the directory layout to :
base/src/internal/a.ml
base/src/internal/b.ml
base/src/base.ml
base/src/base.mli
With base.ml as follows :
module A = A
module B = B
and base.mli restricting the signatures of A and B as needed.
Finally add the following p1/myocamlbuild.ml and p2/myocamlbuild.ml
plugins.
open Ocamlbuild_plugin;;
open Ocamlbuild_pack;;
dispatch begin function
| After_rules ->
Pathname.define_context "base" ["base/internal"]
| _ -> ()
end;;
Caveats
Scalability. Since both
p1andp2build their own version ofbase, this means longer build times after anocamlbuild -clean. On the other hand with ocamlbuild you don't need to clean as much as you had with makefiles.If
base/srcneeds a plugin to build you will have to integrate it intop1andp2's myocamlbuild.ml. This caveat may be removed in the future once ocamlbuild supports multiple plugins. Note that if you are only using tagged caml sources nothing special needs to be done, just put your tags inbase/src/_tags.