Tom*_*lis 4 linker haskell 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
Run Code Online (Sandbox Code Playgroud)
(问题最终源于使用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?
Edw*_*ang 12
所以,你没有在这个bug本身给我足够的信息,但我将尝试使用我的通灵调试能力来回答你的问题.
您试图编译依赖于包p和的GHC程序q.您可能使用-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)
Run Code Online (Sandbox Code Playgroud)
当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这是针对安装unix-2.6.0.1,而不是unix-2.7.1.0
查看并查看是否有q针对旧版本安装的版本unix,并明确请求它.默认情况下,如果包有多种可能的选择,GHC将选择最新版本.您可以告诉它使用早期版本.
重新安装p编译的NEWER版本unix-2.7.1.0.然后GHC会把它拿起来并且没有不兼容性.请注意,它必须是一个较新的版本,因为今天的Cabal不会让你有一个p-0.1针对unix-2.6.0.1AS WELL p-0.1编译的副本作为编译的副本unix-2.7.1.0.傻吧?我们正试图修复它.
吹走你.cabal和.ghc目录,然后cabal install将最新版本的unix,然后一切.然后一切都将(可能)针对新版本进行编译,unix并且不会出现问题.
以下是三个不太有用的解决方案:
请注意,您实际上只是获取此链接错误,因为unix即使在不同版本的程序包中也会为C源分配相同的名称(Haskell标识符不是这种情况,它们是正确的版本前缀).如果unix修复了所有的C符号都是版本前缀,你就不会看到这个问题而你的程序编译得很好.好吧,除非你试图同时使用两个不同版本的类型unix(然后你会被告知这unix-2.6.0.1:BlahBlah不同于unix-2.7.1.0:BlahBlah.如果你很幸运.)现在没有关于如何做到这一点的惯例但是有一个关于它的GHC门票:https://ghc.haskell.org/trac/ghc/ticket/9351
最近,有些人提出GHC应该在实现阴影时强制执行更强的一致性约束,即与Cabal强制执行的约束相同.在那个世界里,GHC不会已经能够找到的一个p或q,并会报告说,并不是所有的包都是满足的.那会更好吗?如何执行此操作的计划是Cabal管理包数据库的一致"视图",这样当您ghc单独使用时,您将永远不会看到实际上不可见的包.这就是GSoC项目:https://www.google-melange.com/gsoc/project/details/google/gsoc2015/vishal4556/5634387206995968
也许您可能会说,"忘记所有这些花哨的视图业务,实际上,GHC应该对您尝试使用的软件包进行更好的一致性检查,以确保它与版本映射的名称一致." (顺便说一句,简化检查将是安装程序可执行文件当前执行的操作).去年夏天,我试图说服邓肯GHC应该这样做,但他认为这是Cabal的工作,我们不应该在GHC中复制这些代码.所以到目前为止,GHC bugtracker还没有建议我们应该这样做.