GHC应该链接相同库的不同版本吗?

时间:2015-06-06 21:51:46

标签: haskell linker ghc

我试图使用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吗?

1 个答案:

答案 0 :(得分:12)

所以,你还没有在这个bug中给我足够的信息,但是我将尝试使用我的通灵调试能力来回答你的问题。

您尝试编译依赖于包pq的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.1unix-2.7.1.0),并且我的通灵调试权力表示在您的扩展中包数据库,这也是事实。 (顺便说一下,如果你正在运行GHC 7.10,那么阴影检查确保任何包密钥它没有选择两个不同的已安装软件包ID。所以这几乎可以保证是真的。)

所以GHC接受kaboodle,我们尝试链接两个不同版本的unix。糟糕!

那么,你应该怎么做?以下是您的选择。

  1. 使用Cabal。 Cabal将强制执行更强的约束,即每个PACKAGE NAME只有一个PACKAGE VERSION。因此,当您尝试cabal configure时,它会告诉您它无法解决依赖关系,或者可能会选择针对q而不是{{1}安装的unix-2.6.0.1的早期版本}}

  2. 查看是否有unix-2.7.1.0的版本是针对较旧的q安装的,并明确请求它。默认情况下,如果包有多种可能的选择,GHC将选择最新版本。您可以告诉它使用早期版本。

  3. 重新安装针对unix编译的p的NEWER版本。然后GHC会接受它并且没有不兼容性。请注意,它必须是更新的版本,因为今天的Cabal不会让你有unix-2.7.1.0的副本编译为p-0.1 AS WELL的副本unix-2.6.0.1编译为p-0.1。傻吧?我们正在尝试解决此问题。

  4. 吹走您的unix-2.7.1.0.cabal目录,然后.ghc最新版本的cabal install,然后是其他所有内容。然后,一切都将(可能)针对新版unix进行编译,并且不会出现问题。

  5. 以下是另外三个不太有用的解决方案:

    1. 请注意,您实际上只是收到此链接错误,因为unix具有C源,即使在不同版本的包下也会分配相同的名称(Haskell标识符不是这种情况,它们是正确版本前缀)。如果unix被修复以使其所有C符号都是版本前缀,那么你就不会看到这个问题而且你的程序编译得很好。好吧,除非您尝试同时使用两个不同版本的unix中的类型(然后您被告知unixunix-2.6.0.1:BlahBlah不同。如果您&#39很幸运。)现在没有关于如何做到这一点的惯例,但有关于它的GHC门票:https://ghc.haskell.org/trac/ghc/ticket/9351

    2. 最近,有些人提出GHC应该在实现阴影时强制执行更强的一致性约束,即与Cabal强制执行的约束相同。在那个世界中,GHC无法找到unix-2.7.1.0:BlahBlahp中的一个,并且会报告并非所有包都可以满足。那会更好吗?如何执行此操作的计划是让q管理一致的"视图"包数据库,所以当你单独使用Cabal时,你永远不会看到实际上不可见的包。这个GSoC项目就是:https://www.google-melange.com/gsoc/project/details/google/gsoc2015/vishal4556/5634387206995968

    3. 也许您可能会说,"忘掉所有这些花哨的观看业务,实际上,GHC应该对您尝试使用的软件包进行更好的一致性检查,以确保它能够使用它。与版本映射的名称一致。" (顺便说一句,简化检查将是安装程序可执行文件当前执行的操作)。去年夏天,我试图说服邓肯GHC应该这样做,但他认为这是Cabal的工作,我们不应该在GHC中复制这些代码。所以到目前为止,GHC bugtracker还没有建议我们应该这样做。

相关问题