我有一个OCaml程序(使用main方法 - 它生成一个可执行文件),我想将它用作库。
我正在编译我的程序:ocamlc -I someDir -g -unsafe lotsOfCmoFiles -o outputFile
,程序运行正常。
现在我删除使其成为可执行文件的行(类似let _ = ...
)并添加-a
参数以编译命令:ocamlc -a -I someDir -g -unsafe lotsOfCmoFiles -o outputFile.cma
但不知怎的,我无法使用ocamltop
加载生成的.cma文件,ocamlbrowser
显示空列表。当我尝试从ocamltop
# #load "outputFile.cma";;
Error: Reference to undefined global `Xyz'
而且我100%确定xyz.cmo包含在lotsOfCmoFiles
中。
编译时我给出了一些参数错误吗?或者,我应该怎么做才能在ocamltop中加载我的程序? (我将在另一个程序中使用此库,我将ocamltop输出作为示例)
任何帮助将不胜感激。
编辑:所以我终于可以设法编译并加载它了,感谢@cago,现在我可以加载我的库,当我不删除主let _ = ...
行时,它会在我加载{{}时自动运行{1}}。
但我还是无法打开任何模块。奇怪的是,这不会引发异常
.cma
但是当我从模块Main调用一个函数时:
open Main
和# someFun;;
Error: Reference to undefined global `Main'
仍显示空列表。现在为什么会这样?
EDIT2:我意识到ocamlbrowse
没有失败,因为我在同一文件夹中有一个主模块(即使我没有明确加载它)。如果我将.cma文件移动到其他地方并加载它,它就可以工作(即主函数自动运行),但是现在我无法打开任何模块,即使open Main
显示模块。
EDIT3: - 我没有帮助:
ocamlobjinfo
答案 0 :(得分:8)
lotsOfCmoFiles
中的某些cmo需要知道模块Xyz。您需要处理cmo文件之间的依赖关系。
例如:
toto.ml:
let x = "toto"
titi.ml:
let y = Toto.x ^ " titi"
ocamlc -c toto.ml
ocamlc -c titi.ml
ocamlc -a titi.cmo toto.cmo -o lib.cma (* here is the probleme *)
# #load "lib.cma"
Error: Reference to undefined global `Toto'
因为titi取决于toto所以你需要改变cmos的顺序:
ocamlc -a toto.cmo titi.cmo -o lib.cma
# #load "lib.cma"
# Titi.y;;
- : string = "toto titi"
编辑:
如果您的cma位于子目录中,例如,当您致电ocaml
时,您需要指定路径:
ocaml -I subdir/ (* subdir which contains lib.cma *)
# #load "lib.cma"
# Toto.x;;
- : string = "toto"
答案 1 :(得分:0)
TL; DR:确保
中没有任何顶级副作用我遇到了同样的麻烦。我的项目将构建良好,大多数模块都可用,但有一个模块一直触发Reference to undefined global
。但很明显,该模块对系统是可见的:它显示在utop
的自动完成列表中,以及它的所有值,我可以引用它并将其导入其他模块。
问题结果是加载该模块时抛出的未捕获异常。该异常是由于尝试加载不存在的文件。它在复杂化过程中不会引起问题,但是当模块实际被加载时,它会被破坏,异常在我看到它之前就被吞噬了。