为什么在OCaml搜索路径上找不到第三方库?

jrk*_*jrk 5 macos homebrew ocaml build llvm

我的配置如下:

OCaml由Homebrew根据其默认配方安装.它存在于其中/usr/local/Cellar/objective-caml/3.12.0/[bin,lib,share],其内容被符号链接到/usr/local/[bin,lib,share].

第三方库(LLVM)安装了符号链接/usr/local/lib/ocaml/*.关键的/usr/local/lib/ocaml是,它本身不是 Homebrew Cellar的符号链接,而是一个包含OCaml Cellar路径下各个文件的链接的文件夹,因此这些第三方库文件位于/usr/local/lib/ocaml/路径中但不是原始路径

标准的OCaml编译器/解释器/构建工具始终无法找到这些第三方库,除非它们明确指出(例如ocamlbuild -cflags -I,/usr/local/lib/ocaml).

ld.conf 列表:

/usr/local/lib/ocaml/stublibs
/usr/local/lib/ocaml
/usr/local/lib/ocaml/site-lib/pcre
Run Code Online (Sandbox Code Playgroud)

这似乎表明编译器搜索路径设置正确,但我不熟悉工具链的内部工作原理.

  • 这是一个已知的问题吗?
  • 有没有办法打印标准工具实际使用的OCaml搜索路径?
  • 假设这是Homebrew configure和安装过程的结果(即假设问题是OCaml,如配置的那样,假设其实际的lib路径/usr/local/Cellar/objective-caml/3.12.0/lib/ocaml不是/usr/local/lib/ocaml),是否可以--prefix在配置期间强制显式添加额外的搜索路径?
  • 是否可以在安装后扩展整个环境的搜索路径(通过编辑配置文件,而不必诉诸于潜在的重新安装)?

ygr*_*rek 5

ocaml 模块的唯一内置搜索路径是 stdlib 的路径 - 用ocamlc -where. ld.conf 中引用的路径用于查找存根库 - C 代码编译为使用 C 绑定(无自定义运行时)的字节码 ocaml 程序的动态可加载模块。没有办法在全局范围内“扩展”搜索路径 wrt ocaml 安装。

正确的方法是在调用 ocaml 工具时添加所需的包含路径。ocamlfind工具极大地帮助以独立于系统的方式做到这一点。例如:

ocamlfind ocamlc -linkpkg -package llvm ll.ml -o ll
Run Code Online (Sandbox Code Playgroud)

像oasis/ocamlbuild/omake/etc这样的高级构建系统完全隐藏了所有这些东西,用户只需要提供依赖包的名称。


gas*_*che 5

确实如同ygrek指出的那样,答案是ocamlfind.OCamlfind维护了系统上安装的findlib-enabled¹OCaml软件包列表,并且可以轻松链接它们.使用

ocamlfind list
Run Code Online (Sandbox Code Playgroud)

获取包可以通过管道输送grep等的包列表.

ocamlfind query mypackage
Run Code Online (Sandbox Code Playgroud)

获取程序包的安装路径(有关详细信息,请参阅参考资料ocamlfind query --help)

ocamlfind ocamlc -package mypackage .....
Run Code Online (Sandbox Code Playgroud)

要使用包作为依赖项进行编译(-linkpkg在最后的链接步骤中用于构建可执行文件,-c -o foo.cmo例如,您不需要它).

ocamlfind也可以通过ocamlbuild使用.此前OCAML 3.12添加砍了一下myocamlbuild.ml文件(链接),但由于3.12的死很容易:使用package(foo),如果你想使用ocamlfind的包在ocamlbuild标签foo,并添加选项-use-ocamlfindocamlbuild的调用.

¹:ocamlfind是OCaml包的通用语言.如果你的第三个库没有通过ocamlfind注册自己,你应该搜索它们,编写一个META文件(这很容易),并将它发送给库维护者.