opam 2.0 小贴士

这篇文章回顾了 opam 2.0 中的一些改进,并提供了一些关于新工作流程的技巧。

包开发环境管理

Opam 2.0 已经大大改进,可以处理本地定义的包。假设你有一个项目 ~/projects/foo,定义了两个包 foo-libfoo-bin,你将拥有

~/projects/foo
|-- foo-lib.opam
|-- foo-bin.opam
`-- src/ ...

(另请参见有关 计算依赖约束 的内容,以处理具有相互约束的多个包定义)

自动固定

底层机制相同,但这是一个界面改进,它取代了大多数基于 opam pin 的 opam 1.2 工作流程。

通常的命令(installupgraderemove 等)已被扩展为支持指定目录作为参数。因此,在处理项目 foo 时,只需编写

cd ~/projects/foo
opam install .

foo-libfoo-bin 将自动固定到当前目录(如果你的项目是版本化的,则使用 git),并安装。你可能更喜欢使用

opam install . --deps-only

仅在开始修改项目之前准备好包依赖项。 参见下文,了解如何更精确地重现构建环境。请注意,opam depext . 目前无法正常工作,这将在下一个版本中得到修复,届时将集成外部依赖处理(opam 仍然会在失败时列出适合你操作系统的正确包)。

如果你的项目是版本化的,并且你做出了更改,请记住要么提交,要么添加 --working-dir,以便你的未提交更改被考虑在内。

本地开关

Opam 2.0 引入了一项名为“本地开关”的新功能。本节将解释它是什么,为什么,何时以及如何使用它。

Opam 开关 允许维护多个独立的开发环境,每个环境都有自己的一组已安装的包。当你需要不同的 OCaml 版本,或者在具有不同依赖集的项目上工作时,这尤其有用。

但是,有时管理或记住要将哪个开关与哪个项目一起使用会很繁琐。这就是“本地开关”发挥作用的地方。

本地开关如何处理

本地开关简单地存储在 _opam/ 目录中,并且每当你的当前目录在其父目录下时,opam 都会自动选择它。

注意:强烈建议你在使用本地开关时启用新的shell 钩子。只需运行 opam init --enable-shell-hook:这将确保你的 PATH 始终为正确的开关设置。

否则,你将需要不断记住每次 cd 到包含本地开关的目录时运行 eval $(opam env)。另请参见 如何在提示符中显示当前开关

例如,如果你有 ~/projects/foo/_opam,每当你在项目 foo 中时,开关都会被选中,允许你根据项目的需要定制它的安装内容。

如果你删除了开关目录,或整个项目,opam 将会透明地忘记它。不过,小心不要移动它,因为一些包仍然包含硬编码的路径,并且不能很好地处理重新定位(我们正在努力解决这个问题)。

创建本地开关

这通常可以从以下开始

cd ~/projects/foo
opam switch create . --deps-only

本地开关句柄只是它们的路径,而不是原始名称。此外,以上内容将检测 ~/projects/foo 中存在的包定义,选择一个兼容的 OCaml 版本(如果你没有明确提及任何版本),并自动安装所有本地包依赖项。

如果没有 --deps-only,这些包本身也会安装到本地开关中。

使用现有开关

如果你只希望自动选择现有的开关,而不需要为每个项目重新编译,你可以使用 opam switch link

cd ~/projects/bar
opam switch link 4.07.1

将确保每当你在项目 bar 中时,都会选择开关 4.07.1。你甚至可以在这里链接到 ../foo,以便在两个项目之间共享 foo 的本地开关。

重现构建环境

固定

如果你的包依赖于某些依赖项的开发版本(例如,你需要将修复程序推送到上游),请在你的 opam 文件中添加

depends: [ "some-package" ] # Remember that pin-depends are depends too
pin-depends: [
  [ "some-package.version" "git+https://gitfoo.com/blob.git#mybranch" ]
]

当你的包发布到存储库中时,这将没有影响,但是当它被固定到它的开发版本时,opam 将首先确保将 some-package 固定到给定的 URL。

锁定文件

依赖约束有时过于宽泛,你不想在开发过程中探索所有依赖项的版本。出于这个原因,你可能希望重现一组已知的有效依赖项。如果你使用

opam lock .

opam 将检查你的当前开关中安装的依赖项版本,并在 *.opam.locked 文件中明确它们。opam lock 目前是一个插件,但会在需要时自动安装。

然后,假设你将这些文件检入版本控制,任何用户都可以执行

opam install . --deps-only --locked

以指示 opam 重现相同的构建环境(--locked 选项也适用于 opam switch create,使事情更容易)。

生成的锁定文件还将包含添加的约束,以重现可选依赖项的存在/不存在,并使用 pin-depends 重现适当的依赖固定。如果你不希望强制执行所有递归依赖项的版本,而只希望强制执行直接依赖项的版本,则添加 --direct-only 选项。