什么是Cabal Hell?

时间:2018-06-19 10:17:02

标签: haskell cabal

在阅读Cabal Hell时,我有点困惑,因为这个词过载了。我猜最初的Cabal Hell提到了钻石依赖问题,它通过限制构建计划在每个构建计划中只有一个版本的任何软件包来解决(一个软件包的两个不同版本不能存在于单个构建计划中)正如本answer中所述。

但是,该术语也用于其他各种情况。例如破坏性重新安装,不正确的包依赖性边界(下限/上限版本),不一致的环境......(或Cabal报告的任何其他错误)。

特别是这些,我很困惑1)破坏性重新安装和2)不一致的环境?他们是什么意思,以及cabal new-build如何解决这些问题(它只是像cabal sandbox这样的沙箱)? ghc-pkg在这里扮演什么角色?

非常感谢任何可以复制这些问题的参考资料或简单例子。

关于“破坏性重新安装”:如果我没有错,GHC有自己的包管理器(ghc-pkg),并且包安装为动态可链接库,即:base依赖于ghc-prim,如果ghc-prim被删除,它将会中断base,我是对的吗?并且由于GHC仅允许具有相同版本的包的一个实例,cabal install可能注册相同(package, version)的较新版本,以便它打破未注册包的依赖项。如果上述关于“破坏性重新安装”的理解是正确的; cabal new-build如何在这里提供帮助?

1 个答案:

答案 0 :(得分:5)

该术语的唯一有意义的用法是链接答案中给出的术语。与此相关的是全局数据库中包含许多不同软件包的后续问题,这些问题可能使遇到钻石的依赖关系变得更加普遍,需要破坏性的重新安装才能解决等等。

该术语的其他用法无济于事,仅表示“以某种方式涉及阴谋集团的问题”。

那是,让我回答您的其他问题。

1)ghc-pkg不是程序包管理器,而是用于管理ghc程序包数据库的工具。 cabal使用它来将软件包注册到数据库中,并且最终用户可以使用它来检查数据库的内容。可以将其视为ghc提供的基础衬底的一部分,而不是竞争工具。

2)new-build完全消除并替换了packagedb的标准概念。 db并不是说db由软件包和版本组成,每对最多有一个,而是db由任何给定版本的软件包的许多副本组成,每个副本都有其依赖关系的潜在版本,所有这些都在以下位置管理通过散列寻址来区分,因此具有唯一的“指纹”标记。这称为storenew-build时,cabal会从头开始计算构建计划,而与先前安装的任何依赖项无关。如果商店中已经存在特定的指纹(包括软件包,版本及其所有依赖项的版本,某些标志等),则它将使用该指纹。如果没有,它将进行计算。

因此,唯一可能出现的“钻石依赖”是真正不可溶的,而不是由于过早固定(由于已经安装了dep)而导致的某些部分依赖树。

tldr;您写了“因为GHC只允许一个版本相同的软件包实例”,但是新建版本部分解除了store中的这一限制,这使求解器可以更频繁地生成更好,更可重复的计划。