【问题标题】:Haskell Cabal: "package indirectly depends on multiple versions of the same package"Haskell Cabal:“包间接依赖于同一个包的多个版本”
【发布时间】:2012-03-07 06:02:10
【问题描述】:

在清除了我所有的 cabal installed 包后,我运行了以下会话:

$ cabal update
Downloading the latest package list from hackage.haskell.org
james@bast:~/.cabal/packages$ cabal install cabal-dev
Resolving dependencies...
Downloading cabal-dev-0.9.1...
[1 of 1] Compiling Main             ( /tmp/cabal-dev-0.9.124882/cabal-dev-0.9.1/Setup.hs, /tmp/cabal-dev-0.9.124882/cabal-dev-0.9.1/dist/setup/Main.o )
Linking /tmp/cabal-dev-0.9.124882/cabal-dev-0.9.1/dist/setup/setup ...
Configuring cabal-dev-0.9.1...
Warning: This package indirectly depends on multiple versions of the same
package. This is highly likely to cause a compile failure.
package containers-0.4.2.1 requires array-0.4.0.0
package Cabal-1.14.0 requires array-0.4.0.0
package text-0.11.1.13 requires array-0.4.0.0
package deepseq-1.3.0.0 requires array-0.4.0.0
package containers-0.4.2.1 requires array-0.4.0.0
package HTTP-4000.2.2 requires array-0.4.0.0
package cabal-dev-0.9.1 requires containers-0.4.2.1
package Cabal-1.14.0 requires containers-0.4.2.1
package template-haskell-2.7.0.0 requires containers-0.4.2.1
Building cabal-dev-0.9.1...
Preprocessing executable 'ghc-pkg-6_8-compat' for cabal-dev-0.9.1...
<command line>: cannot satisfy -package-id Cabal-1.14.0-4af45d3c8d10dc27db38ae0e7e5a952b: 
    Cabal-1.14.0-4af45d3c8d10dc27db38ae0e7e5a952b is unusable due to missing or recursive dependencies:
      array-0.4.0.0-46f61f5fd9543ebf309552ef84dccc86 containers-0.4.2.1-98f9aa15f9c08b13673dc9d89385f449
    (use -v for more information)
cabal: Error: some packages failed to install:
cabal-dev-0.9.1 failed during the building phase. The exception was:
ExitFailure 1
$ 

所以我无法安装 cabal-dev 的原因显然是要么

  • 它“间接依赖于同一个包的多个版本”。但是,cabal 没有命名它声称 cabal-dev 需要多个版本的包。
  • Cabal-1.14.0 具有“缺失或递归依赖”,特别是涉及array-0.4.0.0containers-0.4.2.1

它列出的依赖关系图证实了这些声明都不是真的(或者它列出的依赖关系是错误的或不完整的):

那么:我错过了什么?谁或什么不正确:我、cabal,还是一个或多个包?

我正在跑步:

$ cabal --version
cabal-install version 0.10.2
using version 1.10.1.0 of the Cabal library 
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.4.1
$

【问题讨论】:

  • 看起来好像重建了数组和容器。 ghc-pkg describe 为这些报告什么哈希值?
  • @eegg 您是如何生成该图的?

标签: haskell dependencies package cabal cabal-install


【解决方案1】:

当我们已经安装了包 B 和 C,但针对不同版本的 D 构建,然后我们尝试在包 A 中同时使用包 B 和 C 时,就会出现问题: 钻石依赖问题 这可以正常工作,但前提是包 B 和 C 未在其接口中公开 D 中定义的类型。如果他们这样做了,那么包 A 将无法同时使用 B 和 C 中的函数,因为它们不会使用相同的类型。那就是你会得到一个类型错误。

举一个具体的例子,假设包 D 是 bytestring,我们同时安装了 bytestring-0.9.0.1 和 0.9.0.4。假设 B 是 utf8 字符串,C 是正则表达式。假设包 A 是 Yi 编辑器程序。所以重点是,在 Yi 的代码中的某个地方,我们希望将作为 UTF-8 解码结果生成的字节串作为输入传递给正则表达式函数之一。但这不起作用,因为 utf8-string 包中的函数使用 bytestring-0.9.0.1 中的 ByteString 类型,而 regex 包中的正则表达式函数使用 bytestring-0.9.0.4 中的 ByteString 类型。所以当我们尝试编译 Yi 时会出现类型错误:

无法匹配预期类型bytestring-0.9.0.4:Data.ByteString.ByteString' against inferred typebytestring-0.9.0.1:Data.ByteString.ByteString'

据 GHC 所知,这两种类型是完全不相关的!

这显然非常烦人。也没有简单的解决方案。在这个例子中,我们假设包 B 和 C 已经被构建,所以实际上没有办法明智地一起使用这两个包而不针对不同版本的包 D 重新构建它们。在这种情况下,明显的解决方案是重建 B 以使用 D-1.1 而不是 D-1.0。重建包的问题当然是它破坏了已经针对它构建的所有其他包。不清楚您是否希望包管理器自动重建许多明显不相关的包。

从长远来看,最好的解决方案似乎是做 Nix 所做的事情。在上面的示例中,Nix 不会将针对 D-1.0 构建的包 B 替换为针对 D-1.1 构建的 B,而是添加针对 D-1.1 构建的另一个 B 实例。因此 B 的原始实例将保持不变,并且不会中断。这是一种函数式方法:我们从不改变值(已安装的包),我们只是创建新值并在不再需要旧值时将其回收。

在实践中,这意味着我们必须使用包的一些哈希值和所有依赖包的哈希值来识别已安装的包。 jhc 已经这样做了,并且正在为 GHC 做类似的事情,尽管更多地旨在跟踪 API/ABI 更改。对于健全的基于源的包管理,我认为这是正确的方向。

我应该注意,这不是一个新问题。自从 ghc 开始允许一次安装同一个包的多个版本以来,您就已经能够构造这个问题了。我们现在只是更频繁地注意到它,因为我们拆分了基础包并允许升级这些拆分出来的包。

目前的情况是,Cabal 会警告这个问题,但并不能真正帮助您解决它。对于上面的例子,我们会得到:

$ cabal configure
Configuring A-1.0...
Warning: This package indirectly depends on multiple versions of
the same package. This is highly likely to cause a compile failure.
package B-1.0 requires D-1.0
package C-1.0 requires D-1.1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    相关资源
    最近更新 更多