views:

77

answers:

1

My problem is that ocamlc and ocamlopt apear to be refusing to find third party libraries installed through apt-get. I first started having this problem when I tried to incorporate third-party modules into my own OCaml programs, and quickly wrote it off as a personal failing in understanding OCaml compilation. Soon-- however-- I found myself running into the same problem when trying to compile other peoples projects under their own instructions.

Here is the most straight-forward example. The others all use ocamlbuild, which obfuscates things a little bit.

The program: http://groups.google.com/group/fa.caml/msg/5aee553df34548e2

The compilation:

$ocamlc -g -dtypes -pp camlp4oof -I +camlp4 dynlink.cma camlp4lib.cma -cc g++ llvm.cma llvm_bitwriter.cma minml.ml -o minml
File "minml.ml", line 43, characters 0-9:
Error:Unbound module Llvm

Even when I provide ocamlc with the obsolute paths to the llvm files, like so...

$ ocamlc -g -dtypes -pp camlp4oof -I +camlp4 dynlink.cma camlp4lib.cma -cc g++ /usr/lib/ocaml/llvm-2.7/llvm.cma /usr/lib/ocaml/llvm-2.7/llvm_bitwriter.cma minml.ml -o minml 

... to no avail.

What am I doing wrong?

+7  A: 

Your command is doing two things: it's compiling minml.ml (into minml.cmo), then linking the resulting object into minml.

Compiling a module requires the interfaces of the dependencies. The interfaces contain typing information that is necessary to both the type checker and the code generator; this information is not repeated in the implementation (.cma here). So for the compilation stage, llvm.cmi must be available. The compiler looks for it in the include path, so you need an additional -I +llvm-2.7 (which is short for -I /usr/lib/ocaml/llvm-2.7).

The linking stage requires llvm.cma, which contains the bytecode implementation of the module. Here, you can either use -I or give a full path to let ocamlc know where to find the file.

ocamlc -g -dtypes -I +camlp4 -I +llvm-2.7 -pp camlp4oof -c minml.ml
ocamlc -g -cc g++ -I +camlp4 -I +llvm-2.7 dynlink.cma camlp4lib.cma llvm.cma llvm_bitwriter.cma  minml.cmo -o minml

or if you want to do both stages in a single command:

ocamlc -g -dtypes -cc g++ -I +camlp4 -I +llvm-2.7 dynlink.cma camlp4lib.cma llvm.cma llvm_bitwriter.cma -pp camlp4oof minml.ml -o minml
Gilles
Aha! Thank you for such thorough answer.
itsmyown
Do you have any theories of how these other people expect the program to compile without these flags? Jon Harrop is not exactly some amateur. I suspect there is a method to this madness.
itsmyown
@itsmyown: In Jon's case, he might be compiling the example in the directory where he just compiled the LLVM bindings, or he might have installed those bindings directly in the Ocaml library directory rather than in a subdirectory. The audience of the caml-list message you cite would know to add `-I` as required. By the way, I'm not sure whether `-cc g++` is actually required.
Gilles
small correction : compiler needs cmi files for interfaces, mli files are only for humans.
ygrek