对象文件包含太多部分

时间:2013-05-16 20:28:48

标签: c++ visual-studio boost g++ mingw

我们正在大量使用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?我还没有找到第三个选项吗?

5 个答案:

答案 0 :(得分:38)

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

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

答案 1 :(得分: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副本的人可以写出{{1}的规范进入GNU工具的机会并不大。

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

答案 2 :(得分:4)

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

答案 3 :(得分:3)

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

当你mentioned before你可以拆分cpp文件并且它可以工作,但是当你面对某人的源代码时,如果不破坏某些东西就不能这样做。

作为一个解决方案,你可以启用编译器优化:从-O1开始到-O3,每一步它将构建更小的目标文件,它可以解决问题,它在我的情况下。是的,对于调试版本,它可能是不受欢迎的,you can try -Og以及

答案 4 :(得分:0)

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

解决方法是通过添加 make VERBOSE=1(根据 this link 的最小代码大小,但另一个 -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 中为所有文件全局设置标志。