2013-05-16 2 views
27

Мы активно используем boost :: serialization и templates в целом. Кажется, все идет хорошо.В объектном файле слишком много разделов

Кроме того, мы нанесли удар по нашим сборкам 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 

Мастер Google показал эту архивную сообщение, 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 записей, но это арахис. Опция /bigobj для Visual Studio изменила бы это на 2^32. Результат списка рассылки не знал об эквивалентной опции для gcc. Дальнейшие результаты Google, похоже, не имеют отношения к этому.

На этом этапе нам придется реорганизовать наш код (ugh), чтобы обойти это ограничение. Но я по-прежнему обеспокоен тем, что с тяжелыми шаблонами мы снова и снова сталкиваемся с проблемой (мы уже сталкиваемся с ней с тремя исходными файлами).

Так что мой вопрос таков; есть ли gcc эквивалент опции /bigobj от Microsoft? Есть третий вариант, который я еще не нашел?

+0

Может быть, изменить gcc? – Yakk

+3

Лично я бы с удовольствием. Мне нужно будет изучить формат файлов объектов, которые в настоящее время используются. Я должен придумать новый формат. Звучит как отличный личный проект. К сожалению, мой работодатель не хочет такой ответственности. :) – inetknght

+0

Другая возможность заключается в том, что объектный файл нарушил барьер на 2 ГБ или что-то подобное. Насколько вы уверены, что это количество экспортированных символов? Некоторые googling указывают, что gcc не имеет жесткого барьера при 2^16 ... Вы посмотрели на http://mingw-w64.sourceforge.net/? – Yakk

ответ

8

Ошибка "%B: too many sections (%d)" происходит от функции coff_compute_section_file_positions(), расположенной в bfd/coffcode.h. Он создается, когда выходной файл .obj (в формате COFF) содержит более 32766 разделов. Невозможно избежать этой ошибки, по крайней мере, если вы не хотите использовать формат объекта Windows PE/COFF; Файлы COFF используют только два байта для «NumberOfSections» в заголовке файла.

Непонятно, почему as (сборщик GNU) ограничивает количество секций при 32768-минус-2 вместо 65536-минус-1 (раздел 0 зарезервирован); но в любом случае этого может быть недостаточно, если вы сильно используете шаблоны и, ваш компилятор реализует шаблоны через разделы COMDAT.

Как вы уже заметили, проходя /bigobj к компилятору Microsoft, приводит к его выходу в потеряется формат COFF с до 2 разделов, которые «должно быть достаточно для всех.» Тем не менее, формат munged формально недокументирован, и я не вижу никакой неофициальной документации (сообщений в блогах или того, что у вас есть) по этому вопросу, поэтому пока кто-то с копией MSVC не сможет написать спецификацию для /bigobj, это не так У меня много шансов попасть в инструменты GNU.

IMHO, если вы пытаетесь сделать сборку Windows, вам нужно просто укусить пулю и использовать MSVC. Никто кроме Microsoft не имеет особого желания тратить время на борьбу с форматом PE/COFF.

+0

Полезная информация здесь! Действительно, мы активно используем шаблоны. Я не уверен, какие разделы COMDAT есть, но мы используем gcc на mingw32. Я согласен, что мы должны использовать MSVC, но, к сожалению, управления нет. Они являются подписчиками на идею «одного репозитория кода, одного компилятора, нескольких платформ». Таким образом, вопрос о жизнеспособном решении все еще существует. Как бы то ни было, наше обходное решение состояло в том, чтобы разделить наши файлы CPP на несколько файлов, чтобы представить отдельные единицы компиляции. Но это не так идеально, как я уверен, вы можете себе представить. – inetknght

3

Я столкнулся с той же проблемой, когда я скомпилировал библиотеку Poco с помощью MinGW-w64, оказалось, что объект отладки был огромным для одного файла реализации.

Как вы, mentioned before, вы можете разделить файлы cpp, и это будет работать, но когда вы сталкиваетесь с чьим-то исходным кодом, вы не можете этого сделать, не нарушая что-то.

В качестве решения вы можете включить оптимизацию компилятора: начиная с -O1 до -O3, с каждым шагом он будет создавать меньший объектный файл, он может решить проблему, это было в моем случае. Да, для отладки строит это может быть нежелательным, you can try -Og а

+1

'' '-O3''' сделал трюк для меня. Благодаря! – ManuelAtWork

4

Я нашел некоторые обновления в этом вопросе, кажется, должны быть зафиксированы в новом Binutils для 64 окон, см https://sourceware.org/ml/binutils/2014-03/msg00114.html и http://sourceforge.net/p/mingw-w64/bugs/341/. Однако я не тестировал его, поскольку это исправление не относится к 32-битным версиям, которые мне нужны.

+0

Спасибо за обновление hte. Я не использовал mingw64, только mingw (например, 32-разрядный), потому что мне также пришлось скомпилировать 32-разрядную версию, поэтому я хотел убедиться, что 64-разрядные файлы даже случайно не были скомпилированы. – inetknght

+1

@inetknght: проект MinGW-w64 предоставляет 32-битные и 64-разрядные компиляторы. Проект назван так, потому что исходный проект MinGW предоставил только 32-битные компиляторы, а цель MinGW-w64 заключалась в создании 64-битных компиляторов. –

+2

Я тестировал этот новый вариант с MinGW-w64, и он работает. Вам нужно передать '-Wa, -mbig-obj' в' gcc' для выбора больших объектов ('-Wa' означает * передать эту опцию ассемблеру *). –

31

Решение состоит в том, чтобы добавить опцию -Wa,-mbig-obj, если ваша версия GCC поддерживает эту опцию. Вероятно, вам это нужно только на этапе компиляции, а не на этапе компоновщика.

Если ваш компилятор не поддерживает этот параметр, вы должны изучить использование mingw-w64 и MSYS2.

+0

Спасибо, это было лучшее решение для моей среды. – FabienRohrer

Смежные вопросы