OCaml静态地检测标准分布中对非普适库的依赖性

时间:2017-09-21 20:23:45

标签: ocaml ocamlfind

UnixBigarray等OCaml一起提供的某些模块在.cmx中有.cmxaocamlopt -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包装器的情况下编译它。

我想知道是否有办法静态检测到未绑定的文件模块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

2 个答案:

答案 0 :(得分:1)

我知道你的问题是:

  

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

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

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

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

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

一般情况下,这是不可能的,因为您寻找的图书馆可能不是标准的,也可能不是本地安装的。您可以使用像ocamloscope这样的API搜索引擎,但它们从未覆盖过所有编写过的OCaml库。

答案 1 :(得分:1)

虽然模块可以打包到具有任意名称的库中,但模块接口仍然保留顶级模块名称和编译模块接口文件名之间的一对一映射。因此,如果您遇到错误' Unbound module Xxx`,您可以

find ~/.opam -iname Xxx.cmi

如果您没有找到任何内容,则表示未安装此类库。目前,没有完善的方法可以找出提供此模块的软件包,您可以使用Google,在邮件列表或论坛上询问人员,或尝试使用apt-file希望库是标准的分配。

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

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