对象文件包含太多部分

ine*_*ght 34 c++ boost mingw g++ visual-studio

我们正在大量使用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
Run Code Online (Sandbox Code Playgroud)

谷歌大师透露了这个存档的消息,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条目,但那是花生./bigobjVisual Studio 的选项会将其更改为2 ^ 32.邮件列表结果不知道gcc的等效选项.进一步的谷歌搜索结果似乎与此无关.

在这一点上,我们将不得不重构我们的代码(呃)以克服这个限制.但是我仍然担心,经过大量模板化,我们可能会一次又一次地遇到这个问题(我们已经遇到了三个源文件).

所以我的问题是这样的; 有没有相当于微软/bigobj选项的gcc ?我还没有找到第三种选择吗?

Dav*_*son 42

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

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

  • 我要接受这个答案。我早已转向不同的项目、不同的团队、不同的雇主,而且我还没有遇到过这个问题,因为这就是为什么我之前没有接受它。然而,我注意到很多人都来投票,所以即使六年后,它显然仍然是一个活跃的问题。 (2认同)
  • 我认为 `-mbig-obj` 只能修复“太多部分”错误。如果您没有看到该错误,但确实看到“文件太大”错误,则猜测是您想要创建的文件对于您的文件系统来说太大,但我还没有对此进行过深入研究。我会检查您正在使用的文件系统(例如 NTFS、FAT32)及其限制。 (2认同)

Quu*_*one 9

错误"%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个部分的混合COFF格式,这对任何人来说都应该足够了.然而,munged格式是正式无证的,我没有看到关于这个主题的任何非正式文档(博客文章或者你有什么),所以直到有MSVC副本的人可以写出规范/bigobj,它不会很有可能进入GNU工具.

恕我直言,如果你正在尝试制作Windows版本,你应该咬紧牙关并使用MSVC.除了微软之外,没有人特别倾向于浪费时间与PE/COFF格式搏斗.


小智 5

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

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

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