使用 Opam 管理项目依赖关系

2024-03-18

我是 OCaml 的新手。我使用过的其他语言(例如 Scala、Clojure、Node.js 上的 Javascript)都有包管理器,允许人们以干净的状态启动项目,该项目具有一组已声明的已知版本的依赖项。

我正在尝试与 Opam 做类似的事情。理想情况下,我想要一个列出依赖项(可能还有 OCaml 版本)的文件,以便协作者可以使用以下命令启动项目

git clone myproject
<magic opam command>
ocamlbuild

并且有一个工作版本,无需全局安装任何东西。

我知道执行此操作的正确方法是使用运算开关 https://opam.ocaml.org/doc/Usage.html#opam-switch,但我不确定在实践中该怎么做。似乎开关与编译器版本相关,而不是与每个项目相关(尽管有别名),而且我也找不到是否存在某种项目 Opam 配置文件。

简而言之:假设一个人想要根据 Core 和 Yojson 启动一个新项目(为了举例)。获得干净的可重复构建的步骤是什么?在这里,干净意味着它不会干扰现有已安装的库,可重现意味着它将在带有新克隆项目的干净机器上运行。


就系统库而言,它不可能真正干净。否则,您需要启动自己的虚拟机或其他容器。但是对于 OCaml 环境,您可以通过以下方式实现您的目标opam文件位于项目的根目录中。在其中描述了所有依赖项(包括系统依赖项)后,您可以pin您的项目,这将安装您的所有依赖项,编译您的项目并将其部署到 opam 堆栈。所以工作流程如下:

 $ # install opam 1.2
 $ # install aspcud (optionally, but highly recommended)
 $ opam switch install fresh -A 4.02.1
 $ opam pin add proj /path/to/proj -n
 $ opam depext --install proj
 # optional part:
 $ edit proj/src/main.ml # do the development
 $ opam upgrade proj

现在让我们逐步了解此工作流程。

安装编译器

 $ opam switch install fresh -A 4.02.1 

此命令创建一个新的编译器安装。这里fresh没有特殊含义,它只是安装的任意名称。通常,我使用date +"%y%m%d"命令而不是fresh创建一个由当前年、月和日组成的名称。

固定项目

$ opam pin add proj /path/to/proj -n

该命令会将您的项目引入 OPAM 系统。这就像创建您自己的小型软件包存储库,仅包含一个软件包,即proj。名字proj当然只是您项目的名称,无论它是什么。pin uses opam向 OPAM 系统描述您的项目的文件,您可以使用此手动创建它指示 http://opam.ocaml.org/doc/Packaging.html。或者你可以允许pin命令为您创建它。它将引导您温和地完成整个过程,并提出一些问题。您可以阅读有关固定的更多信息博客文章 https://opam.ocaml.org/blog/opam-1-2-pin/.

安装包和依赖项

在前面的命令中我们添加-n标志,那会停止pin命令在固定后安装您的软件包,因为我们想小步前进。

$ opam depext --install proj

此命令将计算包依赖项的传递闭包并安装它们,包括您的系统依赖项(如果您使用的是 ubuntu 或 fedora,并且您已在opam文件在上一步中)。

从事该项目

假设您要开发代码。有一个 OPAM 友好的工作流程:

 $ edit proj/src/main.ml # do the development
 $ opam upgrade proj

这将重新安装您的软件包(并重新安装您的软件包的所有依赖项,如果它们存在)。

另一方面,如果您的项目并不小,则此工作流程有一个严重的缺点,因为它将复制所有源并从头开始编译它们。但是,如果您有一组并行工作的依赖包,那么这是一种方法。

编译和其他东西

但这仅涉及包管理和包间依赖关系。 OPAM 对特定的构建系统绝对不可知,并且不会对其中任何一个系统给予任何支持(但仍然对其中一些系统提供工具支持)。所以,你可以写一个Makefile你自己或者有你自己的一组 shell 脚本调用ocamlbuild这完全取决于你。但如果我在你身边,我会使用 OASIS 来管理我的构建过程。 OASIS 本身并不是一个构建系统,它的目的是以跨平台的方式管理构建系统。但默认情况下它使用ocamlbuild并且它与它顺利地结合在一起。此外,它还与 OPAM 集成(实际上是 OPAM 与 OASIS 集成)。有一个oasis2opam包,这将创建一个opam文件来自_oasis文件。创造什么_oasis文件,描述了项目的构建过程,那么您可以create http://oasis.forge.ocamlcore.org/MANUAL.html使用您最喜欢的文本 emacs 手动创建它,或者您可以允许 OASIS 为您创建它oasis quickstart.

最后一点,我建议您查看现有项目并将其用作灵感来源。你可以从BAP https://github.com/BinaryAnalysisPlatform/bap.git我正在维护的项目,但它的配置相当复杂。所以,可能有更简单的例子。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Opam 管理项目依赖关系 的相关文章

  • 类型变量和局部抽象类型有什么区别?

    我试图理解的目的局部抽象类型在 OCaml 中 局部抽象类型与类型变量有何不同 看来他们有相同的行为 Type variable let f x a a x val f a gt a
  • 将库发布到 Maven 存储库

    我有一个稳定的开源库 http github com fernandezpablo85 scribe并想知道如何 以及是否 我可以将我的库发布到 Maven 官方存储库 以便人们可以将其包含在他们的pom xml文件并自动下载依赖项 将您的
  • OCaml 中 let rec 的限制

    这几天我在学习OCaml 发现了这个 OCaml 对于可以放在 let 记录右侧的内容有限制 像这个 let memo rec f norec let rec f memoize fun x gt f norec f x in f Erro
  • Gradle 多项目定义对根项目的依赖

    我有一个多项目 gradle 构建 以这种方式配置 root projectA projectB 我想在root build gradle所有嵌套项目的依赖项 这是文件 subprojects version 1 0 SNAPSHOT re
  • 跳过 Maven 测试依赖项

    我正在开发一个使用 Maven 进行构建的项目 我想做的是跳过测试依赖项 基本上在我的 Maven 存储库中不存在工件的情况下运行 Maven 构建 eg
  • 如何解决SBT依赖的依赖冲突?

    我有一个项目的构建 sbt正在使用 libraryDependencies Seq com lerestau killer launcher 1 0 2 com lerestau menu starter 1 0 0 菜单启动器过渡下载 杀
  • 绘制java类的依赖关系图

    嘿嘿 我正在寻找像 JDepend 这样的工具来为 java 类文件绘制图表 JDepend 看起来很好 但它没有从 deps 中解析 deps 也许我只是缺少一些特殊选项 直接输出为 dot 格式或图像会很好 谢谢 你可以试试Java依赖
  • 值的 Ocaml 表示 - 原子

    我查看了一些 OCaml 值的内部表示 空数组的表示是atom 0 即一个块tag 0 and size 0 空浮点数数组由atom 0 too 是否存在由原子表示的任何 OCaml 值tag gt 0 如果不是 OCaml 字节码集包含以
  • Maven:我应该保留还是删除声明的依赖项,这些依赖项也是传递依赖项?

    您认为删除 Maven pom 中可以找到的所有传递依赖项是一个好习惯吗 Example 我的项目依赖于A和B B 也是 A 的传递依赖 我应该将 B 保留在我的 pom 中还是将其删除 哪个最好 拥有所有已知的 jar 甚至是传递性的 j
  • 使用 MaltParser 和 NLTK 进行依存分析

    考虑一下这个句子 new sent PeterParker loves MaryJane 我尝试使用 malparser 和 NLTK 解析这句话 如下所示 maltParser nltk parse malt MaltParser wor
  • OCaml 中类型和模块相等的规则是什么

    我无法理解 OCaml 中模块的平等性 函子应该是适用的 这就是互联网所声称的 但这有时似乎会失败 而且我不太明白其背后的一般规则 这是我的示例代码 module type PT sig end module P struct end le
  • 作曲家和 Yii

    我使用 Composer 作为我的依赖管理器 因为我需要使用 Yii Framework 进行开发 所以我将其添加到我的composer json 文件中 所以它看起来像这样 other properties require other d
  • Spring中的ApplicationContext导入

    我正在从本教程学习 Spring http courses caveofprogramming com courses the java spring tutorial lectures 38024 http courses caveofp
  • Tensorflow:docker 镜像和 -gpu 后缀

    在具有 GPU 支持的 Tensorflow 的 Docker 映像中 例如 tensorflow tensorflow 2 2 0 gpu 安装的python包是tensorflow gpu 如图所示pip freeze 安装任何依赖于的
  • Android Studio .2.2 和 Gradle 包不存在

    Android Studio 和导入外部 Java 库的新功能 我已阅读有关配置 Gradle 依赖项的帖子 并修复了我的第一个包不存在错误 这些是我的 MainAcitivity java 文件中的导入语句 import com goog
  • 使用指针隐藏实现(Pimpl 惯用语)

    是否有可能实现以下目标 x hpp 该文件被许多其他类包含 class x impl forward declare class x public methods private x impl impl x cpp 实施 include
  • OCaml 中的用户定义打印机

    printf fprintf等 全部接受 a转换 手册上说对于 a 用户定义的打印机 采用两个参数 并将第一个参数应用于 outchan 当前输出通道 和第二个参数 因此 第一个参数的类型必须为 out channel gt b gt un
  • 将“列表”转换为“集合”?

    OCaml 真的没有从列表转换为集合的函数吗 如果是这样的话 是否可以制作一个通用函数list to set 我尝试制作一个多态集 但没有成功 基本问题 列表可以包含任何类型的元素 集合 假设你的意思是Set http caml inria
  • 范围为“provided”的工件的 Maven 依赖关系树行为

    我偶然发现同一项目在两台电脑上的不同行为 在两台机器上我运行命令mvn dependency tree X但收到不同的结果 在我收到的第一台机器上 Apache Maven 3 2 2 45f7c06d68e745d05611f7fd14e
  • Gradle 列出本地项目依赖项

    我有以下项目结构 root A B B1 B2 C 其中 B1 依赖于 B2 和 A B2 也依赖于 A 和 C 所有这些项目还具有从中央存储库下载的外部依赖项 是否有一个 gradle 任务来获取所有本地依赖项 传递 我想要某种 B1 A

随机推荐

  • SQL:ENUM 与一对多关系的优点?

    我很少看到 ENUM 数据类型在野外使用 开发人员几乎总是只使用如下所示的辅助表 CREATE TABLE officer ranks id int PRIMARY KEY title varchar NOT NULL UNIQUE INS
  • PHPcurl:“列表中的未知密码”

    我正在使用以下密码列表curl setopt CURLOPT SSL CIPHER LIST DHE DSS AES256 GCM SHA384 DHE RSA AES256 GCM SHA384 DHE RSA AES256 SHA256
  • 如何包装一个方法,以便在超过指定超时时终止其执行?

    我有一个我想调用的方法 然而 我正在寻找一种干净 简单的方法来杀死它 或者在执行时间太长的情况下强制它返回 我正在使用Java 为了显示 logger info sequentially executing all batches for
  • 从 AWS Lambda 连接到 Redshift

    我正在尝试连接到我的Redshift来自我的数据库AWS Lambda功能 con psycopg2 connect dbname my dbname host my url port 5439 user username password
  • Nodejs crypto.publicEncrypt 在不同的机器上产生不同的结果

    我们正在尝试使用 AWS KMS 中的非对称密钥进行加密和解密 key的配置如下 在 NodeJS 中 我们通过 crypto publicEncrypt 使用公钥进行加密 const encryptRSAPayload buffer pu
  • 什么是mockito-inline以及它如何模拟最终方法?

    Mockito 中的 Javadocs 说 从版本 2 7 6 开始 我们提供了 mockito inline 工件 无需配置 MockMaker 扩展文件即可实现内联模拟制作 这是什么意思 mockito inline 是如何工作的 为什
  • 如何使用 JavaScript 读取文本区域中的文本?

    所以我是 JS 的新手 正在尝试了解基础知识 我决定制作一个基本的网页文本编辑器 现在我正在尝试用 JS 来区分单词 这是我的代码 基本上它确定单词 bob 是否已输入到文本区域中
  • 使用 php 验证链接

    谁能告诉我是否可以用 php 验证链接 通过验证 我的意思是检查链接是否处于活动状态 并且不仅仅是链接的实际格式 您需要执行 HEAD 请求并检查响应 200表示请求成功 还有其他的可以在这里找到 http www w3 org Proto
  • MacPorts 手动端口位置

    我正在从 MacPorts 安装一个 python 库 但macports版本的库比实际开发的svn版本旧 是否可以在 MacPorts 中指定端口安装的自定义位置 以便我可以从开发人员站点安装最新的库 Have http guide ma
  • MySQL 复合索引和运算符 BETWEEN

    我对这个查询有一个疑问 SELECT FROM runs WHERE NOW BETWEEN began at AND finished at 您认为为 begin at 和 finish at 列创建复合索引有意义吗 或者只为 begin
  • 模糊效果在模拟器中显示,但在 iPhone 上不显示

    我想创建一个模糊效果UIImageView与下面的代码 问题是 当我在模拟器中运行它时 我可以看到 BlurEffect 但当我连接 iPhone 时却看不到 这里我只能看到灰色背景 有什么想法吗 这是我使用的代码 import UIKit
  • 如何在 MASM 中编写远绝对 JMP/CALL 指令?

    如何使用 MASM 编写远绝对 JMP 或 CALL 指令 具体来说 如何让它使用 EA 和 CA 操作码发出这些指令 而不使用 DB 或其他数据指令手动发出它们 例如 考虑跳转到引导扇区中 FFFF 0000 处的 BIOS 重置入口点的
  • 使用 python 从 BytesIO 创建 Excel 文件

    我在用pandas用于存储 Excel 的库bytesIO记忆 稍后我会存储这个bytesIO对象导入 SQL Server 如下 df pandas DataFrame data1 columns col1 col2 col3 outpu
  • 非常慢的 HHVM、Wordpress、Nginx

    我可能做错了什么 但我正在 php fpm wordpress 设置和 HHVM wordpress 设置之间进行一些测试 我听过并看到过 HHVM 的许多令人兴奋的结果 但我只是对我得到的结果感到震惊 使用以下 apache 测试命令 我
  • 来自 Android 版 IndexedDB Chrome 中保存的块的 HTML5 视频

    我想使用 IndexedDB 在客户端存储离线 HTML5 应用程序的视频文件 为此 我从服务器 API 中下载了 2 个块的视频 然后我将它们作为 blob 存储在 indexedDB 中 然后在其他页面上我从数据库获取它们并创建新的 b
  • 迭代调用 pandas datareader

    我有一个带有股票列表的 python 字典 我试图在 for 循环中使用键 股票代码 见下文 来迭代地为所有股票 以股票代码命名 创建多个 pandas DataFrame 并通过 pandas DataReader 填充价格 交易量 我认
  • JavaFX和Mac:如何设置窗口关闭按钮修改状态?

    我希望能够设置应用程序的修改状态并将其反映在窗口关闭按钮 即其中的黑点 中 我发现了一个非常好的概述 参见 http nadeausoftware com node 90 http nadeausoftware com node 90 如何
  • 简单 mips 中的无限循环

    我正在尝试了解 ra 所以我想要的输出是 mainfunction1main 通过 main 调用 function1 function1 返回到 main 然后 main 完成 但由于某种原因 我得到一个无限循环 打印 mainfunct
  • 使用参数变量获取传递给 ES6 箭头函数的参数 [重复]

    这个问题在这里已经有答案了 我了解箭头函数在 ES6 中的工作原理以及词法 this 但我想知道是否有人知道如何将参数传递给箭头函数 在 ES5 中 你可以简单地执行以下操作 function foo bar baz console log
  • 使用 Opam 管理项目依赖关系

    我是 OCaml 的新手 我使用过的其他语言 例如 Scala Clojure Node js 上的 Javascript 都有包管理器 允许人们以干净的状态启动项目 该项目具有一组已声明的已知版本的依赖项 我正在尝试与 Opam 做类似的