Cabal和Stack有什么区别?

时间:2015-06-18 10:42:57

标签: haskell cabal haskell-stack

昨天我了解了一个名为Stack的新Haskell工具。乍一看,看起来它与Cabal完全相同。那么,它们之间有什么区别?堆叠是Cabal的替代品吗?在哪些情况下我应该使用Stack而不是Cabal?什么可以堆栈做Cabal不能?

3 个答案:

答案 0 :(得分:55)

  

堆叠是Cabal的替代品吗?

是和否。

  

在哪种情况下,我应该使用Stack而不是Cabal? Stack可以做什么?Cabal可以做什么?

由于Stack使用 default 的策划堆栈包,因此已知这些包可以一起构建。在Cabal,你可能会受到阴谋的打击。 Stack也在本地缓存你的包,这样你下次使用那个包(或它的传递依赖)时就不会从头开始编译所有东西。请注意,还有使用非堆栈包的规定,因此即使堆栈快照中没有包也可以使用。

就个人而言,我喜欢Stack,并建议每个Haskell开发人员使用它。他们的发展是。他们不担心(那么多)有关向后兼容性的问题。它有一个很多更好的用户体验。 stack Cabal提供的内容stack build --fast --file-watch尚未提供:{/ p>

  • Stack甚至可以为您下载GHC并将其保存在隔离的位置。
  • Docker支持(这对于部署Haskell应用程序非常方便)
  • Reproducible Haskell script:您可以查明软件包的版本,并确保它始终可以正常执行。
  • 能够--pedantic。如果更改存在的本地文件,这将自动重建。将它与{{1}}选项一起使用对我来说是一个交易障碍。
  • 能够将外部git存储库指定为依赖项。从Cabal 2.4开始,cabal还支持外部git存储库作为依赖。(这里要注意的是Stack已经使用了3年以上的功能,而且Cabal终于赶上了它。)
  • Stack支持使用templates创建项目。它还支持您自己的自定义模板。
  • Stack内置了hpack支持。它提供了另一种(IMO,更好的)使用yaml文件编写cabal文件的方法,该文件在业界得到了更广泛的应用。
  • Intero体验流畅when working with Stack

有一篇很好的博客文章解释了这些差异:Why is Stack not Cabal?

答案 1 :(得分:23)

在下文中,我将把两个被比较的工具称为 cabal-install stack 。特别是,我将使用 cabal-install 来避免与 Cabal 库混淆,后者是两种工具使用的通用基础结构。从广义上讲,我们可以说 cabal-install 堆栈 Cabal 的前端,它们之间的主要区别归结为默认的工作流程是:

  • 默认情况下, cabal-install 在被要求构建项目时,会查看其.cabal文件中指定的依赖项,并使用依赖项求解器来计算(如果可能的话)一组满足它的包和包版本。这个集合来自Hackage整体 - 所有包和所有版本,过去和现在。一旦找到可行的构建计划,默认情况下,所选择的依赖项版本将安装在~/.cabal某处已安装软件包的单个数据库中并注册。

  • 另一方面,
  • 堆栈将首先查看stack.yamlresolver字段。该字段通常指定Stackage 快照,它是Hackage包的一个子集,其中已修复的版本已知是相互兼容的。默认情况下, stack 将尝试使用快照提供的内容来满足依赖关系。从一个快照安装的软件包在不同且隔离的数据库中注册,并且维护单独的GHC安装以考虑快照所需的内容。这种方法具有一点灵活性,保证安装的软件包之间不存在版本不兼容(使用单个软件包数据库与 cabal-install 时的常见问题,原因在this article中讨论),以及总是可以找出用于构建项目的确切版本的依赖项(这对于确保完全充实项目的可重复构建以及轻松指定非常有用)没有伴随.hs文件的自包含.cabal脚本的依赖关系。

请注意,上述说明涵盖了每种工具的默认工作流程。 stack 所做的大部分工作都可以通过逐步退出默认值以 cabal-install 以某种(可能不那么方便)的方式实现,反之亦然。特别是:

  • cabal-install 通过cabal sandbox命令支持每个项目的隔离包数据库,但与 stack 和Stackage快照不同,不可能跨项目共享已安装的包。通过.cabal,也可以独立于cabal freeze修复要用于构建的依赖项版本。 (一个相关的堆栈功能,没有 cabal-install 模拟,是对单独的GHC安装的管理,即stack setup。)

  • 堆栈项目可以使用正在使用的Stackage快照中不可用的软件包,方法是在stack.yamlextra-deps中为Hackage提供的软件包设置相应的字段,但不能来自Stackage,packages使用自定义location来获取不在Hackage中的软件包。这些非Stackage软件包基于每个项目安装,与快照隔离。还有一个stack solver命令,它为Hackage(即非Stackage)依赖项执行自动依赖项解析。

最后,值得一提的是,{em> cabal-install 正在添加对Nix-style local builds的支持,作为缓解版本冲突的替代方法,这可能比{{更方便“ 1}}。此功能作为预览版本可从 cabal-install 1.24。

中获得

答案 2 :(得分:8)

从我从常见问题解答中可以看出,似乎Stack使用Cabal库,而不是cabal.exe二进制文件(更正确地称为cabal-install)。看起来该项目的目标是自动沙箱并避免依赖地狱。

换句话说,它使用相同的Cabal包结构,它只是提供了一个不同的前端来管理这些东西。 (我想!)