当使用不同版本的gcc by cabal编译程序时,未定义的strnlen函数(wxWidgets)

时间:2014-03-15 01:25:27

标签: c++ haskell wxwidgets cabal

这是我的情况,我使用TDM-GCC 4.8.1从源代码构建了wxWidgets 3.0。 然后我们使用Haskell的cabal系统构建依赖于wx的某些包(例如wxHaskell),cabal调用其内部版本的gcc来编译C ++程序,(在我的例子中, /c/HaskellPlatform/2013.2.0.0/mingw/bin/gcc)。现在,gcc的cabal / Haskell版本在一个简单的程序上生成编译错误,如下所示:

#include <wx/wx.h>
int main() {}

但是在使用TDM-GCC的gcc编译时(或者在mingw32-gcc编译的wxWidgets上使用Haskell的gcc时)编译是可以的。问题是cabal和MinGW使用不同版本的gcc,我不能用Haskell gcc替换MinGW gcc,因为它很旧(从Haskell Platform 2013.2开始的gcc 4.5.2)。此外,Haskell gcc被称为realgcc.exe,我甚至不确定它是否与任何流行的MinGW发行版兼容。

- 详情 -

使用Haskell gcc编译上述最小程序的错误信息是:

D:\work\wxHaskell-wxwidgets-3.0.0\wxc>c:\HaskellPlatform\2013.2.0.0\mingw\bin\gc
c.exe -Wl,--hash-size=31 -Wl,--reduce-memory-overheads -Isrc/include -IC:/MinGW/
msys/1.0/local/include/wx-3.0 -IC:/MinGW/msys/1.0/local/lib/wx/include/msw-unico
de-3.0 -D__WXMSW__ -DWXUSINGDLL -D_LARGEFILE_SOURCE=unknown -DwxcREFUSE_MEDIACTR
L -DBUILD_DLL -c src\cpp\apppath.cpp -o dist\build\src/cpp/apppath.o
In file included from C:/MinGW/msys/1.0/local/include/wx-3.0/wx/crt.h:19:0,
                 from C:/MinGW/msys/1.0/local/include/wx-3.0/wx/string.h:4305,
                 from C:/MinGW/msys/1.0/local/include/wx-3.0/wx/memory.h:15,
                 from C:/MinGW/msys/1.0/local/include/wx-3.0/wx/object.h:19,
                 from C:/MinGW/msys/1.0/local/include/wx-3.0/wx/wx.h:15,
                 from src/include/wrapper.h:20,
                 from src\cpp\apppath.cpp:1:
C:/MinGW/msys/1.0/local/include/wx-3.0/wx/wxcrt.h: In function 'size_t wxStrnlen
(const char*, size_t)':
C:/MinGW/msys/1.0/local/include/wx-3.0/wx/wxcrt.h:173:92: error: 'strnlen' was n
ot declared in this scope
C:/MinGW/msys/1.0/local/include/wx-3.0/wx/wxcrt.h: In function 'size_t wxStrnlen
(const wchar_t*, size_t)':
C:/MinGW/msys/1.0/local/include/wx-3.0/wx/wxcrt.h:187:95: error: 'wcsnlen' was n
ot declared in this scope

我用Google搜索,并建议添加#include <cstring>;。我将其添加到wxcrt.h的开头,并没有解决问题。

如果我使用mingw32中的mingw32编译wxWidgets 3.0,那么realgcc 4.5.2的编译错误是相同的。 (但我通过该路径遇到DLL访问冲突错误。)

我的问题是,如果源代码是使用标准MinGW32构建的,realgcc识别strnlenwcsnlen的原因,但是当使用TDM-GCC编译源代码时失败?我们如何破解realgcc / mingw32 / tdm-gcc(或其他东西)来修复此错误?

我知道混合不同版本的mingw / gcc是危险的,但普通用户在这里没有太多选择,因为像cabal这样的构建系统在没有咨询的情况下选择他们自己的编译器。另一个问题是,是否有一种安全的方法可以在不破坏阴谋的情况下更改默认的gcc程序cabal

我使用TDM-gcc,因为TDM-GCC二进制文件是wxWidgets维护者提供的二进制文件,我认为这有更好的机会成功。我尝试使用MinGW-w64 gcc cabal build wx并在编译期间获得有关cc1plus.exe的运行时异常。计算早期关于mingw32的运行时问题,与TDM-GCC一起使用可能是最好的一次,正如我想的那样。

- 更新 -

@icktoofay

这是我尝试过的,似乎没有改变gcc编译器。

$ cabal configure --ghc-option = -pgmc --ghc-option = / c / mingw / bin / gcc.exe 解决依赖关系...... 配置wxc-0.90.1.1 ... 配置wxc以针对wxWidgets 3.0进行构建

$ cabal build 建设wxc c:\ HaskellPlatform \ 2013.2.0.0 \ mingw \ bin \ gcc.exe -Wl, - hash-size = 31 -Wl, - reduce -

1 个答案:

答案 0 :(得分:1)

我不能说你为什么会得到错误,但我可以告诉你如何更改C编译器Cabal和GHC正在使用的错误。它实际上是GHC调用C编译器,并查看this section of the user manual,我们发现:

  

-pgmc cmd 使用cmd作为C编译器。

这就是你告诉GHC使用某个C编译器的方法。现在的问题是如何让Cabal告诉GHC使用那个C编译器。幸运的是,Cabal's user manual goes into that, too

  

--prog-options=options 为程序prog指定其他选项。可以使用Cabal已知的任何程序代替prog。 [编辑:那也意味着GHC!] [...]
   --prog-option=option [...]

正如文档所示,其中任何一个都可以正常工作。 (当参数有空格时,它们的行为会有所不同。)将它们放在一起,你可能能够让Cabal和GHC使用你喜欢的C编译器:

> cabal configure --ghc-option=-pgmc --ghc-option=C:\path\to\gcc.exe
> cabal build

如果您希望cabal install超过configure / build,请高兴,因为它也适用于install。如果您经常这样做,可以考虑编辑.cabal/config文件以更改默认值以使用您首选的C编译器。