Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ocaml 编译不同目录中的模块_Ocaml_Ocamlfind - Fatal编程技术网

Ocaml 编译不同目录中的模块

Ocaml 编译不同目录中的模块,ocaml,ocamlfind,Ocaml,Ocamlfind,我试图按照以下说明编译一个依赖于我创建的另一个模块的模块: 在我的例子中,我有一个模块~/courseFiles/chapter5/moduleA.ml,另一个模块在~/ocamlcomons/listMethods.ml中。我使用ocamlopt-c listMethods.ml编译了listMethods.ml,这似乎有效,它生成了一个文件listMethods.cmx 文件moduleA.ml包含openlistmethods。现在,当我的终端位于~/courseFiles/chapter

我试图按照以下说明编译一个依赖于我创建的另一个模块的模块:

在我的例子中,我有一个模块
~/courseFiles/chapter5/moduleA.ml
,另一个模块在
~/ocamlcomons/listMethods.ml
中。我使用
ocamlopt-c listMethods.ml
编译了
listMethods.ml
,这似乎有效,它生成了一个文件
listMethods.cmx

文件
moduleA.ml
包含
openlistmethods。现在,当我的终端位于
~/courseFiles/chapter5
时,我运行了
ocamlopt-c moduleA.ml
,但终端返回

错误:未绑定模块ListMethods


现在我可以理解为什么它会这样做,但网站上的说明似乎表明我所做的就是你应该如何做。在编译
moduleA.ml
时,我可能需要传入脚本或可执行文件的位置,但我不确定语法应该是什么。我尝试了一些猜测,并猜测了如何使用
ocamlfind
实现这一点,但我没有成功。我试图寻找有关编译位于不同目录中的模块的说明,但没有找到任何说明(或者我能理解的任何说明)。

首先,是OCaml系统发行版附带的工具包(也称为编译器)是非常通用的,但相当低的水平,应该被看作是建立更高层的构建系统的基础层。因此,学习它是相当困难的,通常只有当你要建立这样的系统时才有意义。学习如何使用或替代它要容易得多。此外,它会使你的注意力从真正重要的事情上分散开来——学习语言

话虽如此,让我详细回答你的问题。OCaml实现了一个单独的编译方案,其中每个编译单元可以独立构建,然后链接到单个二进制文件中。这种方案在C/C++语言中很常见,事实上,OCaml编译器工具链与C编译器工具链非常相似

当您运行
ocamlopt-c x.ml
时,您正在创建一个编译单元,因此会生成一些文件,即:

  • x.o
    -实际上包含已编译的机器代码
  • x.cmx
    -包含优化数据和其他编译器特定信息
  • x.cmi
    -包含模块
    x
    的编译接口
为了编译模块,编译器不需要该模块中使用的任何其他模块的代码。但它需要的是键入信息,即它需要知道
List.find
函数的类型,或者由模块外部的某个模块提供的任何其他函数的类型。此信息存储在cmi文件中,其中来自C/C++的(编译的)头文件是最接近的对应文件。与在C/C++中一样,编译器在include搜索路径中搜索它们,默认情况下,该路径包括当前目录和标准库的位置,但可以使用
-I
选项进行扩展(与在C/C++中相同)。因此,如果您的模块正在使用文件夹
a
中定义的另一个模块,则需要告诉编译器在何处搜索它,例如

 ocamlopt -I A -c x.ml
生成的目标文件将不包含来自外部模块的任何代码。因此,一旦您到达编译的最后阶段-链接阶段,您必须提供实现,例如,如果您的模块
X
使用的是在相对路径
a/y.ml
的文件中实现的模块,并且您已经在该文件夹中编译了该模块,然后需要再次指定编译实现的位置,例如

 ocamlopt -I A y.cmx x.cmx -o exe
顺序很重要,一个模块使用的所有模块都应该在该模块之前指定,否则将出现“未提供任何实现”错误


正如你所看到的,这是一个相当复杂的过程,你真的不值得花时间去学习它。因此,如果您有选择,那么使用更高级别的工具来构建您的程序。如果不确定,那么选择沙丘:(

< P>)首先,用OCAML系统分布(AKA编译器)装运的工具包是非常通用的,但非常低,应该被视为构建更高层的构建系统的基础层。因此,学习它是相当困难的,通常只有当你要建立这样的系统时才有意义。学习如何使用或替代它要容易得多。此外,它会使你的注意力从真正重要的事情上分散开来——学习语言

话虽如此,让我详细回答你的问题。OCaml实现了一个单独的编译方案,其中每个编译单元可以独立构建,然后链接到单个二进制文件中。这种方案在C/C++语言中很常见,事实上,OCaml编译器工具链与C编译器工具链非常相似

当您运行
ocamlopt-c x.ml
时,您正在创建一个编译单元,因此会生成一些文件,即:

  • x.o
    -实际上包含已编译的机器代码
  • x.cmx
    -包含优化数据和其他编译器特定信息
  • x.cmi
    -包含模块
    x
    的编译接口
为了编译模块,编译器不需要该模块中使用的任何其他模块的代码。但它需要的是键入信息,即它需要知道
List.find
函数的类型,或者由模块外部的某个模块提供的任何其他函数的类型。此信息存储在cmi文件中,其中来自C/C++的(编译的)头文件是最接近的对应文件。就像在C/C++中一样,编译器在include搜索路径中搜索它们,该路径由