如何在OCaml的两个实现代码之间进行选择

时间:2019-02-27 18:10:41

标签: ocaml

我已经将一个非常小的示例项目上传到github repository

我有一个学校项目。规范说我们可以启用或禁用组件。

我来自c世界,我们可以将c编译为对象并选择要链接的对象。我在OCaml中尝试过。

我有两个功能相同的源文件,但效果不同。 我有两个名为“ on”的实现文件夹,而“ off”的文件夹为空

对于测试,我有一个简单的a.ml和a.mli文件,它们仅打印hello world,而b.mli b.ml则调用模块a。 (所以我有on / a.ml和off / a.ml)

我使用以下命令编译打开和关闭版本:

ocamlc -c -I on on/a.mli on/a.ml -o on/a.cmo

然后我尝试链接C路

ocamlc on/a.cmo  b.ml -o on_b.exe

但是我得到了错误

File "b.ml", line 1, characters 9-15:
Error: Unbound module A

然后我已经读过,我应该指定要使用-I搜索的文件夹。

ocamlc -I on -I off on/a.cmo  b.ml -o on_b.exe

我很高兴,因为该版本适用于

但不适用于关闭版本

ocamlc -I on -I off off/a.cmo b.ml -o off_b.exe

我得到了错误

Error: Files b.cmo and off/a.cmo
       make inconsistent assumptions over interface A

我已经用ocamlobjinfo检查过,它似乎在搜索第一个名为A的模块时构建了B。

在此示例中,我只有A和B,但将来,我将在打开和关闭版本的情况下进行构建...但不要手动进行

找到一个解决方案,但没有真正有效的方法是清除所有.cmo和.cmi文件...

感谢您的阅读和时间

编辑:

我也使用-open进行了测试,但它似乎仅适用于标准模块。

1 个答案:

答案 0 :(得分:4)

如您所见,编译.mli文件会生成一个.cmi文件。这是您使用-I dir选项表示存在的文件。

因此,如果我对您的理解正确,那么在a.mlion目录中都会有一个off

现在,当您在代码中引用模块A时,编译器会在当前目录中查找该模块,然后在链接目录中按给定顺序查找。当您在“ on”上编译时,将找到正确的.cmi(因为在命令行中-I on位于-I off之前)。对于“ off”,找到“ on” cmi,编译器会发现它与正确的cmo不对应。

您的两条编译行应为:

ocamlc -I on on/a.cmo  b.ml -o on_b.exe
ocamlc -I off off/a.cmo  b.ml -o off_b.exe