4

我有一个 OCaml 程序(带有一个 main 方法 - 它生成一个可执行文件),我想将它用作一个库。

我正在像这样编译我ocamlc -I someDir -g -unsafe lotsOfCmoFiles -o outputFile的程序:并且程序运行良好。

现在我正在删除使其成为可执行文件的行(类似于let _ = ...)并将-a参数添加到编译命令:ocamlc -a -I someDir -g -unsafe lotsOfCmoFiles -o outputFile.cma

但不知何故,我无法加载生成的 .cma 文件ocamltopocamlbrowser显示一个空列表。当我尝试从以下位置加载时ocamltop

# #load "outputFile.cma";;
Error: Reference to undefined global `Xyz'

而且我 100% 确定 xyz.cmo 包含在lotsOfCmoFiles.

我在编译时是否给了一些错误的参数?否则,我应该怎么做才能在 ocamltop 中加载我的程序?(我将在另一个程序中使用这个库,我以 ocamltop 输出为例)

任何帮助将不胜感激。

编辑:所以感谢@cago,我终于可以编译和加载它,现在我可以加载我的库,当我不删除主线let _ = ...时,它会在我加载.cma.

但我仍然无法打开任何模块。奇怪的是,这并没有引发异常

open Main

但是当我从模块 Main 调用一个函数时:

# someFun;;
Error: Reference to undefined global `Main'

并且ocamlbrowse仍然显示一个空列表。现在为什么呢?

EDIT2:我意识到open Main不会失败,因为我在同一个文件夹中有一个主模块(即使我没有明确加载它)。如果我将 .cma 文件移动到其他地方并加载它,它可以工作(即 main 函数自动运行),但现在我无法打开任何模块,即使ocamlobjinfo显示了模块。

EDIT3:-我没有帮助:

$ ocaml
        OCaml version 4.00.1

# #load "lib.cma";;
ok
# open Lib;;
Error: Unbound module Lib
# 
$ ocaml -I libFolder    
        OCaml version 4.00.1

# #load "toylib.cma";;
ok
# open Lib;;
# fun;;
Error: Reference to undefined global `Lib'
4

2 回答 2

8

lotsOfCmoFiles您需要了解模块中的一些 cmo Xyz。您需要注意您的 cmo 文件之间的依赖关系。

例如:

toto.ml:

let x = "toto"

标题.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"
于 2013-03-04T12:26:51.213 回答
0

TL;DR:确保你没有任何顶级副作用

我遇到了同样的麻烦。我的项目会构建得很好,大多数模块都可用,但是有一个模块一直在触发Reference to undefined global. 但很明显,该模块对系统是可见的:它utop与它的所有值一起显示在 的自动完成列表中,我可以引用它并将其导入其他模块。

问题原来是加载该模块时抛出的未捕获异常。异常是由于尝试加载不存在的文件。它不会在复杂化过程中引起问题,但是当模块实际加载时,它会被破坏,并且在我看到它之前,异常就被吞没了。

于 2017-05-05T08:51:36.570 回答