I am using Ocaml in the Bachelor introduction to programming class at ENS Rennes. I am encouraging my students to use an Abstract Data Types (ADT) approach with compiled modules and opaque data-types.
Each module is thus made of two parts: a signature
adt.mli part and an implementation part
adt.ml. The documentation at https://caml.inria.fr/pub/docs/manual-ocaml/moduleexamples.html is quite clear when those two files are located in the same directory.
However, they are now working on a project with several modules, respectively developed by separate groups. The groups share the interfaces
adt.mli in a
Interfaces repository, but not the implementation codes.
The question is then the procedure for one group to make
adt.cma. I first instructed them to do
$ ocamlc -c ../Interfaces/adt.mli
$ ocamlc -c adt.ml
Unfortunately, it does not work, as the
adt.cmi file is left in the
Interfaces repository, and it is not found on compiling
adt.ml. Instead, the default
adt.cmi file is rebuilt in the current directory.
I then tried
$ ocamlc -c ../Interfaces/adt.mli adt.ml
Surprisingly enough, it works!
Could somebody provide me with an explanation, so that I can tell my students?
Also, is it possible to tell
ocamlc -c adt.ml to look for the
adt.cmi file in another directory instead of rebuilding a local one?
I think you want to use -I:
ocamlc -c -I ../Interfaces adt.ml
Detailed information from the man page :
Add the given directory to the list of directories searched for compiled interface files (.cmi), compiled object code files (.cmo), libraries (.cma), and C libraries specified with -cclib -l xxx . By default, the current directory is searched first, then the standard library directory. Directories added with -I are searched after the current directory, in the order in which they were given on the command line, but before the standard library directory. See also option -nostdlib .
If the given directory starts with + , it is taken relative to the standard library directory. For instance, -I +compiler-libs adds the subdirectory compiler-libs of the standard library to the search path.
I am not sure to understand your answer. Let me introduce the following example.
test.mli declares function
f and not function
$ more ../Interfaces/test.mli
val f : unit -> int
$ more test.ml
let f() = 0;;
let g() = 1;;
$ cd Interfaces/
$ ocamlc -c test.mli -o test.cmi
$ cd ../Test/
$ rm *.cm*
$ ocamlc -c -I ../Interfaces test.ml
$ ocaml -I ../Interfaces/ test.cmo
OCaml version 4.07.1
- : int = 0
- : int = 1
g is defined, whereas it should not!
Did I miss something? Why is file
../Interfaces/test.cmi missed by the compiler?