OCaml:引用未定义的全局`A`

时间:2015-03-29 05:09:13

标签: ocaml

我有三个签名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,但我不确定如何。

1 个答案:

答案 0 :(得分:2)

直接使用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,以便从一开始就可以看到所有步骤。