【问题标题】:undefined strnlen function (wxWidgets) when a program is compiled using a different version of gcc by cabalcabal 使用不同版本的 gcc 编译程序时未定义的 strnlen 函数 (wxWidgets)
【发布时间】:2014-04-20 12:54:07
【问题描述】:

这是我的情况,我使用 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 时)编译是可以的。所以问题是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 &lt;cstring&gt;;。我把它加到wxcrt.h的开头,并没有解决问题。

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

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

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

我使用 TDM-gcc 是因为 TDM-GCC 二进制文件是 wxWidgets 维护者提供的二进制文件,我认为这更有可能成功。我尝试使用 MinGW-w64 gcc cabal build wx 并在编译期间得到关于 cc1plus.exe 的运行时异常。算上前面提到的关于 mingw32 的运行时问题,我认为使用 TDM-GCC 可能是最好的选择。

-- 更新--

@icktoofay

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

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

$ 阴谋集团建造 构建 wxc c:\HaskellPlatform\2013.2.0.0\mingw\bin\gcc.exe -Wl,--hash-size=31 -Wl,--reduce-

【问题讨论】:

  • 正如我在回复您的other question 时写的,您确实需要查看config.log 以了解发生了什么。
  • @VZ 我不确定你在这篇文章中和其他关于 config.log 的文章中谈论的是什么。您的任何一个 cmets 中都没有太多信息。盲目地对有效问题进行投票,同时断言问题始终与用户有关,这在这两种情况下都是荒谬的。
  • 正如您自己所说,您一生中只使用过一次 cabal,对它的了解并不多。我不认为你为什么认为问题在于 wxWidgets 的构建方式。 @ickfootay 在这里的回答已经比您对用户的随机猜测要好得多,肯定是 wxWidgets 配置错误。正如您在另一个问题中已经看到的那样,wxWidgets 是使用标准配置命令配置的,构建 wxWidgets 没有任何问题。
  • @VZ。如果 wxWidgets 没有构建失败,那么查看 wxWidgets 的 config.log 有什么关系?
  • 非常抱歉尽管对cabal 了解不多,但仍试图帮助您,不会再发生了。特别是当您已经确定配置步骤中没有任何问题时。显然你是对的,你遇到的其他神秘问题与没有正确构建完全无关。

标签: c++ haskell wxwidgets cabal


【解决方案1】:

我无法解释您为什么会遇到错误,但我可以告诉您如何更改 Cabal 和 GHC 正在使用的 C 编译器。实际上是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

--<em>prog</em>-options=<em>options</em> 指定程序prog 的附加选项。 Cabal 知道的任何程序都可以用来代替prog。 [编辑:这也意味着 GHC!] […]
--<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 install 而不是 configure/build,请高兴,因为它也适用于 install。如果您发现自己经常这样做,您可以考虑编辑您的 .cabal/config 文件以更改默认值以使用您喜欢的 C 编译器。

【讨论】:

  • 非常感谢您的回答。我按照您的建议尝试了,但它没有更改编译器。请查看更新。我错过了什么吗?
  • @TingL:请记住,GHC 是本机运行的,而不是在 MinGW 下运行,因此您必须使用像 C:\path\to\gcc.exe 这样的 Windows 路径,而不是 /c/path/to/gcc.exe
  • 我从 Windows 命令行尝试了 c:\mingw\bin\gcc.exe(存在)以及cabal build --ghc-option=-pgmc --ghc-option=C:\mingw\bin\gcc.exe。不知何故,总是选择 Haskell 版本的 gcc。
  • 我需要在某处添加-cpp,因为该文件是cpp文件吗?
  • @TingL:我现在更多地考虑这个问题,虽然 GHC 确实为某些事情调用 C 编译器(在这种情况下这就足够了),但它会为一些其他事情调用编译器本身。看看configureCCompiler中的Distribution.Simple.Setup;您也许能够弄清楚如何改变它发现 C 编译器的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多