簡體   English   中英

Haskell Cabal:“包間接取決於同一包的多個版本”

[英]Haskell Cabal: “package indirectly depends on multiple versions of the same package”

在清除了我的所有cabal install ed包之后,我運行了以下會話:

$ 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-dev-0.9.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
$

當我們已經安裝了包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-string而C是regex-base。 可以說包A是Yi編輯程序。 所以關鍵是,在Yi的代碼中的某個地方,我們希望將作為UTF-8解碼結果產生的字節串作為輸入傳遞給其中一個正則表達式函數。 但這不起作用,因為utf8-string包中的函數使用bytestring-0.9.0.1中的ByteString類型,而regex包中的regex函數使用bytestring-0.9.0.4中的ByteString類型。 所以當我們嘗試編譯Yi時會出現類型錯誤:

無法匹配期望類型bytestring-0.9.0.4:Data.ByteString.ByteString' against inferred type -0.9.0.4:Data.ByteString.ByteString' bytestring-0.9.0.4:Data.ByteString.ByteString' against inferred type bytestring-0.9.0.1:Data.ByteString.ByteString'

據GHC所知,這兩種類型完全不相關!

這顯然非常煩人。 也沒有簡單的解決方案。 在這個例子中,我們假設已經構建了包B和C,所以實際上沒有辦法合理地使用這兩個包而不用針對不同版本的包D重建它們。在這種情況下,顯而易見的解決方案是重建B使用D-1.1而不是D-1.0。 重建程序包的問題當然是它打破了已經針對它構建的所有其他包。 目前尚不清楚您是否希望程序包管理器自動重建大量明顯不相關的程序包。

從長遠來看,最好的解決方案似乎是做Nix所做的事情。 在上面的例子中,Nix不是用針對D-1.1構建的B替換針對D-1.0構建的包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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM