44

我们一般都在大量使用boost::serialization和模板。一切似乎进展顺利。

除了,我们在 Windows 版本上遇到了障碍。它似乎导致目标文件太大的问题。我们将 MinGW/Msys 与 g++ 4.7.0 一起使用。

c:/mingw/bin/../lib/gcc/mingw32/4.7.0/../../../../mingw32/bin/as.exe: CMakeFiles/source.dir/sourcecode.cpp.obj: too many sections (33396)
C:\Users\username\AppData\Local\Temp\ccnAocvD.s: Assembler messages:
C:\Users\username\AppData\Local\Temp\ccnAocvD.s: Fatal error: can't write CMakeFiles/source.dir/sourcecode.cpp.obj: File too big

谷歌大师透露了这条存档消息,http://sourceforge.net/mailarchive/forum.php ?thread_name=CA%2Bsc5mkLvj%3DW9w2%3DsY%3Dc_N%3DEwnsQuPDEX%3DiBcbsbxS3CuE_5Bg%40mail.gmail.com&forum_name=mingw-users

在其中,它表明另一个人遇到了几乎相同的障碍。它确实指向了 Visual Studio 选项的一个选项,该/bigobj选项似乎可以满足我们的需要。但是,我们无法迁移到 Visual Studio。

一个建议是将 --hash-size 添加到汇编器选项中。这没有帮助。

如果我没记错的话,问题在于目标文件中的条目限制为 2^16 个。实际上,根据错误消息,我敢说这是一个签名的 2^16 条目,但那是花生。Visual Studio的/bigobj选项会将其更改为 2^32。邮件列表结果不知道 GCC 的等效选项。进一步的谷歌结果似乎与此无关。

在这一点上,我们将不得不重构我们的代码(呃)来绕过这个限制。但我仍然担心,由于模板繁重,我们可能会一次又一次地遇到这个问题(我们已经用三个源文件遇到过这个问题)。

所以我的问题是这样的;是否有与微软/bigobj选项等效的 GCC?我还没有找到第三种选择吗?

4

5 回答 5

52

-Wa,-mbig-obj如果您的 GCC 版本支持该选项,则解决方案是添加该选项。您可能只在编译步骤中需要它,而不是链接器步骤。

如果您的编译器不支持该选项,您应该考虑使用 mingw-w64 和MSYS2

于 2015-08-09T19:12:10.123 回答
10

错误"%B: too many sections (%d)"来自coff_compute_section_file_positions()位于 中的函数bfd/coffcode.h。它是在输出.obj文件(COFF 格式)包含超过 32766 个部分时生成的。没有办法避免这个错误,至少如果你想使用 Windows 的 PE/COFF 对象格式则不能;COFF 文件仅使用两个字节作为文件头中的“NumberOfSections”。

我不清楚为什么as(GNU 汇编程序)将节数限制为 32768-minus-2,而不是 65536-minus-1(保留第 0 节);但无论哪种方式,如果您大量使用模板并且您的编译器通过 COMDAT 部分实现模板,这可能还不够。

正如您已经注意到的那样,传递/bigobj给 Microsoft 的编译器会导致它输出具有多达 2 个31节的 munged COFF 格式,“这对任何人来说都应该足够了”。但是,munged 格式没有正式记录,而且我没有看到任何关于该主题的非正式文档(博客文章或你有什么),所以在拥有 MSVC 副本的人可以为 编写规范之前/bigobj,它没有进入 GNU 工具的机会不大。

恕我直言,如果您尝试构建 Windows,则应该硬着头皮使用 MSVC。除了微软之外,没有人特别愿意浪费时间与 PE/COFF 格式搏斗。

于 2013-10-13T04:49:03.440 回答
4

当我用 MinGW-w64 编译 Poco 库时,我遇到了同样的问题,结果发现调试对象对于一个实现文件来说是巨大的。

正如您之前提到的,您可以拆分 cpp 文件并且它会起作用,但是当您面对某人的源代码时,您无法在不破坏某些内容的情况下做到这一点。

作为一种解决方案,您可以打开编译器优化:从 -O1 到 -O3 开始,每一步它都会构建更小的目标文件,它可能会解决问题,在我的例子中是这样。是的,对于调试版本,它可能是不可取的,您也可以尝试 -Og

于 2014-01-28T19:30:40.580 回答
4

我在这件事上发现了一些更新,它似乎已在 x64 窗口的新 binutils 中得到修复,请参阅https://sourceware.org/ml/binutils/2014-03/msg00114.htmlhttp://sourceforge.net/p /mingw-w64/bugs/341/。但是,我没有对其进行测试,因为此修复不适用于我需要的 32 位版本。

于 2015-02-06T18:45:39.663 回答
0

正如一些人已经指出的那样,如果在 之后引发错误Fatal error: can't close xxx.obj: file too big,那么-Wa,-mbig-obj将不起作用。

一种解决方法是通过添加(根据此链接的最小代码大小,但另一个选项也可能有效)来重新编译有问题的行(执行 amake VERBOSE=1来找到它)。-Os-O

总之 :

C:/msys64/mingw64/bin/c++.exe [...] -Wa,-mbig-obj -c D:/Dev/a_installer/llvm-project/llvm/lib/Passes/PassBuilder.cpp # -> file too big error
C:/msys64/mingw64/bin/c++.exe -Os [...] -Wa,-mbig-obj -c D:/Dev/a_installer/llvm-project/llvm/lib/Passes/PassBuilder.cpp # -> compilation ok

或者,如果您不确定优化不会改变代码的行为,您可以在 CMake 中为所有文件全局设置标志。

于 2021-03-12T09:59:01.453 回答