繁体   English   中英

Cabal 和 Stack 有什么区别?

[英]What is the difference between Cabal and Stack?

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

stack 是 Cabal 的替代品吗?

是和否。

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

默认情况下, Stack 使用精选的 stackage 包。 既然如此,任何依赖项都可以一起构建,从而避免版本冲突问题(当它们在 Haskell 体验中司空见惯时,曾经被称为“阴谋集团地狱”)。 最近版本的 Cabal 也有防止冲突的措施。 尽管如此,使用 Stack 设置一个可重现的构建配置,您可以确切地知道将从存储库中提取的内容。 请注意,还提供了使用非堆栈包的规定,因此即使堆栈快照中不存在包,您也可以继续使用。

就个人而言,我喜欢 Stack,并会推荐每个 Haskell 开发人员使用它。 他们的发展很快 而且它有一个更好的UX。 Stack 做了一些 Cabal 还没有提供的事情:

  • Stack 甚至会为您下载 GHC 并将其保存在一个孤立的位置。
  • Docker 支持(这对于部署您的 Haskell 应用程序非常方便)
  • 可重现的 Haskell 脚本:您可以确定包的版本,并可以保证它始终可以毫无问题地执行。 Cabal 也有一个脚本功能,但完全确保它的可重复性并不那么简单。)
  • 能够进行stack build --fast --file-watch 如果您更改当前的本地文件,这将自动重建。 将它与--pedantic选项一起使用对我来说是一个交易破坏者。
  • Stack 支持使用模板创建项目。 它还支持您自己的自定义模板。
  • Stack 内置了hpack支持。 它提供了另一种(IMO,更好的)使用 yaml 文件编写 cabal 文件的方法,yaml 文件在行业中使用更广泛。
  • Intero 使用 Stack 时体验流畅。

有一篇很好的博客文章解释了差异: 为什么 Stack 不是 Cabal? 尽管在那篇文章之后的几年中,Cabal 不断发展以克服那里讨论的一些问题,但对 Stack 背后的设计目标和哲学的讨论仍然具有相关性。

在下文中,我将比较的两个工具称为cabal-installstack 特别是,我将使用cabal-install来避免与Cabal库混淆, Cabal库是这两种工具使用的通用基础架构。

从广义上讲,我们可以说cabal-installstackCabal 的前端。 这两种工具都可以构建 Haskell 项目,这些项目的依赖集可能在单个系统的范围内相互冲突。 它们之间的主要区别在于它们如何实现这一目标:

  • 默认情况下,当要求构建项目时, cabal-install将查看其.cabal文件中指定的依赖项,并使用依赖项求解器找出一组满足它的包和包版本。 这个集合是从Hackage整体中提取的——所有包和所有版本,过去和现在。 一旦找到可行的构建计划,所选版本的依赖项将被安装并索引到~/.cabal某处的数据库中。 通过根据版本(以及其他相关的配置选项)索引已安装的包,避免依赖之间的版本冲突,这样不同的项目就可以检索他们需要的依赖版本,而不会相互踩踏。 这种安排就是cabal-install文档中“Nix 风格的本地构建”的意思

  • 当被要求构建一个项目时, stack会查看 stack.yaml 的resolver字段,而不是去stack.yaml 在默认工作流中,该字段指定Stackage快照,它是具有已知相互兼容的固定版本的 Hackage 包的子集。 然后, stack将尝试仅使用快照提供的内容来满足.cabal文件(或可能project.yaml文件——不同格式,相同角色)中指定的依赖项。 从每个快照安装的软件包都注册在不同的数据库中,它们不会相互干扰。

我们可能会说堆栈方法在指定构建配置时牺牲了一些设置灵活性以换取简单性。 特别是,如果你知道你的项目使用了 LTS 15.3 快照,你可以转到它的 Stackage 页面,一目了然地知道任何依赖堆栈的版本都可能从 Stackage 中提取。 也就是说,这两种工具都提供了超出基本工作流程的功能,因此总的来说,每个工具都可以完成另一个工具所做的一切(尽管可能以不太方便的方式)。 例如,有一些方法可以冻结已知良好构建配置的确切版本,并使用cabal-install 解决旧 Hackage 状态的依赖关系,并且可能需要非 Stackage 依赖关系或在使用stack 时覆盖快照包版本

最后, cabal-installstack之间的另一个区别在本概述中非常值得一提,这是stack旨在提供完整的构建环境,具有自动 GHC 安装管理Docker 集成等功能 相比之下, cabal-install旨在与生态系统的其他部分正交,因此它不会尝试提供此类功能(特别是 GHC 版本必须单独安装和管理,无论是通过 Linux 发行版)包、Windows 中的Haskell 平台核心ghcup 工具)。

从我从 FAQ 中收集到的信息来看,Stack 似乎使用了 Cabal 库,而不是cabal.exe二进制文件(更正确地称为 cabal-install)。 看起来该项目的目标是自动沙箱和避免依赖地狱。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM