我已经将一个非常小的示例项目上传到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进行了测试,但它似乎仅适用于标准模块。
答案 0 :(得分:4)
如您所见,编译.mli
文件会生成一个.cmi
文件。这是您使用-I dir
选项表示存在的文件。
因此,如果我对您的理解正确,那么在a.mli
和on
目录中都会有一个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