Question

I'm trying to work out how to use ocamlfind to compile a C library and an OCaml executable using that C library.

I put together a set of rather silly example files.

% cat sillystubs.c
#include <stdio.h>

#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/custom.h>

value
caml_silly_silly( value unit )
{
    CAMLparam1( unit );
    printf( "%s\n", __FILE__ );
    CAMLreturn( Val_unit );
}

% cat silly.mli 
external silly : unit -> unit = "silly_silly"

% cat foo.ml
open Silly
open String

let _ =
    print_string "About to call into silly";
    silly ();
    print_string "Called into silly"

I believe the following is the way to compile up the library:

% ocamlfind ocamlc -c sillystubs.c
% ar rc libsillystubs.a sillystubs.o
% ocamlfind ocamlc -c silly.mli
% ocamlfind ocamlc -a -o silly.cma -ccopt -L${PWD} -cclib -lsillystubs

Now I don't seem to be able to use the created library though:

% ocamlfind ocamlc -custom -o foo foo.cmo silly.cma
/usr/bin/ld: cannot find -lsillystubs
collect2: ld returned 1 exit status
File "_none_", line 1, characters 0-1:
Error: Error while building custom runtime system

The OCaml tools are somewhat mysterious to me, so any pointers would be most welcome.

Was it helpful?

Solution

ocamlmklib to the rescue. Step by step:

$ ocamlc -verbose -c sillystubs.c
$ ocamlmklib -verbose sillystubs.o silly.mli -o silly
$ ocamlc -verbose silly.cma foo.ml -o foo
File "foo.ml", line 1, characters 0-1:
Error: Error while linking foo.cmo:
The external function `silly_silly' is not available

Oops, you defined caml_silly_silly in sillystubs.c but reference silly_silly in silly.mli (so much silly :) Repairing :

$ cat silly.mli 
external silly : unit -> unit = "caml_silly_silly"
$ ocamlmklib -verbose sillystubs.o silly.mli -o silly
$ ocamlc -custom -verbose silly.cma foo.ml -o foo
/usr/bin/ld: cannot find -lsilly
collect2: ld returned 1 exit status
File "foo.ml", line 1, characters 0-1:
Error: Error while building custom runtime system

Still no luck? Add -I. to find needed libraries.

$ ocamlc -I . -verbose silly.cma foo.ml -o foo.byte
$ ocamlc -I . -verbose -custom silly.cma foo.ml -o foo.byte.custom
$ ocamlopt -I . -verbose silly.cmxa foo.ml -o foo.native

But in "real" setup you indeed want to install silly library with ocamlfind and then running compilation via ocamlfind will put needed command-line options in place and everything works automatically. Starting from scratch the whole procedure looks as follows :

$ ocamlc -verbose -c sillystubs.c
$ ocamlmklib -verbose sillystubs.o silly.mli -o silly
$ cat META
version="0"
description="quite silly"
archive(byte)="silly.cma"
archive(native)="silly.cmxa"
$ ocamlfind install silly META silly.cm* *.mli *.a *.so
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.a
Installed /usr/local/lib/ocaml/3.11.2/silly/libsilly.a
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.mli
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.cmxa
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.cmi
Installed /usr/local/lib/ocaml/3.11.2/silly/silly.cma
Installed /usr/local/lib/ocaml/3.11.2/silly/META
Installed /usr/local/lib/ocaml/3.11.2/stublibs/dllsilly.so
Installed /usr/local/lib/ocaml/3.11.2/stublibs/dllsilly.so.owner
$ rm *.cm* *.a *.so *.o
$ ocamlfind ocamlopt -linkpkg -package silly foo.ml -o foo.native
$ ocamlfind ocamlc -custom -linkpkg -package silly foo.ml -o foo.byte.custom
$ ocamlfind ocamlc -linkpkg -package silly foo.ml -o foo.byte

Native and byte versions are ready. BTW ocamlc -custom is deprecated.

Mystery unveiled I hope.

OTHER TIPS

The OCaml tools are somewhat mysterious to me,

I think so, too. why don't you use omake? omake makes the build sequences simple. http://omake.metaprl.org/manual/omake-build.html#@fun272

I'm a version behind on OCaml, but it looks like silly.cma has sillystubs linked dynamically, so you may need a

-ccopt -L${PWD} 

on that last line.

Also, I don't see anything you're doing that calls for the extra power of ocamlfind—you may as well call ocamlc directly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top