Il file object ha troppe sezioni

Stiamo facendo un uso intensivo di boost :: serialization e templates in generale. Tutto sembra andare bene.

Tranne, abbiamo avuto un problema con le nostre build di Windows. Sembra che i problemi nei file object siano troppo grandi. Stiamo usando MinGW / Msys con 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 ha rivelato questo messaggio archiviato, 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 esso, indica che un’altra persona colpisce più o meno lo stesso intoppo. /bigobj un’opzione per l’opzione /bigobj Visual Studio che sembra fare ciò di cui avremmo bisogno. Tuttavia, non siamo in grado di passare a Visual Studio.

Un suggerimento è stato quello di aggiungere –hash-size alle opzioni di assembler. Questo non ha aiutato.

Se non sbaglio, il problema sta nel fatto che i file object hanno un limite di 2 ^ 16 voci al loro interno. In realtà, secondo il messaggio di errore, mi azzarderei a dire che si tratta di una firma 2 ^ 16 voci, ma questa è noccioline. L’opzione /bigobj per Visual Studio cambierebbe quella in 2 ^ 32. Il risultato della mailing list non sapeva di un’opzione equivalente per gcc. Ulteriori risultati di google non sembrano essere rilevanti per questo.

A questo punto dovremo rifattorizzare il nostro codice (ugh) per ovviare a questa limitazione. Ma sono ancora preoccupato del fatto che, con pesanti modelli, potremmo incorrere nel problema più e più volte (ci siamo già imbattuti in esso con tre file sorgente).

Quindi la mia domanda è così; c’è un equivalente di gcc all’opzione di Microsoft /bigobj ? C’è una terza opzione che non sono ancora stata trovata?

La soluzione è aggiungere l’opzione -Wa,-mbig-obj se la tua versione di GCC supporta -Wa,-mbig-obj . Probabilmente ne hai solo bisogno durante la fase di compilazione, non il passaggio del linker.

Se il tuo compilatore non supporta questa opzione, dovresti esaminare l’utilizzo di mingw-w64 e MSYS2 .

L’errore "%B: too many sections (%d)" deriva dalla funzione coff_compute_section_file_positions() trova in bfd/coffcode.h . Viene prodotto quando il file .obj output (in formato COFF) contiene più di 32766 sezioni. Non c’è modo di evitare questo errore, almeno non se si desidera utilizzare il formato object PE / COFF di Windows; I file COFF utilizzano solo due byte per “NumberOfSections” nell’intestazione del file.

Non mi è chiaro perché as (l’assemblatore GNU) limita il numero di sezioni a 32768-minus-2, invece di 65536-minus-1 (la sezione 0 è riservata); ma in entrambi i casi, ciò potrebbe non essere sufficiente se stai facendo un uso massiccio dei modelli e il tuo compilatore implementa i modelli tramite le sezioni COMDAT.

Come hai già notato, passare /bigobj al compilatore di Microsoft fa sì che generi un formato COFF munged con un massimo di 2 31 sezioni, il che “dovrebbe essere sufficiente per chiunque”. Tuttavia, il formato mungito è formalmente non documentato, e non vedo alcuna documentazione informale (post di blog o what-have-you) sull’argomento, quindi finché qualcuno con una copia di MSVC può scrivere una specifica per /bigobj , non ha molte possibilità di entrare negli strumenti GNU.

IMHO, se stai provando a creare una build di Windows, dovresti solo morderlo e usare MSVC. Nessuno oltre a Microsoft è particolarmente motivato a perdere tempo a lottare con il formato PE / COFF.

Ho trovato alcuni aggiornamenti in questa materia, sembra essere stato corretto in nuovi binutils per x64 windows, vedere https://sourceware.org/ml/binutils/2014-03/msg00114.html e http://sourceforge.net/p / mingw-w64 / bugs / 341 / . Tuttavia, non l’ho testato poiché questa correzione non si applica alle versioni a 32 bit di cui ho bisogno.

Ho affrontato lo stesso problema quando ho compilato la libreria Poco con MinGW-w64, si è scoperto che l’object di debug era enorme per un file di implementazione.

Come hai detto prima puoi dividere i file cpp e funzionerà, ma quando affronti il ​​codice sorgente di qualcuno non puoi farlo senza rompere qualcosa.

Come soluzione è ansible triggersre le ottimizzazioni del compilatore: iniziare con -O1 fino a -O3, con ogni passo si costruirà un file object più piccolo, potrebbe risolvere il problema, lo ha fatto nel mio caso. Sì, per le build di debug potrebbe essere indesiderabile, puoi anche provare -Og