GCC equivalent of MS's /bigobj

24,161

Solution 1

The solution is to add the option -Wa,-mbig-obj if your version of GCC supports that option. You probably only need it during the compilation step, not the linker step.

If your compiler does not support that option, you should look into using mingw-w64 and MSYS2.

Solution 2

The error "%B: too many sections (%d)" comes from the function coff_compute_section_file_positions() located in bfd/coffcode.h. It's produced when the output .obj file (in COFF format) contains more than 32766 sections. There is no way to avoid this error, at least not if you want to use Windows' PE/COFF object format; COFF files use only two bytes for "NumberOfSections" in the file header.

It's not clear to me why as (the GNU assembler) caps the number of sections at 32768-minus-2, instead of 65536-minus-1 (section 0 is reserved); but either way, that might not be enough if you're making heavy use of templates and your compiler implements templates via COMDAT sections.

As you've already noticed, passing /bigobj to Microsoft's compiler causes it to output a munged COFF format with up to 231 sections, which "should be enough for anybody." However, the munged format is formally undocumented, and I don't see any informal documentation (blog posts or what-have-you) on the subject, so until someone with a copy of MSVC can write up a specification for /bigobj, it doesn't stand much chance of getting into the GNU tools.

IMHO, if you're trying to make a Windows build, you should just bite the bullet and use MSVC. Nobody besides Microsoft is particularly motivated to waste time wrestling with the PE/COFF format.

Solution 3

I faced the same problem when I compiled Poco library with MinGW-w64, it turned out that debug object was huge for one implementation file.

As you mentioned before you can split up cpp files and it will work, but when you face with someone's source code you can't do that without breaking something.

As a solution you can turn on compiler optimisations: start with -O1 up to -O3, with each step it will build smaller object file, it may solve the problem, it did in my case. Yes, for debug builds it may be undesirable, you can try -Og as well

Solution 4

I found some updates in this matter, it seems to be fixed in new binutils for x64 windows, see https://sourceware.org/ml/binutils/2014-03/msg00114.html and http://sourceforge.net/p/mingw-w64/bugs/341/. However, I did not test it as this fix does not apply to 32 bit versions I need.

Share:
24,161

Related videos on Youtube

inetknght
Author by

inetknght

SoftwareEngineer inetknght; inetknght.title = {"C++ Software Engineer"}; [&l = inetknght.languages](){ l.emplace_back("C++"); l.emplace_back("Bash"); l.emplace_back("Xojo", alias{"REALbasic"}); l.emplace_back("C"); l.emplace_back("Ruby"); l.emplace_back("x86 assembly"); }(); [&os = inetknght.operating_systems](){ os.emplace_back("Linux"); os.emplace_back("Windows 7", deprecated); os.emplace_back("OS X 10.8", deprecated); }();

Updated on July 09, 2022

Comments

  • inetknght
    inetknght almost 2 years

    We are making heavy use of boost::serialization and templates in general. All seems to be going well.

    Except, we've hit a snag on our Windows builds. It seems to cause issues in the object files being too large. We're using MinGW/Msys with 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
    

    Master google revealed this archived message, http://sourceforge.net/mailarchive/forum.php?thread_name=CA%2Bsc5mkLvj%3DW9w2%3DsY%3Dc_N%3DEwnsQuPDEX%3DiBcbsbxS3CuE_5Bg%40mail.gmail.com&forum_name=mingw-users

    In it, it indicates that another person hit pretty much the same snag. It did point to an option for Visual Studio's /bigobj option which appears to do what we would need. However, we're unable to move to Visual Studio.

    One suggestion was to add --hash-size to the assembler options. This did not help.

    If I'm not mistaken, the issue lies in the fact that the object files have a limit of 2^16 entries in them. Actually, according to the error message, I would venture that it's a signed 2^16 entries, but that's peanuts. The /bigobj option for Visual Studio would change that to 2^32. The mailing list result did not know of an equivalent option for GCC. Further google results don't appear to be relevant to this.

    At this point we'll have to refactor our code (ugh) to get around this limitation. But I am still concerned that, with heavy templating, we could run into the issue again and again (we've already run into it with three source files).

    So my question is thus; is there a GCC equivalent to Microsoft's /bigobj option? Is there a third option that I'm not yet found?

    • inetknght
      inetknght about 11 years
      Personally, I would love to. I'd have to learn the format of the object files that's currently being used. I'd have to come up with a new format. Sounds like a great personal project. Unfortunately, my employer doesn't want that kind of responsibility. :)
    • Yakk - Adam Nevraumont
      Yakk - Adam Nevraumont about 11 years
      Another possibility is that the object file broke a 2 GB barrier or somesuch. How certain are you that it is the number of exported symbols? Some googling indicates that gcc doesn't have a hard barrier at 2^16... Did you look at mingw-w64.sourceforge.net ?
    • inetknght
      inetknght about 11 years
      @Yakk, clever use of ProcessMonitor while g++ is running the assembler reveals that the intermediary assembler file (ccnAocvD.s in the error message) is around 60MiB in size. It then goes to create the object file (assumably to ensure it can open it). A few seconds later, it exits and the error message shows up on the console. I assume the few seconds is the amount of time it takes to process the assembly file and determine that there would be too many symbols. The 2GiB barrier was mentioned in the mailing list. I wanted to be sure that wasn't the culprit.
    • Yakk - Adam Nevraumont
      Yakk - Adam Nevraumont about 11 years
      @inetkght If you look here, we have someone testing gcc to see if it has a hard limit on that value: gcc.gnu.org/ml/gcc-patches/2007-05/msg02104.html -- but that was back in '07. You might consider figuring out how to run these tests with the current compiler, which might isolate which limit is the problem.
    • inetknght
      inetknght about 11 years
      That looks like it might be fun to go through. Thanks!
    • rogerdpack
      rogerdpack over 7 years
      See also svn.boost.org/trac/boost/ticket/8786 apparently there are macros that can help reduce the size or some odd...
  • inetknght
    inetknght over 10 years
    Good info here! Indeed, we make heavy use of templates. I'm not sure what COMDAT sections are, but we use gcc on mingw32. I agree we should use MSVC but unfortunately management does not. They're subscribers to the idea of "one code repository, one compiler, multiple platforms". So the question of a viable solution still exists. As-is, our workaround has been to split up our CPP files into multiple files to present separate compilation units. But that's less than ideal, as I'm sure you can imagine.
  • inetknght
    inetknght over 9 years
    Thanks for hte update. I wasn't using mingw64, only mingw (eg, 32-bit) because I also had to compile for 32-bit so wanted to ensure no 64-bit stuff even accidentally was compiled.
  • Francis Gagné
    Francis Gagné almost 9 years
    @inetknght: The MinGW-w64 project provides 32-bit and 64-bit compilers. The project is named like this because the original MinGW project only provided 32-bit compilers, and the goal of MinGW-w64 was to produce 64-bit compilers.
  • Francis Gagné
    Francis Gagné almost 9 years
    I've tested this new option with MinGW-w64 and it works. You need to pass -Wa,-mbig-obj to gcc to opt-in to big objects (-Wa means pass this option to the assembler).
  • inetknght
    inetknght over 4 years
    I'm going to accept this answer. I have long since moved on to a different project, different team, different employer and I haven't encountered this problem since which is why I haven't accepted it prior to now. However I've noticed that a lot of people come and upvote it so it's apparently still an active issue even six years later.
  • Sergey Kolesnik
    Sergey Kolesnik over 3 years
    didn't help me with MinGW64 from MSYS2 (file too big)
  • David Grayson
    David Grayson over 3 years
    I think -mbig-obj only fixes the "too many sections" error. If you don't see that error, but you do see a "File too big" error, by guess is that the file you want to make is too big for your filesystem, but I haven't looked into this very much. I'd check what filesystem you are using (e.g. NTFS, FAT32), and what its limits are.