单独编译OCaml模块

时间:2014-02-25 23:04:12

标签: ocaml

我已阅读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 / 我认为是绿洲。

排除文件中的语法错误, 如果我将它们一起捕获到一个文件(中间需要的空间),它就会编译 并且完美地执行。

1 个答案:

答案 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会将它们链接在一起。