OCaml模块的分离编译

3

我已经阅读了这个问题和其他相关的问题,但我的编译问题仍未解决。

我正在使用以下文件进行分离编译测试:

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 / oasis。

如果将这些文件拼接到一个文件中(需要添加所需空格),则排除文件中的语法错误,它可以编译并执行得很完美。

1个回答

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会自动将它们链接起来。


哦,奇迹啊,没有显式模块定义也能正常工作,ocamlc -c testmoda.ml 命令将创建 .cmi 和 .cmo 文件,后者可用于编译 testmod.ml 文件——这是一种分离式编译。 - Str.
1
以下是关于编程的内容翻译,仅返回翻译后的文本:这里是分离式编译: ocamlc -c testmoda.ml;ocamlc -c testmodb.ml; ocamlc -o testmod testmoda.cmo testmodb.cmo testmod.ml - Str.
请注意,我所给出的单个命令也进行了分离编译 :-) 它与这三个命令完全等效。但是当然有时候您只想编译其中一个源文件,就像您所展示的那样。这对于 testmod.ml 也适用。 - Jeffrey Scofield

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接