简体   繁体   English

Cabal 和 Stack 有什么区别?

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

Yesterday I learnt about a new Haskell tool called Stack .昨天我了解了一个名为Stack的新 Haskell 工具。 At the first blush, it looks like it does much the same job as Cabal.乍一看,它看起来与 Cabal 的工作大致相同。 So, what is the difference between them?那么,它们之间有什么区别呢? Is stack a replacement for Cabal? stack 是 Cabal 的替代品吗? In which cases should I use Stack instead of Cabal?在哪些情况下我应该使用 Stack 而不是 Cabal? What can Stack do that Cabal can't? Stack 可以做什么而 Cabal 不能?

Is stack a replacement for Cabal? stack 是 Cabal 的替代品吗?

Yes and No.是和否。

In which cases should I use Stack instead of Cabal?在哪些情况下我应该使用 Stack 而不是 Cabal? What can Stack do that Cabal can't? Stack 可以做什么而 Cabal 不能?

Stack uses the curated stackage packages by default .默认情况下, Stack 使用精选的 stackage 包。 That being so, any dependencies are known to build together, avoiding version conflict problems (which, back when they were commonplace in the Haskell experience, used to be known as "cabal hell").既然如此,任何依赖项都可以一起构建,从而避免版本冲突问题(当它们在 Haskell 体验中司空见惯时,曾经被称为“阴谋集团地狱”)。 Recent versions of Cabal also have measures in place to prevent conflict.最近版本的 Cabal 也有防止冲突的措施。 Still, setting up a reproducible build configuration in which you know exactly what will be pulled from the repositories is more straightforward with Stack.尽管如此,使用 Stack 设置一个可重现的构建配置,您可以确切地知道将从存储库中提取的内容。 Note that there is also provision for using non stackage packages, so you are good to go even if a package isn't present in the stackage snapshot.请注意,还提供了使用非堆栈包的规定,因此即使堆栈快照中不存在包,您也可以继续使用。

Personally, I like Stack and would recommend every Haskell developers to use it.就个人而言,我喜欢 Stack,并会推荐每个 Haskell 开发人员使用它。 Their development is fast .他们的发展很快 And it has a much better UX.而且它有一个更好的UX。 And there are things which Stack does which Cabal yet doesn't provide: Stack 做了一些 Cabal 还没有提供的事情:

  • Stack even downloads GHC for you and keeps it in an isolated location. Stack 甚至会为您下载 GHC 并将其保存在一个孤立的位置。
  • Docker support (which is very convenient for deploying your Haskell applications) Docker 支持(这对于部署您的 Haskell 应用程序非常方便)
  • Reproducible Haskell script : You can pinpoint version of a package and can get guarantee that it will always execute without any problem. 可重现的 Haskell 脚本:您可以确定包的版本,并可以保证它始终可以毫无问题地执行。 ( Cabal also has a script feature , but fully ensuring reproducibility with it is not quite as straightforward.) Cabal 也有一个脚本功能,但完全确保它的可重复性并不那么简单。)
  • Ability to do stack build --fast --file-watch .能够进行stack build --fast --file-watch This will automatically rebuild if you change the local files present.如果您更改当前的本地文件,这将自动重建。 Using it along with --pedantic option is a deal-breaker for me.将它与--pedantic选项一起使用对我来说是一个交易破坏者。
  • Stack supports creating projects using templates . Stack 支持使用模板创建项目。 It also supports your own custom templates.它还支持您自己的自定义模板。
  • Stack has built-in hpack support in it. Stack 内置了hpack支持。 It provides an alternative (IMO, a better) way of writing cabal files using yaml file which is more widely used in the industry.它提供了另一种(IMO,更好的)使用 yaml 文件编写 cabal 文件的方法,yaml 文件在行业中使用更广泛。
  • Intero has a smooth experience when working with Stack . Intero 使用 Stack 时体验流畅。

There is a nice blog post explaining the difference: Why is Stack not Cabal?有一篇很好的博客文章解释了差异: 为什么 Stack 不是 Cabal? While Cabal has, in the intervening years since that post, evolved so as to overcome some of the issues discussed there, the discussion of the design goals and philosophy behind Stack remains relevant.尽管在那篇文章之后的几年中,Cabal 不断发展以克服那里讨论的一些问题,但对 Stack 背后的设计目标和哲学的讨论仍然具有相关性。

In what follows, I will refer to the two tools being compared as cabal-install and stack .在下文中,我将比较的两个工具称为cabal-installstack In particular, I will use cabal-install to avoid confusion with the Cabal library, which is common infrastructure used by both tools.特别是,我将使用cabal-install来避免与Cabal库混淆, Cabal库是这两种工具使用的通用基础架构。

Broadly speaking, we can say cabal-install and stack are frontends to Cabal .从广义上讲,我们可以说cabal-installstackCabal 的前端。 Both tools make it possible to build Haskell projects whose sets of dependencies might conflict with each other within the confines of a single system.这两种工具都可以构建 Haskell 项目,这些项目的依赖集可能在单个系统的范围内相互冲突。 The key difference between them lies in how they address this goal:它们之间的主要区别在于它们如何实现这一目标:

  • By default, cabal-install will, when asked to build a project, look at the dependencies specified in its .cabal file and use a dependency solver to figure out a set of packages and package versions that satisfy it.默认情况下,当要求构建项目时, cabal-install将查看其.cabal文件中指定的依赖项,并使用依赖项求解器找出一组满足它的包和包版本。 This set is drawn from Hackage as a whole -- all packages and all versions, past and present.这个集合是从Hackage整体中提取的——所有包和所有版本,过去和现在。 Once a feasible build plan is found, the chosen version of the dependencies will be installed and indexed in a database somewhere in ~/.cabal .一旦找到可行的构建计划,所选版本的依赖项将被安装并索引到~/.cabal某处的数据库中。 Version conflicts between dependencies are avoided by indexing the installed packages according to their versions (as well as other relevant configuration options), so that different projects can retrieve the dependency versions they need without stepping on each other's toes.通过根据版本(以及其他相关的配置选项)索引已安装的包,避免依赖之间的版本冲突,这样不同的项目就可以检索他们需要的依赖版本,而不会相互踩踏。 This arrangement is what the cabal-install documentation means by "Nix-style local builds" .这种安排就是cabal-install文档中“Nix 风格的本地构建”的意思

  • When asked to build a project, stack will, rather than going to Hackage, look at the resolver field of stack.yaml .当被要求构建一个项目时, stack会查看 stack.yaml 的resolver字段,而不是去stack.yaml In the default workflow, that field specifies a Stackage snapshot , which is a subset of Hackage packages with fixed versions that are known to be mutually compatible.在默认工作流中,该字段指定Stackage快照,它是具有已知相互兼容的固定版本的 Hackage 包的子集。 stack will then attempt to satisfy the dependencies specified in the .cabal file (or possibly the project.yaml file -- different format, same role) using only what is provided by the snapshot.然后, stack将尝试仅使用快照提供的内容来满足.cabal文件(或可能project.yaml文件——不同格式,相同角色)中指定的依赖项。 Packages installed from each snapshot are registered in separate databases, which do not interfere with each other.从每个快照安装的软件包都注册在不同的数据库中,它们不会相互干扰。

We might say that the stack approach trades some setup flexibility for straightforwardness when it comes to specifying a build configuration.我们可能会说堆栈方法在指定构建配置时牺牲了一些设置灵活性以换取简单性。 In particular, if you know that your project uses, say, the LTS 15.3 snapshot, you can go to its Stackage page and know, at a glance, the versions of any dependency stack might pull from Stackage.特别是,如果你知道你的项目使用了 LTS 15.3 快照,你可以转到它的 Stackage 页面,一目了然地知道任何依赖堆栈的版本都可能从 Stackage 中提取。 That said, both tools offer features that go beyond the basic workflows so that, by and large, each can do all that the other does (albeit possibly in a less convenient manner).也就是说,这两种工具都提供了超出基本工作流程的功能,因此总的来说,每个工具都可以完成另一个工具所做的一切(尽管可能以不太方便的方式)。 For instance, there are ways to freeze exact versions of a known good build configuration and to solve dependencies with an old state of Hackage with cabal-install , and it is possible to require non-Stackage dependencies or override snapshot package versions while using stack .例如,有一些方法可以冻结已知良好构建配置的确切版本,并使用cabal-install 解决旧 Hackage 状态的依赖关系,并且可能需要非 Stackage 依赖关系或在使用stack 时覆盖快照包版本

Lastly, another difference between cabal-install and stack which is big enough to be worth mentioning in this overview is that stack aims at providing a complete build environment, with features such as automatic GHC installation management and Docker integration .最后, cabal-installstack之间的另一个区别在本概述中非常值得一提,这是stack旨在提供完整的构建环境,具有自动 GHC 安装管理Docker 集成等功能 In contrast, cabal-install is meant to be orthogonal to other parts of the ecosystem, and so it doesn't attempt to provide this sort of feature (in particular, GHC versions have to be installed and managed separately, be it through Linux distro packages, the Haskell Platform Core in Windows, or the ghcup tool ).相比之下, cabal-install旨在与生态系统的其他部分正交,因此它不会尝试提供此类功能(特别是 GHC 版本必须单独安装和管理,无论是通过 Linux 发行版)包、Windows 中的Haskell 平台核心ghcup 工具)。

From what I can glean from the FAQ, it seems that Stack uses the Cabal library, but not the cabal.exe binary (more correctly known as cabal-install).从我从 FAQ 中收集到的信息来看,Stack 似乎使用了 Cabal 库,而不是cabal.exe二进制文件(更正确地称为 cabal-install)。 It looks like the aim of the project is automatic sandboxing and avoidance of dependency hell.看起来该项目的目标是自动沙箱和避免依赖地狱。

In other words, it uses the same Cabal package structure, it just provides a different front-end for managing this stuff.换句话说,它使用相同的 Cabal 包结构,只是提供了一个不同的前端来管理这些东西。 (I think!) (我认为!)

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

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