opam 新功能: "opam build"

更新:在本文发表后,经过讨论,该功能被放弃,下面是新的接口。更多细节请查看此文!

当前处于测试阶段的 opam 2.0 新版本引入了几个新功能。本文将详细介绍新的opam build命令,包括其目的、使用方法以及一些实现细节。

opam build命令在项目的源代码树中运行,不依赖于已有的 opam 安装。 因此,除了基于管理共享 OCaml 安装的现有工作流程(以切换的形式)之外,它提供了一种新的选项。

它有什么作用呢?

通常,它用于某个 OCaml 项目的全新 git 克隆。与固定包类似,opam 会在源代码中找到并利用包定义(以opam文件形式)。

  • 如果 opam 未初始化(没有~/.opam),则会自动处理。
  • 如果没有显式地选择其他切换,则会使用本地切换,并在必要时创建(例如,在./_opam/中)。
  • 当前项目的元数据会被注册,并且在安装其依赖项之后会安装该包,这与 opam 的通常操作一致。

这对分发项目特别有用,因为对于那些不熟悉 opam 和 OCaml 生态系统的用户来说,设置步骤会自动处理,一个opam build调用可以处理包的依赖链解析。

如果希望直接构建项目,添加--deps-only是一个很好的方法,可以使项目的依赖项就绪。

opam build --deps-only
eval $(opam config env)
./configure; make; etc.

请注意,如果你只想处理项目本地 opam 文件,也可以在现有切换中使用opam build:只需指定--no-autoinit--switch,或者确保OPAMSWITCH变量已设置。例如opam build --no-autoinit --deps-only 是一种方便的方法,可以在当前切换中为本地项目准备依赖项。

附加功能

安装

包的安装与通常一样,安装到与所用切换相对应的目录(对于本地切换,为<project-root>/_opam/)。但使用--install-prefix还可以将包进一步安装到系统中。

opam build --install-prefix ~/local

将会将当前目录中找到的包的安装结果安装到~/local下方。

包的依赖项不会被安装,因此这适用于程序(假设它们是可移植的),而不适用于库。

选择自定义仓库

用户可以在创建本地切换时,预先选择要使用的仓库。

opam build --repositories <repos>

其中<repos>是仓库的逗号分隔列表,可以指定为name=URL,或者如果已在系统中配置,则指定为name

多个包

通常多个包共享一个仓库。在这种情况下,opam build会注册并构建所有包,尊重跨依赖关系。可以使用命令行显式选择要使用的 opam 文件。

在这种情况下,特定的 opam 文件必须命名为<package-name>.opam

实现细节

在自动初始化时,编译器的选择要么是显式的,使用--compiler选项,要么是自动的。在后一种情况下,会使用默认选择(查看opam init --help,"CONFIGURATION FILE" 部分了解详情),但会从该选择中搜索与本地包兼容的编译器。这样就可以选择系统编译器(如果可用且兼容),避免重新编译 OCaml。

使用--install-prefix时,会进行正常的安装,然后会使用 opam 2.0 中引入的包安装文件跟踪功能,从切换中提取安装的文件并将其复制到前缀目录。

通过opam build安装的包不会注册到任何仓库,这不是opam pin的隐式用法:其原理是,以这种方式安装的包也会通过重复opam build来更新。这意味着,在使用其他命令(例如opam upgrade)时,opam 不会尝试将包保留为本地源版本,而是会将它们恢复为仓库定义,或者如果需要重新编译,则会将其删除。

计划的扩展

这仍然处于测试阶段:仍然有一些粗糙的地方,请尝试并提供反馈!在发布之前,命令语法和语义可能会有很大的变化。

我们努力改进的另一个用例是共享开发环境(共享固定包的集合、依赖于特定的远程仓库或 git 哈希值等)。我们有很多 想法改进这一点,但opam build目前还不是对此的直接解决方案。特别是,以这种方式安装仍然依赖于默认的 opam 仓库;我们正在研究一种方法,为opam build隐式创建的切换定义特定的选项。

注意:本文在opam.ocaml.orgocamlpro.com上交叉发布。请前往后者查看评论!