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
p1
andp2
build 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/src
needs a plugin to build you will have to integrate it intop1
andp2
'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
.