c++ - cabal 使用不同版本的 gcc 编译程序时未定义的 strnlen 函数 (wxWidgets)

标签 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)。现在,cabal/Haskell 版本的 gcc 在一个简单的程序上生成如下编译错误:

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

但是用TDM-GCC的gcc编译时(或者在mingw32-gcc编译的wxWidgets上使用Haskell的gcc时编译是OK的)。所以问题是 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

我四处搜索,有些人建议添加 #include <cstring>; .我将其添加到 wxcrt.h 的开头,但这并没有解决问题。

如果我使用来自 mingw.org 的 mingw32 编译 wxWidgets 3.0,realgcc 4.5.2 就不会发生同样的编译错误。 (但我通过该路径遇到了 DLL 访问冲突错误)。

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

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

我使用 TDM-gcc 因为 TDM-GCC 二进制文件是由 wxWidgets 维护者提供的二进制文件,我认为这更有可能成功。我试过 cabal build wx 使用 MinGW-w64 gcc 并得到关于 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-

最佳答案

我无法说明您为什么会收到错误,但我可以告诉您如何更改 Cabal 和 GHC 使用的 C 编译器。实际上是 GHC 调用了 C 编译器,并在 this section of the user manual 中查找,我们发现:

-pgmc cmd Use cmd as the C compiler.

这就是您告诉 GHC 使用特定 C 编译器的方式。现在的问题是如何让 Cabal 告诉 GHC 使用那个 C 编译器。还好,Cabal's user manual goes into that, too :

--<em>prog</em>-options=<em>options</em> Specify additional options to the program prog. Any program known to Cabal can be used in place of prog. [ed: that means GHC, too!] […]
--<em>prog</em>-option=<em>option</em> […]

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

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

如果你喜欢 cabal installconfigure/build ,很高兴,因为它适用于 install , 也。如果您发现自己经常这样做,您可以考虑编辑您的 .cabal/config文件以更改默认值以使用您首选的 C 编译器。

关于c++ - cabal 使用不同版本的 gcc 编译程序时未定义的 strnlen 函数 (wxWidgets),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22418439/

相关文章:

c++ - wxWidgets 在关闭应用程序时崩溃

haskell - 无法让 w Haskell 在 Mac 上从 ghc 工作

c++ - 同时检查指针或引用类型的 C++ dynamic_cast 的设计考虑

c# - 在 C++ DLL 中包含 Lua 使其与 C# 不兼容?

haskell - 是否可以使用您自己的数据类型模拟函数?

haskell - 了解 `sequence_`

c++ - wxWidgets 中的可切换菜单栏(何时隐藏?)

c++ - 调整窗口大小时游戏崩溃 (Directx9)

c++ - 使用搅拌器处理图像 - OpenCV

xml - 从 xml-conduit 获取所有名称