Reputation: 1439
I have read this question and others, but my compile problem is unsolved.
I am testing separate compilation with these files:
testmoda.ml
module Testmoda = struct
let greeter () = print_endline "greetings from module a"
end
testmodb.ml
module Testmodb = struct
let dogreet () = print_endline "Modul B:"; Testmoda.greeter ()
end
testmod.ml
let main () =
print_endline "Calling modules now...";
Testmoda.greeter ();
Testmodb.dogreet ();
print_endline "End."
;;
let _ = main ()
Now I generate the .mli file
ocamlc -c -i testmoda.ml >testmoda.mli
and the testmoda.cmi is there.
Next I create the .cmo file without errors:
ocamlc -c testmoda.ml
Fine, so do the same with testmodb.ml:
strobel@s131-amd:~/Ocaml/ml/testmod> ocamlc -c -i testmodb.ml >testmodb.mli
File "testmodb.ml", line 3, characters 45-61:
Error: Unbound value Testmoda.greeter
Another try:
strobel@s131-amd:~/Ocaml/ml/testmod> ocamlc -c testmoda.cmo testmodb.ml
File "testmodb.ml", line 3, characters 45-61:
Error: Unbound value Testmoda.greeter
Other combinations failed as well.
How do I compile testmodb.ml and testmod.ml? This should be easy - without ocamlbuild / omake / oasis, I think.
Syntax errors in the files are excluded, if I cat them together to one file (with the required space between) it compiles and executes perfectly.
Upvotes: 3
Views: 440
Reputation: 66818
OCaml gives you a module for free at the top level of each source file. So your first module is actually named Testmoda.Testmoda
, the function is named Testmoda.Testmoda.greeter
, and so on. Things will work better if your files just contain the function definitions.
As a side comment, if you're going to use the interface generated by ocamlc -i
, you really don't need mli files. The interface in the absence of an mli file is the same as the one generated by ocamlc -i
. If you don't want the default interface, using ocamlc -i
gives a good starting point for your mli file. But for a simple example like this, it just makes things look a lot more complicated than they really are (IMHO).
If you modify your files as I describe (remove extra module declarations), you can compile and run from scratch as follows:
$ ls
testmod.ml testmoda.ml testmodb.ml
$ cat testmoda.ml
let greeter () = print_endline "greetings from module a"
$ cat testmodb.ml
let dogreet () = print_endline "Modul B:"; Testmoda.greeter ()
$ ocamlc -o testmod testmoda.ml testmodb.ml testmod.ml
$ ./testmod
Calling modules now...
greetings from module a
Modul B:
greetings from module a
End.
If you have already compiled a file (with ocamlc -c file.ml
) you can replace .ml
with .cmo
in the above command. This works even if all the filenames are .cmo
files; in that case ocamlc just links them together for you.
Upvotes: 5