神秘的 cabal-install 问题

9

在进行“Haskell平台”(OS X Snow-Leopard & Platform 2010.1.0.1)的全新安装后,执行此操作会导致简单序列引起非常奇怪的cabal install行为:

$ cabal install time

$ cabal install random

$ ghc-pkg list random
/Library/Frameworks/GHC.framework/Versions/612/usr/lib/ghc-6.12.1/package.conf.d
   random-1.0.0.2
/Users/yairc/.ghc/i386-darwin-6.12.1/package.conf.d
   random-1.0.0.2

我的系统中安装了两次random-1.0.0.2,现在每次运行cabal install random都会重新安装random-1.0.0.2

看起来random依赖于time,当有新版本的time可用时,cabal希望重新安装它?由于存在两个random-1.0.0.2,cabal感到困惑,并且总是认为它不是最新的,因为它查看的是第一个版本?

ghc-pkg check未发现错误。

3个回答

6
请执行以下操作。
ghc-pkg check

如果没有显示错误,让我们看一下输出结果:

ghc-pkg list -v

并且

cabal install random -v

编辑:我可以复现您在GHC 6.12.1下的问题,但是在使用完全相同版本的cabal-install(0.8.0)时,无法重现该问题。我会研究一下。

编辑2已报告为cabal-install中的错误


感谢您的出现!:) 我已经将这些命令的输出添加到我的问题中。 - yairchu

2
我将描述一下目前为止对我有效的解决方法。我尝试了许多不同的方法,但这里只描述成功的尝试。
(顺便说一句:我正在使用Mac OS X 10.6.4,您在不同的系统上可能会得到不同的结果)
  • 我从源代码安装了 GHC 6.12.3。构建 GHC 需要保留先前的 GHC。
  • 我删除了 /usr/bin 中的符号链接(ghc、ghci、ghc-pkg 和 runhaskell),这些链接指向我之前安装的 Haskell Platform 2010.1.0.1 版本。
  • 我使用 cabal-install 的 bootstrap.sh 脚本安装了它。
  • 我安装了经过修补的 random 和 haskell98 包的版本。它们的区别仅在于它们的 .cabal 文件
    • 将 random 的版本提升到 1.0.0.2.1,并将其对 time 的依赖关系更改为 time == 1.1.*
    • 将 haskell98 的版本提升到 1.0.1.1.1
  • 我运行了 cabal update 和 cabal upgrade 以查看哪些软件包已过时。我使用 cabal install 安装了那些软件包。我认为这有助于更快地达到稳定状态。(请注意,syb 的安装失败了,而 cabal install parsec 却说没有任何问题,而 cabal upgrade 则说有问题。所以我将这两个软件包保持不变)

我通过在各个阶段之间运行 ghc-pkg check 来验证我的设置是否正确。有时会出现问题,因为某个软件包被重新安装到具有相同版本号的先前版本上,并且依赖于它的软件包需要重新安装。当发生这种情况时,我再次使用 cabal install 安装已损坏的软件包。

我还使用了以下程序来验证我的设置中是否包含具有相同版本的两个软件包:

import Data.List (sort)
import Data.Maybe (fromJust)
import System.IO (hGetContents)
import System.Process (CreateProcess (std_out), StdStream (CreatePipe), createProcess, shell)

main :: IO ()
main = do
    pkgListRaw <-
        createProcess (shell "ghc-pkg list") { std_out = CreatePipe }
        >>= hGetContents . fromJust . sndOfFourTup
    let pkgListSorted = sort . filter (not . null) $ lines pkgListRaw
    putStrLn .
        unlines . map (dropWhile (== ' ') . fst) .
        filter (uncurry (==)) . zip pkgListSorted $ tail pkgListSorted
    where
        sndOfFourTup (_, x, _, _) = x
  • 我用 cabal install 安装了 hlintyesodhaddockHDBC-mysqlhakyll 和其他包,然后一遍又一遍地安装前面的列表,直到我的设置达到了“稳定状态”,在这种状态下,cabal install 不会重新安装任何这些包。

  • 我验证了我正在开发的程序编译和工作。现在一切都很好。

注:

  • 我无法让 Haskell Platform 2010.1.0.1 正常工作。只有在我升级到 GHC 6.12.3 后,事情才对我起作用。具有讽刺意味的是,这与 GHC 的下载页面上的建议相反:

停!

对于大多数用户,我们建议安装 Haskell Platform 而不是 GHC。当前的 Haskell Platform 发布包括最近的 GHC 发布以及一些其他工具(如 cabal)和一个更大的库集合,这些库已知可以一起使用。

  • 这种解决方法可能在未来某个时候也会失效。我猜大概几个月后就会出现问题。像random这样的核心库将得到更新,然后依赖问题将再次浮出水面。那时我/你将不得不花时间修复我们的设置。也许需要升级到更高版本的GHC。但谁知道,也许会有一个较旧的版本由于Hackage包的更新而变得稳定。当时机成熟时,我将为您更新此问题和答案。(假设其他人也遇到了此问题。至今为止,我已验证Simon Marlow和Peaker也面临此问题)

  • 判断您的Haskell设置是否损坏的方法(如果以下任一情况成立,则设置损坏):

    • 什么都不起作用
    • ghc-pkg check指示其已损坏
    • 上述答案中我放置源代码的简短程序发现您安装了两个完全相同版本的软件包
    • cabal update,然后循环执行安装我上面列出的软件包列表,或另一个列表(最好是具有许多依赖项的大型列表)。如果您从未达到稳定状态(循环的每个迭代都重新安装了某些内容),则您的设置已损坏。警告:此步骤可能会破坏您当前运行的Haskell设置。如果您是 maso-curious 或愿意修复损坏后的设置(这可能需要耗费时间)时,请执行此操作。
  • 我想知道您的设置是损坏还是正常工作的。这可以帮助我。例如,如果我们发现GHC 6.10的设置没有问题,我/您就可以在向某人推荐尝试Haskell等语言时建议他们使用这些设置。

我希望这能帮助面临同样或类似问题的其他人。非常感谢Simon Marlow和John!


2

我有两种可能的解决方案,两者都有一定的危险性,但应该可以让您获得一个可用的安装。我很高兴Simon在跟进这个问题,因为这听起来像是某种bug。为了获得一个可用的安装,我建议首先尝试以下方法:

ghc-pkg unregister random

然后执行ghc-pkg list random,查看已安装的内容。我猜(但不确定)你仍然有来自平台的/Library/Frameworks版本,但新安装的版本将会消失。如果是这种情况,请继续下一步。如果不是,你可能需要重新干净地安装平台。

假设平台上的random仍然存在,请执行以下操作:

cabal unpack random

切换到解压后的目录,并通过将版本号提升为1.0.0.2.1(添加另一个字段并将其递增一)来编辑.cabal文件。然后从该目录安装cabal,它应该会安装新的随机数生成器。由于这个版本与平台随机数生成器不同,因此两者可以安全共存。

与其使用ghc-pkg unregister,你可以直接从以下位置删除注册文件:

/Users/yairc/.ghc/i386-darwin-6.12.1/package.conf.d

文件名将带有哈希值附加在其后,因此您需要查看目录内容以获取实际值。只需删除该文件,ghc-pkg和cabal就不应再看到它。这不会影响平台的安装(因此从这个意义上说更安全),但仍可能破坏其他已安装的软件包。完成后,您可以按照上述步骤重新安装随机数生成器。


我尝试了类似的东西,一开始它是有效的。我修补了randomhaskell98,我目前正在工作的项目也正常运行。我决定通过cabal install安装hlinthoogledarcsHDBC-mysqlauthenticatehakyll来进行更精细的检查,并重复这个过程以验证我是否达到了一个固定点。最后,几乎每一个随着Haskell平台一起安装的包都出现了问题。我的下一步尝试是禁用cabal的user-install选项。 - yairchu
经过几次尝试,我终于成功地解决了问题!我在下面的答案中描述了我的解决方法。谢谢! - yairchu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接