我已阅读this question和其他人, 但我的编译问题尚未解决。
我正在使用这些文件测试单独的编译:
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 ()
现在我生成.mli文件
ocamlc -c -i testmoda.ml >testmoda.mli
并且testmoda.cmi就在那里。
接下来,我创建.cmo文件,没有错误:
ocamlc -c testmoda.ml
很好,对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
另一次尝试:
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
其他组合也失败了。
如何编译testmodb.ml和testmod.ml?这应该很容易 - 没有ocamlbuild / omake / 我认为是绿洲。
排除文件中的语法错误, 如果我将它们一起捕获到一个文件(中间需要的空间),它就会编译 并且完美地执行。
答案 0 :(得分:5)
OCaml在每个源文件的顶层为您提供免费模块。因此,您的第一个模块实际上名为Testmoda.Testmoda
,该函数名为Testmoda.Testmoda.greeter
,依此类推。如果您的文件只包含函数定义,那么事情会更好。
作为旁注,如果你要使用ocamlc -i
生成的界面,你真的不需要mli文件。缺少mli文件时的接口与ocamlc -i
生成的接口相同。如果您不想使用默认界面,使用ocamlc -i
为您的mli文件提供了一个很好的起点。但是对于这样一个简单的例子,它只是使事情看起来比实际上复杂得多(恕我直言)。
如果您按照我的描述修改文件(删除额外的模块声明),您可以从头开始编译和运行,如下所示:
$ 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.
如果您已经编译了一个文件(ocamlc -c file.ml
),则可以在上面的命令中将.ml
替换为.cmo
。即使所有文件名都是.cmo
个文件,这也有效;在这种情况下,ocamlc会将它们链接在一起。