In the course of my work with OCaml I have traditionally resisted using anything other than “pure” OCaml, and the facilities of the underlying OS. So rather than OMake or OASIS I just used plain, old-fashioned Makefiles. For package management, I relied on APT on Debian and MacPorts on OSX. And I avoided both Batteries and Core. No so much out of a fear of “backing the wrong horse” but just to make whatever I did as portable and easy to adopt as possible. And also, in the early days, I didn’t really know enough to choose anyway, and I wanted to work with the raw language rather than a high-level framework. Sort of like you can learn to program MFC without ever really learning C++.
But now Real World OCaml (which I have on pre-order) is in final draft, and spent some of yesterday getting my Debian and OSX environments set up for it†. One quirk I quickly found is that both have
pkgconfig as a prereq, which for whatever reason, neither system had already, and that’s not mentioned on the page, maybe everyone else has it by default. I have a bunch of OCaml stuff in-flight at the moment – OCI*ML test suite and new features, some playing with Project Euler (solved
1516 problems at time of writing) and now working my way through this (trying not to skip to FFI which is a keen interest of mine, obviously!). That’s on top of playing with Oracle 12c, and I have barely started properly playing with C++11 new features yet!
† Links to the draft of the book will stop working at some point I expect…
I am not sure about your statement concerning ‘portability’ of Makefile. OASIS has been designed to provide a very good portability (OASIS itself compiles cleanly on Mac OS X, Windows and Linux) and to prevent extremly common mistake.
Just to give you a very simple example, taken from your OC*ML Makefile:
all: ociml.cma ociml.cmxa
It won’t compile on architecture that don’t have ocamlopt !
ocamlfind install ociml META ociml.a ociml.cma ociml.cmxa ociml.cmi dllociml.so libociml.a
On Windows you have to change this line because it is not .so and .a
Not to mention that all your target must be dependencies of .PHONY, that you should $(RM) instead of rm, add a ‘-‘ in front of rm to avoid failing if invoked twice in a row, use $(wildcard …) to avoid trying to delete a file name ‘*.cm*’ (if shell wildcard expansion doesn’t work the filename stay the same, which is not the case of the Makefile function $(wildcard …)).
Writing really portable makefile is not easy and this is some of the thing I have tried to help with OASIS.
If you are interested, I can send you the _oasis file for OC*ML, you’ll see that it is not a big deal.
Sure, that wasn’t meant as a dig at OASIS, just that when I begun I didn’t know anything, so I decided to stick with good old-fashioned make, which everyone knows! The lowest common denominator, if you prefer. I would be interested in seeing the file, if it’s not too much bother. Merci 🙂
Now I am going to take a big step into the 21st century, wish me luck 🙂
There are two related but distinct meanings to “portable”. The one you use here, and that is the most frequent these days it seams, is: you can take something from one architecture and drop in into another one, and it just work. This is a desirable property but it’s not always possible, or in some cases it’s so complex that it becomes harder than to rewrite the thing for the other architecture.
The other meaning, and I think the original meaning of the word, is to arrange things so that it’s easier to adapt to another machine (for instance, by putting apart what should be replaced when porting, placing abstractions between the parts that’s architecture dependent and what’s not, keeping as simple as possible what would need to be modified for parting, and so on). In that sense, gcc is a portable compiler, Linux is a portable Unix (as was the original one BTW) ; these are portable even to most architectures that does not exist yet.
So, Makefiles are not portable in the former sense of the word, but I believe they are in the later since they are easy to fix in case of need, while _oasis files are portable in the former sense but maybe not the later: the very complexity that’s due to the requirement to be ‘copiable’ from one system to the other imply that they are harder to tweak when needed (for instance, in the rare cases when they don’t work out of the box).
Although, OASIS works very much in the same way as autoconf. It generates a huge unreadable file, but you can still re-regenerate it with latest version of autoconf and get all the improvement (more system supported and bug fixes). Contrary to autoconf, OASIS has the good taste to use OCaml rather than m4/sh 😉
I have been a packager for a long time and I have seen too much Makefile were you have to do half of the work. Most of the time the the work to adapt Makefile is just preventing packager to do the job. They will have to port and fix the Makefile for all the architectures and this is the kind of work they will have to do everytime a new version of the library is released. That is better than a broken build system but on the long terme this is daunting.
I noticed the footnote in this post (re: draft versions of Real World OCaml).
The installation instructions can now be found at http://realworldocaml.org/install (which will redirect to a wiki page — moved out of the book so that they’re easier to keep up to date). For the other links (e.g FFI) you replace ‘beta3’ by ‘v1’ and those should take you to the right places.