Compilation 编译多个Ocaml文件
我是Ocaml新手,正在尝试编写一些小示例应用程序。我正在使用Linux Ubuntu 10.04下的Compilation 编译多个Ocaml文件,compilation,ocaml,Compilation,Ocaml,我是Ocaml新手,正在尝试编写一些小示例应用程序。我正在使用Linux Ubuntu 10.04下的ocamlc3.11.2版。我想编译两个文件: a.ml b.ml 文件b.ml使用a.ml中的定义。据我所知,我只能使用ocamlc-c执行编译。当我拥有所有.cmo文件时,我可以最后一次调用ocamlc,将它们链接到可执行文件。此外,在编译使用其他文件定义的文件时,我必须告诉编译器在哪个.cmi文件中查找外部定义 所以我的想法是使用: ocamlc -i -c a.ml > a.ml
ocamlc
3.11.2版。我想编译两个文件:
a.ml
b.ml
文件b.ml
使用a.ml
中的定义。据我所知,我只能使用ocamlc-c
执行编译。当我拥有所有.cmo
文件时,我可以最后一次调用ocamlc
,将它们链接到可执行文件。此外,在编译使用其他文件定义的文件时,我必须告诉编译器在哪个.cmi
文件中查找外部定义
所以我的想法是使用:
ocamlc -i -c a.ml > a.mli
ocamlc -c a.mli b.ml
ocamlc -o b a.cmo b.cmo
第一步工作并生成文件a.mli
和a.cmo
,但运行第二步时,我得到
File "b.ml", line 1, characters 28-31:
Error: Unbound value foo
其中foo
是在a.ml
中定义并在b.ml
中调用的函数
所以我的问题是:如何分别编译每个源文件并指定要在命令行上导入的接口?我一直在查看文档,据我所知,我必须指定要包含的.mli
文件,但我不知道如何操作
编辑
这里有更多的细节。文件a.ml
包含定义
let foo = 5;;
文件b.ml
包含表达式
print_string (string_of_int foo) ^ "\n";;
真实的例子更大,但有了这些文件,我已经有了我上面报告的错误
编辑2
我已经编辑了文件
b.ml
,并用A.foo
替换了foo
,这很有效(foo在b.ml
中可见,即使我有另一个编译错误,这对这个问题并不重要)。我想明确地编写自己的.mli
文件会更清晰,正如所建议的那样,如果您显示了不起作用的代码,则会更清晰。不过,正如克里斯托弗指出的,最可能的问题是您没有指定哪个模块foo
。您可以显式指定模块,如A.foo
。或者您可以打开一个
,只需使用名称foo
对于一个小例子来说,这并不重要,但是对于一个大项目,你应该小心不要太随意地使用
open
。您希望在模块中自由使用好的名称,如果您打开的名称太多,好的名称可能会相互冲突。首先解决未绑定值的问题,正如Jeffrey的回答所解释的那样。
这是关于您正在使用的命令的注释
将编译分解为几个步骤是了解发生了什么的好方法。
若您想编写自己的a.mli
,很可能会隐藏模块a
的一些值,那个么您的命令ocaml-i-ca.ml>a.mli
是获取此文件的第一个版本并对其进行编辑的好方法。但是如果您没有触摸a.mli,那么您不需要生成它:您也可以直接输入
ocamlc -o foo a.ml b.ml
这将产生a.cmo
,b.cmo
和可执行的foo
(它还将生成a.cmi
,这是通过发布ocamlc-c a.mli
获得的a.mli
的编译版本。同样,它还将生成b.cmi
)
请注意,顺序很重要:您需要在命令行上的b.ml
之前提供a.ml
。这样,在编译b.ml
时,编译器已经看到了a.ml
,并且知道在哪里可以找到模块a
还有一些评论:
- 你的“据我所知”一段是对的
- 您实际上不包括单独的文件,它更像Python中的导入:模块
a
的值可用,但名称为a.foo
。a.ml
的内容尚未复制粘贴到b.ml
中,而是访问了a.ml
中定义的模块a
的值及其编译版本a.cmo
- 如果您在
b.ml
中使用此模块A
,则可以在b.ml
之前在命令行上传递以下任意命令:
a.mli
,它将被编译成a.cmi
a.cmi
如果您已经将a.mli
编译成a.cmi
a.ml
或其编译版本a.cmo
,如果您不需要编写自己的a.mli
,即如果模块a
的默认界面适合您。(此接口只是a.ml
的每个值)
您是否在B中打开了A?因为否则这没有意义。否。我必须在a中定义一个模块并在B中打开它吗?目前,A中的所有定义都是全局的(我没有模块),每个OCaml文件都有一个隐式模块。因此,您的文件a.ml
定义了一个名为a
的模块。