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.org 和ocamlpro.com上交叉发布。请前往后者查看评论!