Working on dependent projects with ocamlbuild
From Gallium
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
file 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
.