0

与 OCaml 一起发布的某些模块喜欢UnixBigarray有自己的.cmx.cmxa文件ocamlopt -where~/.opam/4.03.0/lib/ocaml在我当前的 opam 开关中的系统上)。

有没有办法在不编译的情况下确定哪些源文件取决于标准发行版中的哪些“特殊”库?我打算稍后在 Makefile 中使用此输出。

以下程序example.ml

open Unix;;

Unix.system "echo hi";;

可以使用编译ocamlfind ocamlopt -package unix -linkpkg example.ml。我不确定如何在不通过ocamlfind包装器的情况下编译它。

我想知道是否有一种方法可以静态检测 unbound-in-this-file 模块Unix对应于标准发行版中的“某物”并报告unix.cmxa为依赖项。ocamldep默认情况下似乎没有将其报告为依赖项。

ocamldep -all example.ml只是报告可以使用生成的各种对象和接口文件example.ml依赖于example.ml. 我希望得到一条错误消息,抱怨 ocamldep 不理解该Unix模块,或者有一些迹象表明它是构建对象所必需的。

$ ocamldep -all example.ml
example.cmo example.cmi : example.ml
example.cmx example.o example.cmi : example.ml
4

2 回答 2

1

我了解您的问题是:

例如,对于给定的模块名称,Unix我们如何找到提供它的库?

不幸的是(还没有)这样的工具。

如果我们将搜索空间限制为 OCaml 编译器本身附带的库,我会这样做:

$ ocamlobjinfo $HOME/.opam/4.03.0/lib/ocaml/*.cma | grep '^\(File\|Unit name\)'

这将列出每个存档中定义的所有模块。您可能会或可能不会在结果中找到模块名称。

通常这是不可能的,因为您寻找的库可能不是标准的或者可能没有在本地安装。您可以使用 ocamloscope 之类的 API 搜索引擎,但它们当然不会涵盖所有曾经编写过的 OCaml 库。

于 2017-09-22T05:36:07.853 回答
1

尽管模块可能被打包到具有任意名称的库中,但模块接口仍然保留顶级模块名称和已编译模块接口文件名之间的一对一映射。所以如果你有一个错误'Unbound module Xxx`,你可以这样做

find ~/.opam -iname Xxx.cmi

如果您没有找到任何内容,则表示未安装此类库。目前,还没有完善的方法来找出哪个包提供了这个模块,你可以使用谷歌,在邮件列表或讨论论坛上询问人们,或者尝试使用apt-file希望该库在标准发行版中。

如果搜索只返回一个文件夹,那么你很幸运,你得到了这个包。该包可能包含不同类型的目标文件(.cmx - 用于本地代码,.cmo - 用于字节码)以及库(.cma - 是 .cmo 的集合,.cmxa - 是 .cmx 的集合, .cmxs 是 .cmxs 的动态版本)。OCaml 的灵活性,既是福音也是祸根,允许丢失任何这些文件。有礼貌的库通常会提供所有这些文件,并且具有包名与库名匹配的命名约定。但是,如果您正在使用ocamlfind并且该文件夹具有 META 文件,那么该文件夹的名称就是您需要传递的包的名称,ocamlfind以便从该包中链接库。

如果您有多个结果,那么您需要使用常识来确定您需要使用这两个库中的哪一个。或者,您可以尝试使用一个和另一个,看看哪个编译。

于 2017-09-22T12:17:58.780 回答