GHC 是否应该链接相同库的不同版本?
Should GHC be linking different versions of the same libraries?
我正在尝试使用 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 真的应该尝试 link 两个不同版本的 unix
吗?
所以,关于这个错误本身,你没有给我足够的信息,但我将尝试使用我的心理调试能力来回答你的问题。
您试图编译依赖包 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,我们尝试 link 在两个不同版本的 unix
中。糟糕!
那么,你该怎么办?这是您的选择。
使用 Cabal。 Cabal 将强制执行更强的约束,即对于每个 PACKAGE NAME,只有一个 PACKAGE VERSION。因此,当您尝试 cabal configure
时,它会告诉您它无法解析依赖关系,或者可能会选择针对 unix-2.6.0.1
而不是 unix-2.7.1.0
安装的 q
的早期版本
查看您是否有针对旧版 unix
安装的 q
版本,并明确请求它。默认情况下,如果一个包有多个可能的选择,GHC 将选择最新版本。您可以告诉它使用较早的版本。
重新安装针对 unix-2.7.1.0
编译的 p
的较新版本。然后 GHC 将拾取它并且没有不兼容。请注意,它必须是较新的版本,因为今天的 Cabal 不会让您拥有针对 unix-2.6.0.1
编译的 p-0.1
的副本以及针对 [=22= 编译的 p-0.1
的副本].傻吧?我们正在努力修复它。
删除您的 .cabal
和 .ghc
目录,然后 cabal install
最新版本的 unix
,然后是其他所有内容。然后一切都将(可能)针对新版本 unix
进行编译,不会有问题。
这里还有三个不太有用的解决方案:
请注意,您实际上只会收到此 link 错误,因为 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在实现shadowing时应该强制执行更强的一致性约束,即Cabal强制执行的相同约束。在那个世界中,GHC 将无法找到 p
或 q
之一,并且会报告并非所有包都是可满足的。那会更好吗?如何做到这一点的计划是让 Cabal
管理一个一致的 "view" 包数据库,这样当你单独使用 ghc
时,你永远不会看到不应该看到的包实际上是可见的。这就是这个 GSoC 项目:https://www.google-melange.com/gsoc/project/details/google/gsoc2015/vishal4556/5634387206995968
也许您可能会说,"Forget about all this fancy view business, really, GHC should just do a better consistency check on the packages you try to make it use to make sure that it's consistent with respect to a name to version mapping."(顺便说一句,安装程序可执行文件当前执行的检查将是一个简化的检查)。去年夏天我试图说服 Duncan GHC 应该这样做,但他坚定地认为这是 Cabal 的工作,我们不应该在 GHC 中复制这段代码。所以直到今天,GHC bugtracker 上还没有票据建议我们应该这样做。
我正在尝试使用 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 真的应该尝试 link 两个不同版本的 unix
吗?
所以,关于这个错误本身,你没有给我足够的信息,但我将尝试使用我的心理调试能力来回答你的问题。
您试图编译依赖包 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,我们尝试 link 在两个不同版本的 unix
中。糟糕!
那么,你该怎么办?这是您的选择。
使用 Cabal。 Cabal 将强制执行更强的约束,即对于每个 PACKAGE NAME,只有一个 PACKAGE VERSION。因此,当您尝试
cabal configure
时,它会告诉您它无法解析依赖关系,或者可能会选择针对unix-2.6.0.1
而不是unix-2.7.1.0
安装的q
的早期版本查看您是否有针对旧版
unix
安装的q
版本,并明确请求它。默认情况下,如果一个包有多个可能的选择,GHC 将选择最新版本。您可以告诉它使用较早的版本。重新安装针对
unix-2.7.1.0
编译的p
的较新版本。然后 GHC 将拾取它并且没有不兼容。请注意,它必须是较新的版本,因为今天的 Cabal 不会让您拥有针对unix-2.6.0.1
编译的p-0.1
的副本以及针对 [=22= 编译的p-0.1
的副本].傻吧?我们正在努力修复它。删除您的
.cabal
和.ghc
目录,然后cabal install
最新版本的unix
,然后是其他所有内容。然后一切都将(可能)针对新版本unix
进行编译,不会有问题。
这里还有三个不太有用的解决方案:
请注意,您实际上只会收到此 link 错误,因为
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在实现shadowing时应该强制执行更强的一致性约束,即Cabal强制执行的相同约束。在那个世界中,GHC 将无法找到
p
或q
之一,并且会报告并非所有包都是可满足的。那会更好吗?如何做到这一点的计划是让Cabal
管理一个一致的 "view" 包数据库,这样当你单独使用ghc
时,你永远不会看到不应该看到的包实际上是可见的。这就是这个 GSoC 项目:https://www.google-melange.com/gsoc/project/details/google/gsoc2015/vishal4556/5634387206995968也许您可能会说,"Forget about all this fancy view business, really, GHC should just do a better consistency check on the packages you try to make it use to make sure that it's consistent with respect to a name to version mapping."(顺便说一句,安装程序可执行文件当前执行的检查将是一个简化的检查)。去年夏天我试图说服 Duncan GHC 应该这样做,但他坚定地认为这是 Cabal 的工作,我们不应该在 GHC 中复制这段代码。所以直到今天,GHC bugtracker 上还没有票据建议我们应该这样做。