What is the preferred way to structure and build OCaml projects?
Asked Answered
T

5

65

It is unclear to newcomers to the ecosystem what is the canonically preferred way to structure and manage building small to medium sized OCaml projects. I understand the basics of ocamlc, &c.--they mirror conventional UNIX C compilers enough to seem straightforward. But, above the level of one-off compilation of individual files, it is unclear how best to manage compilation simply and cleanly. The issue is not searching for potential tools, but seeing one or a few Right (enough) Ways--as validated by the experience of the community--for structuring and building standard OCaml projects.

My model use case is a modest but nontrivial project, of pure OCaml or OCaml plus a C dependency. Such a project:

  1. contains a number of source files
  2. links to a number of standard libraries
  3. links to one or more 3rd party libraries
  4. optionally includes a C library and OCaml wrapper as a subproject (though this could also be managed separately and included as a 3rd party library, as in (3))

Several alternative tools stand out:

  • Custom Makefiles seem to be the common standard in most open source OCaml packages, but appear frustratingly verbose and complex--even more so than for modest C/C++ projects. Worse, many even seemingly simple OCaml libraries layer autoconf/automake on top for even greater complexity.
  • ocamlbuild appears to offer a modern, streamlined mechanism for automating builds with minimal configuration, but it is not well documented for newcomers, nor represented by example in the introductory materials in the OCaml ecosystem, nor visibly used by any of the various published OCaml projects which I have browsed for inspiration.
  • OASIS seems to be a layer of convention and library code atop other build systems to support building a package manager and library, like Cabal.

(I have also seen OMake, which appears to be a self-styled "make++" which also includes a suite of standard rules for common languages, including OCaml, and ocaml-make née OCamlMakefile, providing a template of standard rules for GNU make.)

Are any of these a preferred, modern way of managing OCaml builds?

How are project files best structured?

How are 3rd party library dependencies included and managed? Is it preferred to install them at the system level, or is there a standard and straightforward way of managing them locally to a project? I would much prefer a model in which projects remain as self-contained as possible.

Tanning answered 10/5, 2011 at 20:50 Comment(0)
P
23

You've got a thorough listing of the options available, but this question will not have a clear answer. My personal recommendation is also to use ocamlbuild. The myocamlbuild.ml file provided here is a good start. It will allow you to easily compile projects that depend on various libraries. I don't think it handles the case of binding to C libraries, but there are additional examples on the wiki that may help.

Some people object to ocamlbuild because it is yet another build tool, complicating package managers jobs. However, its ease of use and the fact that it is included in the official distribution is making it more and more widely used.

You can also skip all this and use oasis directly. It is very new, and a stable release has not yet been announced, but it is very usable. It will generate the myocamlbuild.ml automatically for you. This is probably the way to go in the very near future, if not already. Furthermore, by using oasis, you will immediately have the benefit of oasis-db, a CPAN like system for OCaml that is under development.

Regarding managing libraries, the answer is ocamlfind. If you have multiple instances of OCaml installed, calling the appropriate copy of ocamlfind will automatically cause all references to libraries be those for that particular instance, assuming you use ocamlfind systematically for all libraries. I currently use godi to install OCaml and libraries. It uses ocamlfind, and I have no problem having multiple instances of OCaml installed.

Protrude answered 11/5, 2011 at 12:43 Comment(5)
It's been almost three years since this answer. I'd like to share my experience as a newcomer. After much pain I've come to the conclusion that devouring the docs for and using ocamlc, ocamlopt, and ocamlmklib through ocamlfind is the least painful way to build OCaml projects. I've documented my findings here github.com/pacemkr/ocaml-scrypt/blob/master/Makefile I'm sure oasis an myocamlbuild.ml files solve real problems. I tried, I really have, but both tools fail miserably at abstracting the underlying complexity.Tilbury
I consider my response outdated too. Recently I've been using OMake, but I'm unsatisfied with all build tools and hope something fundamentally better will emerge eventually.Protrude
Things are improving,opam doesn't really care about the build system, which is good. ocamlfind makes using ocamlc and friends much easier. These two get me close enough. The hardest part was understanding all the intermediate artifacts (cm*) and where they come from, and the indirection of cclib and similar flags, how they're passed along with a package, custom runtime builds, etc.Tilbury
Another simple Makefile, for posterity: github.com/pacemkr/ocaml-termbox/blob/master/MakefileTilbury
This answer keeps getting more upvotes, for which I am grateful. However, I'd like to be clear that much of what is stated here is no longer true. oasis-db and godi have been superseded by OPAM. I think oasis is still okay for simple projects, but I don't personally use it and feel a better solution could exist. I do use ocamlbuild but ignore most of its features.Protrude
I
15

Personally I'd give +1 for ocamlbuild. It's default rules are good enough to compile small to medium projects with one command and none to very minimal configuration. It also enforces some very reasonable conventions (not mixing sources with build results). And for larger projects it can be customized to one's desire, with extra rules & plugins. At the company where I work we are using it for a large project (Ocaml + some C + some preprocessing + ...) and it works like a charm (and gives us much less headaches than Makefiles would).

As for manuals, I'd think the user guide (available from the author's webpage,) should be enough to get you started. More funky stuff may require a bit more digging.

Intercommunion answered 10/5, 2011 at 21:45 Comment(4)
Completely agree. I'm involved in a large project that uses ocamlfind, preprocessing, and c without too many problems.Herakleion
It certainly seemed the most appealing in my parallel investigation. I will report back once I've gotten off the ground with it.Tanning
To all the ocamlbuild fans out there: remember that you can improve the tool by helping to write documentation, releasing snippets of your interesting home-made myocamlbuild.ml files, or even possibly contributing to the code (but for that you should contact the devs first) for features you would like (easy target on my wishlist : allow to call ocamldoc to produce dot diagrams).Ohalloran
A (not so important?) negative point: I've heard people complain about the poor speedup brought by ocamlbuild when using the parallel flag -j n, compared to the speedup that make -j n achieves.Bellwort
M
10

+1 for OMake.

We revamped our build infrastructure a few years ago and chose OMake for the following reasons:

  • our products are composed of mixture of C, C++, Managed C++, Ruby and OCaml.
  • we target both Linux and Windows.
  • we interact with databases at build time.
  • for some productions we had to use OCaml 3.10.
  • our original build system used autoconf/automake.
  • we require out-of-source builds*.

To be honest I don't know if we could have done it with ocamlbuild, I haven't tested it. The tool is in use for sure since there is some activity around it in OCaml's bugtracker. If you opt for ocamlbuild, make sure you have an up-to-date version of OCaml.

*OMake supports out-of-source builds in a bit non-obvious way. It also has some issues when sources are read-only. We had to patch and rebuild our Windows version of OMake.

Meit answered 11/5, 2011 at 13:51 Comment(1)
I'd like to see a comparison between omake and ocamlbuild. I've used omake with a lot of success. Didn't have as much luck when I tried ocamlbuild, but that was a couple of years ago.Thurston
F
10

The current recommendation is to use Dune, a composable build system that supports OCaml and Reason compilation. It's being actively developed.

The Quickstart page gives a variety of project templates to start with.

Dune can also handle the following:

Opam is the de-facto package manager for OCaml. Besides finding and installing packages, it can also handle multiple OCaml installations.

Esy is a newer, package.json-driven package manager born from the Reason community. Its pitch is that it brings out-of-the-box project sandboxing, and provides an easy way to pull existing opam packages.

Fleecy answered 31/3, 2020 at 2:56 Comment(0)
F
3

good question. I would tend to say :

1) ocamlbuild It is likely to be the standard way to compile, because it is efficient, fast, and the default tool given by the official distribution. The fact that it is in the official distribution is good point, because it is more likely to remain with time. Furthermore, it has ocamlfind enabled, so it can manage packages installed with ocamlfind, another standard for installing packages (ocamlfind is a bit like pkg-config for C)

2) But it won't be enough for your project. The integration with C is basic with ocamlbuild. So here I would maybe advise you to use oasis to finally answer your question. I also tried OMake, but did not like it.

3) However, your build scripts are not likely to work straight if you wan't other people to be able to download and build your project on their own machine. Furthermore, oasis does not handle pkg-config. For those reasons, I would tend to advise you to use ocaml-autoconf (ocaml macros for autotools). Because autotools are the standard for managing C libraries and it is well known by package maintainers. It can also handle cross-compilation...

=> ocaml-autoconf with ocamlbuild

Flosi answered 22/5, 2012 at 17:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.