`cabal repl` 导致带有 C++ 文件的简单项目出现 GHC 恐慌

`cabal repl` causes GHC panic on simple project with C++ files

我已将项目上传为 zip 文件,您可以试用一下。 https://dl.dropboxusercontent.com/u/35032740/ShareX/2015/11/Buggy.zip

我想围绕 clipper 库编写一个包装器。代码使用 cabal build 编译良好,使用 cabal run 运行但 cabal repl 产生此错误:

Preprocessing executable 'Buggy' for Buggy-0.1.0.0...
GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
GHC runtime linker: fatal error: I found a duplicate definition for symbol
   _ZNSt6vectorIN10ClipperLib8IntPointESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_
whilst processing object file
   dist\build\Buggy\Buggy-tmp\wrapper.o
This could be caused by:
   * Loading two different object files which export the same symbol
   * Specifying the same object file twice on the GHCi command line
   * An incorrect `package.conf' entry, causing some object to be
     loaded twice.
ghc.exe: panic! (the 'impossible' happened)
  (GHC version 7.10.2 for x86_64-unknown-mingw32):
        loadObj "dist\build\Buggy\Buggy-tmp\wrapper.o": failed

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

作为参考,这里是 cabal 文件

-- Initial Buggy.cabal generated by cabal init.  For further documentation,
--  see http://haskell.org/cabal/users-guide/

name:                Buggy
version:             0.1.0.0
-- synopsis:
-- description:
-- license:
license-file:        LICENSE
author:              Luka Horvat
maintainer:          lukahorvat9@gmail.com
-- copyright:
-- category:
build-type:          Simple
-- extra-source-files:
cabal-version:       >=1.10

executable Buggy
  main-is:             Main.hs
  c-sources:           clipper.cpp
                     , wrapper.cpp
  -- other-modules:
  -- other-extensions:
  build-depends:       base >=4.8 && <4.9
  -- hs-source-dirs:
  default-language:    Haskell2010
  extra-libraries:     stdc++

知道这里的原因是什么吗? 我是 运行 Windows 10、64 位。

具体的错误不是我习惯看到的,但那些反斜杠表示你在 Windows,否则这看起来像 GHC bug #3242 多年来一直造成痛苦现在。好消息:两周前终于查明了病因。坏消息:修复没有在 7.10.3 的最后期限前完成,尽管至少 8.0.1 里程碑在这一点上似乎是安全的。

可能仍然值得将您的错误文本发布到该错误的线程;我的只是一个有根据的猜测,有人肯定知道。

我不知道 Windows 上目标文件格式的细节,所以我猜了一点。

可能 clipper.owrapper.o 都定义了一个名为 _ZNSt6vectorIN10ClipperLib8IntPointESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_weak 符号。 (我在 Linux 上看到了同样的情况。)这可能来自模板实例化(vector)。弱符号指示系统链接器在遇到重复项时只选择符号的任何副本。

Windows 上的 GHCi 不使用系统链接器,它有自己的运行时链接器,可以在运行时将目标文件加载到自身中。因此,它通常与系统链接器不兼容。运行时链接器可能不理解弱符号,至少在 Windows (https://ghc.haskell.org/trac/ghc/ticket/3333) 上是这样。从你得到的错误,我们可以假设它将它们视为常规符号,并且两个常规符号不允许具有相同的名称。

作为解决方法,您可以使用 -fno-weak 构建 C++ 文件,如 中所述。

如果这不起作用,另一种方法是将 C++ 文件构建到 DLL 中,您可以使用系统动态加载程序让 GHCi 加载它,从而避免整个问题。在 Linux 这看起来像

g++ wrapper.cpp clipper.cpp -shared -fPIC -o libclipper.so
ghci -L. -lclipper

尽管我认为 Windows 上的细节有所不同。