OCaml:引用未定义的全局“A”

OCaml: Reference to undefined global `A`

我有三个签名 A.mliB.mliC.mli。在它们中,我分别有子模块 AaBbCc,以及实现 AiBiCi 的签名。

我在一个名为 D.ml 的文件中实现了它们,看起来像这样

open A
open B
open C

module Ai : Aa = struct ... end
module Bi : Bb = struct ... end
module Ci : Cc = struct ... end

我使用以下命令依次编译它们:

ocamlfind ocamlc -linkpkg -thread -package core A.mli
ocamlfind ocamlc -linkpkg -thread -package core B.mli
ocamlfind ocamlc -linkpkg -thread -package core C.mli
ocamlfind ocamlc -linkpkg -thread -package core D.ml

全部成功。

然后我有一个文件 E.ml,我在其中尝试使用模块 AiBiCi.

open A
open B
open C

module M = Ai(Ci)

(* do something else *)

然而,当我尝试编译 E.ml 时,我得到了

Error: Error while linking E.cmo:
Reference to undefined global `A`

我想我必须以某种方式在编译步骤中包含 D.ml,但我不确定该怎么做。

直接使用ocamlcocamlopt编译器(即使在ocamlfind的帮助下)不是一件容易的事,应该只留给那些编写OCaml工具和非常确定他们在做什么。所以,简而言之,只需使用 ocamlbuild,这是 OCaml 世界中编译事物的默认方式。因为,您正在使用 Core 库,所以使用 corebuild 而不是 ocamlbuild 也是一个好主意。 corebuild 与核心一起提供,实际上是 ocamlbuild 的一个小包装器,它添加了核心依赖项以及一些方便的标志。所以,使用 corebuild 你可以只编译:

 corebuild E.native

没有corebuild,你可以用

编译
 ocamlbuild -pkg core E.native

ocamlbuild 将为您完成所有工作,即找到所有依赖项、按正确顺序对它们进行排序、调用适当的工具等...您只需要这个,命令。

如果您仍然对如何正确编译您的示例项目感兴趣,那么您可以询问 ocamlbuild。使用 -classic-display 选项,它将显示所有中间命令,

 ocamlbuild -use-ocamlfind -classic-display -pkg core E.byte

将向您展示所有步骤。 (您可能需要 ocamlbuild -clean,以便您可以从头看到所有步骤)。