【问题标题】:GCC equivalent of MS's /bigobjGCC 相当于 MS 的 /bigobj
【发布时间】:2013-05-16 20:28:47
【问题描述】:

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

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

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 的等效选项。进一步的谷歌搜索结果似乎与此无关。

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

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

【问题讨论】:

  • 就个人而言,我很乐意。我必须了解当前正在使用的目标文件的格式。我必须想出一个新的格式。听起来像是一个很棒的个人项目。不幸的是,我的雇主不想承担这种责任。 :)
  • 另一种可能性是目标文件打破了 2 GB 的障碍或类似的情况。您对导出符号的数量有多大把握?一些谷歌搜索表明 gcc 在 2^16 处没有硬障碍......你看过mingw-w64.sourceforge.net 吗?
  • @Yakk,在 g++ 运行汇编程序时巧妙地使用 ProcessMonitor 表明中间汇编程序文件(错误消息中的 ccnAocvD.s)大小约为 60MiB。然后它去创建目标文件(大概是为了确保它可以打开它)。几秒钟后,它退出并且错误消息显示在控制台上。我假设几秒钟是处理程序集文件并确定符号过多所需的时间。邮件列表中提到了 2GiB 屏障。我想确定那不是罪魁祸首。
  • @inetkght 如果您看这里,我们有人在测试 gcc 以查看它是否对该值有硬限制:gcc.gnu.org/ml/gcc-patches/2007-05/msg02104.html - 但那是在 07 年。您可能会考虑弄清楚如何使用当前编译器运行这些测试,这可能会找出问题所在。
  • 这看起来可能会很有趣。谢谢!

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


【解决方案1】:

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

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

【讨论】:

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

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

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

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

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

【讨论】:

  • 这里有很好的信息!事实上,我们大量使用模板。我不确定 COMDAT 部分是什么,但我们在 mingw32 上使用 gcc。我同意我们应该使用 MSVC,但不幸的是管理层没有。他们是“一个代码库、一个编译器、多个平台”理念的订阅者。因此,可行的解决方案的问题仍然存在。照原样,我们的解决方法是将 CPP 文件拆分为多个文件以呈现单独的编译单元。但这并不理想,我相信您可以想象。
【解决方案3】:

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

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 感谢您的更新。我没有使用 mingw64,只使用了 mingw(例如 32 位),因为我还必须针对 32 位进行编译,所以想确保不会意外编译 64 位的东西。
    • @inetknght:MinGW-w64 项目提供 32 位和 64 位编译器。项目之所以这样命名,是因为最初的 MinGW 项目只提供了 32 位编译器,而 MinGW-w64 的目标是生产 64 位编译器。
    • 我已经用 MinGW-w64 测试了这个新选项,它可以工作。您需要将-Wa,-mbig-obj 传递给gcc 以选择加入大对象(-Wa 表示将此选项传递给汇编程序)。
    【解决方案5】:

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

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

    总结:

    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 中为所有文件全局设置标志。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-02
      • 2010-10-24
      • 2018-07-12
      • 2016-04-13
      • 1970-01-01
      • 2010-12-05
      相关资源
      最近更新 更多