我试图使用GHC 7.6.3编译程序,我收到错误
/usr/lib/ghc/unix-2.6.0.1/libHSunix-2.6.0.1.a(execvpe.o): In function `pPrPr_disableITimers':
(.text+0x300): multiple definition of `pPrPr_disableITimers'
/home/tom/.cabal/lib/i386-linux-ghc-7.6.3/unix-2.7.1.0/libHSunix-2.7.1.0.a(ghcrts.o):ghcrts.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
(问题最终源于readProcessWithExitCode
的使用,但我认为这并不特别相关)
如果我使用ghc
运行-v
,那么我会在命令行参数中看到
'-L/home/tom/.cabal/lib/i386-linux-ghc-7.6.3/unix-2.7.1.0'
'-L/usr/lib/ghc/unix-2.6.0.1'
'-lHSunix-2.7.1.0'
'-lHSunix-2.6.0.1'
这是一个错误吗? GHC真的应该尝试链接两个不同版本的unix
吗?
答案 0 :(得分:12)
所以,你还没有在这个bug中给我足够的信息,但是我将尝试使用我的通灵调试能力来回答你的问题。
您尝试编译依赖于包p
和q
的GHC程序。您可能使用-package p
和-package q
指定了它们。您的包数据库可能看起来像这样(或者传递看起来像这样):
id: p-0.1-8aa5d403c45ea59dcd2c39f123e27d57
depends: unix-2.6.0.1-9ce33138f4fcfb9c37f6e6c300bcc367
id: q-0.1-d5221a8c8a269b66ab9a07bdc23317dd
depends: unix-2.7.1.0-2f15426f5b53fe4c6490832f9b20d8d7
id: unix-2.6.0.1-9ce33138f4fcfb9c37f6e6c300bcc367
depends: (none)
id: unix-2.7.1.0-2f15426f5b53fe4c6490832f9b20d8d7
depends: (none)
当GHC查找包p
时,它会看到p-0.1-8aa5d403c45ea59dcd2c39f123e27d57
并决定使用它。然后,当它查找包q
时,它会看到q-0.1-d5221a8c8a269b66ab9a07bdc23317dd
并决定使用它。然后进行一致性检查,以确保对于任何包ID foo-0.1
,它没有选择两个已安装的包ID。在我的示例中,这很简单,因为选择的unix
的两个版本具有不同的包ID(unix-2.6.0.1
和unix-2.7.1.0
),并且我的通灵调试权力表示在您的扩展中包数据库,这也是事实。 (顺便说一下,如果你正在运行GHC 7.10,那么阴影检查确保任何包密钥它没有选择两个不同的已安装软件包ID。所以这几乎可以保证是真的。)
所以GHC接受kaboodle,我们尝试链接两个不同版本的unix
。糟糕!
那么,你应该怎么做?以下是您的选择。
使用Cabal。 Cabal将强制执行更强的约束,即每个PACKAGE NAME只有一个PACKAGE VERSION。因此,当您尝试cabal configure
时,它会告诉您它无法解决依赖关系,或者可能会选择针对q
而不是{{1}安装的unix-2.6.0.1
的早期版本}}
查看是否有unix-2.7.1.0
的版本是针对较旧的q
安装的,并明确请求它。默认情况下,如果包有多种可能的选择,GHC将选择最新版本。您可以告诉它使用早期版本。
重新安装针对unix
编译的p
的NEWER版本。然后GHC会接受它并且没有不兼容性。请注意,它必须是更新的版本,因为今天的Cabal不会让你有unix-2.7.1.0
的副本编译为p-0.1
AS WELL的副本unix-2.6.0.1
编译为p-0.1
。傻吧?我们正在尝试解决此问题。
吹走您的unix-2.7.1.0
和.cabal
目录,然后.ghc
最新版本的cabal install
,然后是其他所有内容。然后,一切都将(可能)针对新版unix
进行编译,并且不会出现问题。
以下是另外三个不太有用的解决方案:
请注意,您实际上只是收到此链接错误,因为unix
具有C源,即使在不同版本的包下也会分配相同的名称(Haskell标识符不是这种情况,它们是正确版本前缀)。如果unix
被修复以使其所有C符号都是版本前缀,那么你就不会看到这个问题而且你的程序编译得很好。好吧,除非您尝试同时使用两个不同版本的unix
中的类型(然后您被告知unix
与unix-2.6.0.1:BlahBlah
不同。如果您&#39很幸运。)现在没有关于如何做到这一点的惯例,但有关于它的GHC门票:https://ghc.haskell.org/trac/ghc/ticket/9351
最近,有些人提出GHC应该在实现阴影时强制执行更强的一致性约束,即与Cabal强制执行的约束相同。在那个世界中,GHC无法找到unix-2.7.1.0:BlahBlah
或p
中的一个,并且会报告并非所有包都可以满足。那会更好吗?如何执行此操作的计划是让q
管理一致的"视图"包数据库,所以当你单独使用Cabal
时,你永远不会看到实际上不可见的包。这个GSoC项目就是:https://www.google-melange.com/gsoc/project/details/google/gsoc2015/vishal4556/5634387206995968
也许您可能会说,"忘掉所有这些花哨的观看业务,实际上,GHC应该对您尝试使用的软件包进行更好的一致性检查,以确保它能够使用它。与版本映射的名称一致。" (顺便说一句,简化检查将是安装程序可执行文件当前执行的操作)。去年夏天,我试图说服邓肯GHC应该这样做,但他认为这是Cabal的工作,我们不应该在GHC中复制这些代码。所以到目前为止,GHC bugtracker还没有建议我们应该这样做。