OCaml 静态检测对标准发行版中非普遍性库的依赖
OCaml statically detect dependency on non-pervasives library in standard distribution
OCaml 附带的某些模块,如 Unix
和 Bigarray
在 ocamlopt -where
中有自己的 .cmx
和 .cmxa
文件(即 ~/.opam/4.03.0/lib/ocaml
在我当前的 opam 开关中的系统上)。
有没有办法在不编译的情况下确定哪些源文件依赖于标准发行版中的哪些 "special" 库?我打算稍后在 Makefile 中使用此输出。
下面的程序example.ml
open Unix;;
Unix.system "echo hi";;
可以使用ocamlfind ocamlopt -package unix -linkpkg example.ml
编译。我不确定如何在不通过 ocamlfind
包装器的情况下编译它。
我想知道是否有办法静态检测未绑定的文件模块 Unix
对应于标准分发中的 "something" 并报告 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
我了解到您的问题是:
For a given module name, say Unix
, how can we find the library which provides it?
遗憾的是(目前)还没有这样的工具。
如果我们将搜索 space 限制在 OCaml 编译器本身附带的库中,我会这样做:
$ ocamlobjinfo $HOME/.opam/4.03.0/lib/ocaml/*.cma | grep '^\(File\|Unit name\)'
这将列出每个存档中定义的所有模块。您可能会也可能不会在结果中找到模块名称。
一般情况下是不可能的,因为你找的库可能不是标准的,也可能本地没有安装。您可以使用 API 搜索引擎,如 ocamloscope,但它们当然不会涵盖所有曾经编写过的 OCaml 库。
虽然模块可能被打包到具有任意名称的库中,但模块接口仍然保留顶级模块名称和编译模块接口文件名之间的一对一映射。所以如果你有一个错误'Unbound module Xxx',你可以做
find ~/.opam -iname Xxx.cmi
如果没有找到,说明没有安装这样的库。目前,还没有确定的方法来找出哪个包提供了这个模块,你可以使用 Google,在邮件列表或论坛上询问人们,或者尝试使用 apt-file
希望库服从标准分布。
如果搜索只返回一个文件夹,那么您很幸运,您收到了包裹。该包可能包含不同类的目标文件(.cmx - 用于本机代码,.cmo - 用于字节码)以及库(.cma - 是 .cmo 的集合,.cmxa - 是 .cmx 的集合, .cmxs 是 .cmxs 的动态版本)。 OCaml 的灵活性既是福音又是祸根,允许这些文件中的任何一个丢失。良好的库通常会提供所有这些文件,并且具有包名称与库名称匹配的命名约定。但是,如果您使用的是 ocamlfind
并且该文件夹包含 META 文件,那么该文件夹的名称就是您需要传递给 ocamlfind
以便 link 的包的名称这个包中的库。
如果您有多个结果,那么您需要使用常识来确定您需要使用这两个库中的哪一个。或者,您可以尝试使用一个和另一个,看看哪个可以编译。
OCaml 附带的某些模块,如 Unix
和 Bigarray
在 ocamlopt -where
中有自己的 .cmx
和 .cmxa
文件(即 ~/.opam/4.03.0/lib/ocaml
在我当前的 opam 开关中的系统上)。
有没有办法在不编译的情况下确定哪些源文件依赖于标准发行版中的哪些 "special" 库?我打算稍后在 Makefile 中使用此输出。
下面的程序example.ml
open Unix;;
Unix.system "echo hi";;
可以使用ocamlfind ocamlopt -package unix -linkpkg example.ml
编译。我不确定如何在不通过 ocamlfind
包装器的情况下编译它。
我想知道是否有办法静态检测未绑定的文件模块 Unix
对应于标准分发中的 "something" 并报告 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
我了解到您的问题是:
For a given module name, say
Unix
, how can we find the library which provides it?
遗憾的是(目前)还没有这样的工具。
如果我们将搜索 space 限制在 OCaml 编译器本身附带的库中,我会这样做:
$ ocamlobjinfo $HOME/.opam/4.03.0/lib/ocaml/*.cma | grep '^\(File\|Unit name\)'
这将列出每个存档中定义的所有模块。您可能会也可能不会在结果中找到模块名称。
一般情况下是不可能的,因为你找的库可能不是标准的,也可能本地没有安装。您可以使用 API 搜索引擎,如 ocamloscope,但它们当然不会涵盖所有曾经编写过的 OCaml 库。
虽然模块可能被打包到具有任意名称的库中,但模块接口仍然保留顶级模块名称和编译模块接口文件名之间的一对一映射。所以如果你有一个错误'Unbound module Xxx',你可以做
find ~/.opam -iname Xxx.cmi
如果没有找到,说明没有安装这样的库。目前,还没有确定的方法来找出哪个包提供了这个模块,你可以使用 Google,在邮件列表或论坛上询问人们,或者尝试使用 apt-file
希望库服从标准分布。
如果搜索只返回一个文件夹,那么您很幸运,您收到了包裹。该包可能包含不同类的目标文件(.cmx - 用于本机代码,.cmo - 用于字节码)以及库(.cma - 是 .cmo 的集合,.cmxa - 是 .cmx 的集合, .cmxs 是 .cmxs 的动态版本)。 OCaml 的灵活性既是福音又是祸根,允许这些文件中的任何一个丢失。良好的库通常会提供所有这些文件,并且具有包名称与库名称匹配的命名约定。但是,如果您使用的是 ocamlfind
并且该文件夹包含 META 文件,那么该文件夹的名称就是您需要传递给 ocamlfind
以便 link 的包的名称这个包中的库。
如果您有多个结果,那么您需要使用常识来确定您需要使用这两个库中的哪一个。或者,您可以尝试使用一个和另一个,看看哪个可以编译。