什么是构建OCaml项目的首选方式和结构?

65

对于新手来说,在构建小到中等规模的OCaml项目时,什么是最推荐的结构和管理方式并不清楚。我了解ocamlc的基本知识等--它们足够类似于常规的UNIX C编译器,看起来很简单。但是,在单个文件一次性编译的层面之上,如何以简单和清晰的方式管理编译并不清楚。问题不在于寻找潜在的工具,而在于看到一个或多个正确(足够)的方式--这些方式已经由社区的经验验证过--来构建和管理标准的OCaml项目。

我的模型用例是一个适度但非平凡的项目,纯粹使用OCaml或OCaml加上一个C依赖项。这样的项目:

  1. 包含许多源文件
  2. 链接到一些标准库
  3. 链接到一个或多个第三方库
  4. 可选地包含一个C库和OCaml包装器作为子项目(尽管这也可以单独管理并作为第三方库包含,如(3))

有几个备选工具:

  • 自定义Makefile似乎是大多数开源OCaml软件包中的通用标准,但看起来比适度的C/C++项目更为冗长和复杂。更糟糕的是,许多看似简单的OCaml库在其上层autoconf/automake以增加更多的复杂性。
  • ocamlbuild似乎提供了一种现代化、简化的机制来自动化构建,只需要最少的配置,但对于新手来说文档不充分,在OCaml生态系统的入门材料中没有被示例代表,也没有被我浏览过的各种已发布的OCaml项目所使用,因此不是很明显。
  • OASIS似乎是在支持构建软件包管理器和库(如Cabal)的其他构建系统之上的一个公约和库代码层。

我还看到了一个名为OMake的工具,它自诩为“make++”,还包括一套适用于常见语言(包括OCaml)的标准规则以及一个模板ocaml-make(前身为OCamlMakefile),提供GNU make的标准规则。

这些工具中有没有一种现代化的首选方式来管理OCaml构建?

项目文件最佳结构是什么样的?

如何包含和管理第三方库依赖项?是将它们安装在系统级别上更好,还是有一种管理它们的标准简单方法,可以使其局限于项目本身?我更喜欢使用尽可能自包含的项目模型。

5个回答

23

您已经全面列出了可用选项,但这个问题没有明确的答案。我的个人建议也是使用ocamlbuild。提供的myocamlbuild.ml文件在这里是一个很好的起点。它将允许您轻松编译依赖于各种库的项目。我认为它不处理绑定到C库的情况,但是在wiki上有其他的例子可能会有所帮助。

有些人反对ocamlbuild,因为它又是一个构建工具,使软件包管理器的工作变得更加复杂。然而,它的易用性和被包含在官方发布中的事实正在使它越来越广泛地使用。

您还可以跳过所有这些,直接使用oasis。它非常新,尚未宣布稳定版本,但是它非常可用。它将自动生成myocamlbuild.ml文件。如果不是已经这样做,那么在不久的将来,这可能是一个很好的选择。此外,通过使用oasis,您将立即获得oasis-db的好处,这是一个类似于OCaml的CPAN系统,正在开发中。

关于管理库的问题,答案是ocamlfind。如果安装了多个OCaml实例,则调用相应的ocamlfind副本将自动导致所有库的引用都是针对该特定实例的,假设您对所有库使用ocamlfind系统地进行操作。我目前使用godi来安装OCaml和库。它使用ocamlfind,我没有在安装多个OCaml实例时遇到任何问题。


5
自回答发布以来已经将近三年了。作为新手,我想分享一下我的经验。经历了很多痛苦之后,我得出了这样的结论:仔细阅读文档,并通过 ocamlfind 使用 ocamlcocamloptocamlmklib 是构建 OCaml 项目最不痛苦的方式。我在这里记录了我的发现 https://github.com/pacemkr/ocaml-scrypt/blob/master/Makefile 。我相信 oasismyocamlbuild.ml 这两个工具可以解决实际问题。我真的尝试过,但是这两个工具都无法很好地抽象出底层复杂性。 - Nick Zalutskiy
2
我也认为我的回答已经过时了。最近我一直在使用OMake,但是我对所有的构建工具都不满意,希望最终会出现一些根本上更好的东西。 - Ashish Agarwal
2
事情正在改善,opam并不真正关心构建系统,这是好事。ocamlfind使得使用ocamlc和其他工具更加容易。这两个工具已经让我足够接近目标了。最困难的部分是理解所有中间产物(cm*)以及它们来自哪里,以及cclib和类似标志的间接性,它们如何与包一起传递,自定义运行时构建等等。 - Nick Zalutskiy
3
另一个简单的 Makefile,供后人参考:https://github.com/pacemkr/ocaml-termbox/blob/master/Makefile - Nick Zalutskiy
1
这个回答的赞数越来越多,我感激不尽。然而,我想要明确指出的是,这里所陈述的很多内容已经不再适用。oasis-db和godi已被OPAM取代。我认为对于简单的项目,oasis仍然可以使用,但我个人不使用它,并认为更好的解决方案可能存在。我确实使用ocamlbuild,但忽略了它的大部分功能。 - Ashish Agarwal

15
个人而言,我会给 ocamlbuild 打+1。它的默认规则已经足够好了,可以用一个命令编译小到中等大小的项目,并且几乎不需要配置。它还实施了一些非常合理的约定(不将源代码与构建结果混合)。对于更大的项目,可以根据自己的需求进行定制,添加额外的规则和插件。在我工作的公司中,我们正在为一个大型项目(包括 Ocaml + 一些 C + 一些预处理等)使用它,它的工作效果非常好(比 Makefile 更少地带来了头痛)。
至于手册,我认为用户指南(可从作者的网页获得)应该足以让您入门。更高级的内容可能需要更多的挖掘。

完全同意。我参与了一个使用ocamlfind、预处理和c的大型项目,没有太多问题。 - nlucaroni
1
一旦我开始使用它,我会及时汇报的,它确实在我的并行调查中看起来最具吸引力。 - jrk
7
对于所有的ocamlbuild粉丝们:请记住,通过编写文档、发布有趣的自制myocamlbuild.ml文件片段甚至可能为所期望的功能而贡献代码(但这需要先联系开发人员),可以改进这个工具。我的心愿清单上容易实现的一个目标是允许调用ocamldoc生成点图。 - gasche
一个(不太重要?)的负面点:我听到人们抱怨使用并行标志“-j n”时,ocamlbuild带来的加速效果比make -j n实现的加速效果差。 - esope

10
当前的建议是使用 Dune,这是一个支持 OCaml 和 Reason 编译的可组合构建系统。它正在 积极开发快速入门页面 提供了各种项目模板供您选择。
Dune 还可以处理以下内容:

Opam是OCaml的事实标准软件包管理器。除了查找和安装软件包外,它还可以处理多个OCaml安装

Esy是一种新型的基于package.json的软件包管理器,诞生于Reason社区。 它的优点在于提供开箱即用的项目沙盒功能,并提供了一个轻松的方法来拉取现有的opam软件包。


10

+1 for OMake.

我们在几年前重新设计了构建基础设施,并出于以下原因选择了OMake:

  • 我们的产品由C、C++、Managed C++、Ruby和OCaml混合编写而成。
  • 目标平台为Linux和Windows。
  • 我们需要在构建时与数据库进行交互。
  • 对于某些生产环境,我们必须使用OCaml3.10。
  • 我们原始的构建系统使用autoconf/automake。
  • 我们需要支持离线构建*。

说实话,我不知道是否可以使用ocamlbuild完成此任务,因为我没有测试过。该工具肯定已经在使用了,因为在OCaml的Bug Tracker中有一些相关活动。如果您选择使用ocamlbuild,请确保您拥有最新版本的OCaml。

*OMake以有点不太明显的方式支持离线构建。当源文件是只读的时,它也存在一些问题。我们不得不对Windows版本的OMake进行修补并重新构建。


3
我想看一下omake和ocamlbuild之间的比较。我曾经非常成功地使用过omake。几年前我尝试使用ocamlbuild时没有那么顺利。 - aneccodeal

3

好问题,我的回答是:

1) ocamlbuild 它很可能成为标准的编译方式,因为它高效、快速,并且是官方发行版提供的默认工具。它在官方发行版中的存在是一个好的迹象,因为随着时间的推移,它更有可能得以保留。此外,它已启用了ocamlfind,因此可以管理使用ocamlfind安装的包,这是安装软件包的另一种标准方式(ocamlfind有点像C语言的pkg-config)

2) 但对于你的项目来说,仅使用ocamlbuild可能不够。ocamlbuild与C的集成比较基础。因此,在这里,我建议你使用oasis来最终解决你的问题。我也尝试过OMake,但并不喜欢它。

3) 然而,如果你希望其他人能够下载并在自己的机器上构建你的项目,那么你的构建脚本可能无法直接工作。此外,oasis不能处理pkg-config。出于这些原因,我倾向于建议你使用ocaml-autoconf(autotools的ocaml宏)。因为autotools是管理C库的标准方式,而且被软件包维护者所熟知。它还可以处理交叉编译......

=> 使用ocamlbuild的ocaml-autoconf


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接