编译多个Ocaml文件

时间:2012-10-07 18:39:55

标签: compilation ocaml

我是Ocaml的新手并尝试编写一些小型示例应用程序。我在Linux Ubuntu 10.04下使用ocamlc版本3.11.2。我想编译两个文件:

a.ml
b.ml

文件b.ml使用a.ml中的定义。据我了解,我可以使用ocamlc -c仅执行编译。当我有所有ocamlc个文件将它们链接到可执行文件时,我可以最后一次调用.cmo。此外,在编译使用另一个文件中的定义的文件时,我必须告诉编译器在哪个.cmi文件中找到外部定义。

所以我的想法是使用:

ocamlc -i -c a.ml > a.mli
ocamlc -c a.mli b.ml
ocamlc -o b a.cmo b.cmo

第一步工作并生成文件a.mlia.cmo,但在运行第二步时我得到了

File "b.ml", line 1, characters 28-31:
Error: Unbound value foo

其中fooa.ml中定义并在b.ml中调用的函数。

所以我的问题是:我如何单独编译每个源文件并指定要在命令行上导入的接口?我一直在查看文档,据我所知,我必须指定要包含的.mli文件,但我不知道如何。

修改

这里有一些更多细节。文件a.ml包含定义

let foo = 5;;

文件b.ml包含表达式

print_string (string_of_int foo) ^ "\n";;

真实的例子比较大,但是对于这些文件,我已经有了上面报告的错误。

编辑2

我已编辑了文件b.ml,并将foo替换为A.foo,这有效(foo在b.ml中可见,即使我有另一个编译错误,这对我来说并不重要这个问题)。我想根据

的建议明确编写我自己的.mli文件更清晰

2 个答案:

答案 0 :(得分:5)

如果您显示的代码不起作用会更清楚。正如克里斯托弗指出的那样,最可能的问题是你没有指定模块foo所在的模块。你可以明确地指定模块,A.foo。或者您可以open A使用名称foo

对于一个小例子并不重要,但对于一个大项目,你应该注意不要过于自由地使用open。你希望自由在你的模块中使用好的名字,如果你打开了太多的名字,好名字可能会相互冲突。

答案 1 :(得分:5)

首先解决unbound value问题,正如Jeffrey的回答所解释的那样。 这是关于您正在使用的命令的评论。

通过几个步骤分解编译是理解正在发生的事情的好方法。 如果您想编写自己的a.mli,最有可能隐藏模块A的某些值,那么您的命令ocaml -i -c a.ml > a.mli是获取此文件的第一个版本的好方法,然后编辑它。但如果您没有触摸a.mli,那么您不需要生成它:您也可以直接输入

ocamlc -o foo a.ml b.ml

将生成a.cmob.cmo和exectuable foo

(它还会生成a.cmi,这是a.mli的编译版本,您可以通过发出ocamlc -c a.mli来获得。同样,它也会生成b.cmi)。< / p>

请注意,顺序很重要:您需要在命令行上a.ml之前提供b.ml。这样,在编译b.ml时,编译器已经看到a.ml并且知道在哪里找到模块A


更多评论:

  • 你的“据我所知”段落是对的。
  • 你真的没有包含一个单独的文件,它更像是Python中的 import :模块A的值可用,但名称不同A.fooa.ml的内容尚未复制粘贴到b.ml中,而是A中定义的模块a.ml的值及其编译版本a.cmo被访问过。
  • 如果您在A中使用此模块b.ml,则可以在b.ml之前在命令行上传递以下任何内容:
    • a.mli,将汇编为a.cmi
    • 如果您已将a.cmi编入a.mli ,则
    • a.cmi
    • a.ml或其编译版本a.cmo如果您不需要编写自己的a.mli,即模块A的默认界面是否适合您。 (此界面只是a.ml)的每个值。