我有三个签名A.mli
,B.mli
和C.mli
。在其中,我分别有子模块Aa
,Bb
和Cc
,还有实施Ai
,Bi
和Ci
的签名。
我已在名为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
,我尝试使用模块Ai
,Bi
,Ci
。
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
,但我不确定如何。
答案 0 :(得分:2)
直接使用ocamlc
或ocamlopt
编译器(即使在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
,以便从一开始就可以看到所有步骤。