We am 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?
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.
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.
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.
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