Dear list,

Let me share with you my frustration over compiling a c library out of an ocaml project. [apologies for long post]

This is now my third project where an ocaml implementation needs a c binding and I keep on struggling
with the right build environment.

While it is very well documented how to compile and build applications with ocaml bindings to
c implementations, the opposite way is a neglected topic.
sections 18.7-8 of the manual http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
plus a couple of pages of the o-reilly book is devoted to this topic.
The sporadic info found on mailing lists is not enough so I need your help.

The well known abstract problem is the following:

foo.ml: the ocaml routine root (responsible for foo.cmxa)
foo_export.ml the C API (register callback, exceptions, etc)
foo_stub.c the C bindings referring to the callbacks, containing init code
(foo_wrapper.ml the ocaml wrapper to foo)

clearly what I want is the following:

* foo.cmxa ocaml lib with ocaml entrypoints
* (foo: standalone executable from foo.cmxa and foo_wrapper.ml)
* libfoo: static and dynamic C library out of foo.cmxa , foo_export and foo_stub

what do I do? now more or less according to the manual:

ocamlc -a <all files> fib.ml
ocamlc -custom -output-obj -o fib_caml.o fib.cma fib_export.ml
ocamlc -c fib_stub.c
cp /usr/local/lib/ocaml/libcamlrun.a fib.a
ar r fib.a fib_caml.o fib_stub.o
ranlib fib.a

or

ocamlc -a <all files> foo.ml
ocamlc -custom -output-obj -o foo_caml.o foo.cma foo_export.ml
ocamlc -c foo_stub.c
libtool -o libfoo.a foo_caml.o foo_stub.o /usr/local/lib/ocaml/libcamlrun.a

and then link the c program with foo

* I know that building on several platforms is always a challange but this is such a simple routine.
if I have to use random command lines in my Makefile, I run into an autoconf hell.
is their a truly plantform independent routine to do this?

* can someone explain to me how the how exactly .a file created with .cmxa differ from an archive?
is it the ocaml sturtup code?

* why does the bytecode need the curses library when linking and why the native doesn't?

* why does ocamlc have a -custom option and why does ocamlopt does not? do I need the -custom options at all here?

* what do I do if I don't want to compile the ocaml runtime into my lib, since they might use several
of my modules so just link at the end with the runtime lib
* what if I want to share ocaml code for the same reason?

and most importantly:

* how do I create dynamic libs, dlls for windows?

In general, I found not much help from the existing build tools:

* OCamlMake does not support creation of c libraries

* omake is serious overkill (after hours of reading through the manual, I still don't know how the gtk example is relevant, plus omake creates an extra problem for portability, please correct me if I am wrong)

* ocamlbuild? I have problems with this piece of software. I found it frustatingly underdocumented and buggy.
I read the manual, help and the -documentation, and still don't understand anything.
The examples on the wiki page http://brion.inria.fr/gallium/index.php/C_stub_functions
give 100 lines of ocaml code for a similar problem?
- I still don't know the most basic thing, how to build an output-obj o file.
- I found no way to convince ocamlbuild to use the local library (in this example we build
ocamlbuild foo.cmxa
and then would simply want
ocamlopt -o foo foo.cmxa foo_wrapper.ml
but 'ocamlbuild foo_wrapper.native' rebuilds it all the way.

* I even tried to get inpiration from rocaml (a nice ruby binding for ocaml, which is mediated by a c, and all build is automated, but
it was too complicated to delineate the ruby-relevant things from the c-ocaml interface)

* why are the c object files end in .o irrespective of whether they are byte or native?
this makes it impossible to write rules on them?
In fact 'ocamlbuild foo.o' will build both and it overwrites the targets of the first round!!!
(since it matches both cmo & o and cmx & o rules?)


I know it is a lot of questions, but any help or comment is appreciated.

Something constructive:
Does the community not feel that we should somehow support this export much more within our existing build tools and documentation? If something reassuring comes out of this discussion I promise I write up a tutorial.
(At least I understand how to write the code)

Thanks very much.

viktor