Haskell Cabal:“包间接依赖于同一包装的多个版本” [英] Haskell Cabal: "package indirectly depends on multiple versions of the same package"

查看:251
本文介绍了Haskell Cabal:“包间接依赖于同一包装的多个版本”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

After clearing out all of my cabal installed packages, I ran this following session:

$ 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
$ 

所以我可以' t安装 cabal-dev 显然是

So the reason I can't install cabal-dev is apparently either that


  • 它间接地依赖于多个版本的相同包。但是, cabal 不会声明它所声称的包 cabal-dev 需要多个版本。

  • Cabal-1.14.0 具有缺少或递归依赖关系,具体涉及 array-0.4.0.0 containers-0.4.2.1

  • it "indirectly depends on multiple versions of the same package." However, cabal does not name the package that it claims cabal-dev requires multiple versions of.
  • Cabal-1.14.0 has "missing or recursive dependencies", specifically somehow involving array-0.4.0.0 and containers-0.4.2.1.

它列出的依赖关系确认这两个声明都不正确(或者它列出的依赖关系是假的或不完整的):

A graph of the dependencies it lists confirms that neither of these claims are true (or the dependencies it lists are false or incomplete):

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

So: what am I missing? Who or what is incorrect: me, cabal, or one or more packages?

我是运行:

$ 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
$


推荐答案

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

The problem arises when we have package B and C already installed but built against different versions of D and then we try to use both packages B and C together in package A: Diamond dependency problem This can work ok but only if packages B and C do not expose types defined in D in their interfaces. If they do then package A will not be able to use functions from B and C together because they will not be working with the same type. That is you'll get a type error.

选择一个具体的例子,假设包D是bytestring,我们同时安装了bytestring-0.9.0.1和0.9.0.4 。让我们说B是utf8-string,C是正则表达式。让我们说包A是彝编辑程序。所以重点在于,在Yi的代码中的某个地方,我们希望将作为UTF-8解码的结果产生的测试通过作为输入到正则表达式函数之一。但是这不起作用,因为utf8-string包中的函数正在使用Bytestring-0.9.0.1中的ByteString类型,而regex包中的正则表达式函数正在使用Bytestring-0.9.0.4中的ByteString类型。所以当我们尝试编译Yi时,我们得到一个类型错误:

To pick a concrete example, suppose package D is bytestring and we have both bytestring-0.9.0.1 and 0.9.0.4 installed. Lets say B is utf8-string and C is regex-base. Lets say that package A is the Yi editor program. So the point is, at some place in the code in Yi we want to pass a bytestring produced as the result of UTF-8 decoding as input to one of the regex functions. But this does not work because the functions in the utf8-string package are using the ByteString type from bytestring-0.9.0.1 while the regex functions in the regex package are using the ByteString type from bytestring-0.9.0.4. So we get a type error when we try to compile Yi:

无法匹配预期的类型 bytestring-0.9.0.4:Data.ByteString。 ByteString'
对推断类型
bytestring-0.9.0.1:Data.ByteString.ByteString'

Couldn't match expected type bytestring-0.9.0.4:Data.ByteString.ByteString' against inferred typebytestring-0.9.0.1:Data.ByteString.ByteString'

就GHC而言,这些两种类型完全不相关!

As far as GHC knows, these two types are totally unrelated!

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

This is obviously extremely annoying. There is also no easy solution. In this example we're assuming that packages B and C have already been built, so there is actually no way to sensibly use the two packages together without rebuilding on of them against a different version of package D. In this case the obvious solution is to rebuild B to use the D-1.1 rather than D-1.0. The problem with rebuilding a package of course is it breaks all other packages that have already been built against it. It isn't clear that you want a package manager to go automatically rebuilding lots of apparently unrelated packages.

从长远来看,最佳解决方案似乎是做什么尼克斯在上面的例子中,Nix将根据D-1.1建立的内置B对应D-1.0,而不是根据D-1.1建立B,而N则将添加另一个针对D-1.1构建的B实例。所以B的原始实例将保持不变,没有什么会破坏。这是功能性的方法:我们不会突变价值(已安装的软件包),我们只需要创建新的值,而当不再需要时,垃圾收集旧的。

In the longer term the best solution would seem to be to do what Nix does. In the above example, instead of replacing package B built against D-1.0 with B built against D-1.1, Nix would add another instance of B built against D-1.1. So the original instance of B would remain unchanged and nothing would break. It's the functional approach: we never mutate values (installed packages) we just create new ones and garbage collect old one when they are no longer needed.

在实践中,这意味着我们必须使用包的一些散列和所有相关包的散列来识别已安装的包。 jhc已经做到了这一点,并且有一些动作要做一些类似于GHC的操作,尽管更多的是跟踪API / ABI的变化。对于基于源代码的软件包管理,我认为这是正确的方向。

In practice it means we have to identify installed packages using some hash of the package and the hashes of all dependent packages. jhc already does this and there are moves afoot to do something similar for GHC, though aimed more at tracking API/ABI changes. For sane source based package management, I think it's the right direction to take.

我应该注意,这不是一个新问题。自从ghc开始允许同时安装同一个软件包的多个版本以来,您就可以构建这个问题。我们现在只是注意到它更多的频率,因为我们拆分了基础包,并允许这些拆分包升级。

I should note that this is not a new problem. You've been able to construct this problem ever since ghc started to allow multiple versions of the same package to be installed at once. We are just noticing it a lot more frequently now because we split up the base package and allow those split-out packages to be upgraded.

目前的播放状态是Cabal警告这个问题,但并没有真正帮助你解决它。对于上面的例子,我们将得到:

The current state of play is that Cabal warns of this problem but doesn't really help you solve it. For the above example we'd get:

$ 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

这篇关于Haskell Cabal:“包间接依赖于同一包装的多个版本”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆