GCC: пустая программа == 23202 байта?

test.c:

int main()
{
    return 0;
}

Я не использовал никаких флагов (я новичок в gcc), просто команда:

gcc test.c

Я использовал последнюю TDM-сборку GCC на win32. Итоговый исполняемый файл почти 23KB, слишком большой для пустой программы.

Как уменьшить размер исполняемого файла?

Ответы

Ответ 1

Не следуйте его рекомендациям, но ради удовольствия, прочитайте эту "историю" о создании минимально возможного двоичного файла ELF.

Ответ 2

Как уменьшить размер?

  • Не делай этого. Вы просто теряете время.
  • Использовать флаг -s для разделения символов (gcc -s)

Ответ 3

Откажитесь. В x86 Linux gcc 4.3.2 создает двоичный файл 5K. Но ждать! Это с динамической связью! Статически связанная двоичная система составляет более половины мегабайта: 516K. Расслабьтесь и научитесь жить с наворотом.

И они сказали, что Modula-3 никогда не пойдет куда-либо из-за 200K привет мир бинарных!


Если вам интересно, что происходит, библиотека Gnu C структурирована таким образом, чтобы включать определенные функции, зависит ли ваша программа от них или нет. Эти функции включают в себя такие мелочи, как malloc и free, dlopen, некоторую строчную обработку и всю загрузку вещей, которые, как представляется, связаны с локалями и интернационализацией, хотя я не могу найти соответствующие справочные страницы.

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

Ответ 4

По умолчанию некоторые стандартные библиотеки (например, C runtime) связаны с вашим исполняемым файлом. Подробнее см. Ключи --nostdlib --nostartfiles --nodefaultlib. Параметры ссылок описаны здесь.

Для реальной программы второй вариант - попробовать параметры оптимизации, например. -O (оптимизируйте размер).

Ответ 5

Собственно, если ваш код ничего не делает, разве даже справедливо, что компилятор все еще создает исполняемый файл?; -)

Ну, в Windows любой исполняемый файл все равно будет иметь размер, хотя он может быть разумным. Со старой системой MS-DOS полное приложение do-nothing будет всего лишь пару байтов. (Я думаю, что четыре байта используют 21-часовое прерывание для закрытия программы.) Затем снова приложение было загружено прямо в память. Когда формат EXE стал более популярным, все немного изменилось. Теперь исполняемые файлы имели дополнительную информацию о самом процессе, таком как перемещение сегментов кода и данных, а также некоторые контрольные суммы и информация о версии. Введение Windows добавило еще один заголовок в формат, чтобы сообщить MS-DOS, что он не может выполнить исполняемый файл, поскольку он должен запускаться под Windows. И Windows распознает его без проблем. Конечно, исполняемый формат также был расширен информацией о ресурсах, например растровыми изображениями, значками и диалоговыми формами и многое, многое другое.

Исполняемый файл do-nothing теперь будет от 4 до 8 килобайт в зависимости от вашего компилятора и каждого метода, который вы использовали для уменьшения его размера. Он будет иметь размер, где UPX фактически приведет к большим исполняемым файлам! Дополнительные байты в вашем исполняемом файле могут быть добавлены, потому что вы добавили определенные библиотеки в свой код. Особенно библиотеки с инициализированными данными или ресурсами будут добавлять значительное количество байтов. Добавление отладочной информации также увеличивает размер исполняемого файла.

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


Интересует EXE-заголовок? Он начинается с букв MZ, для" Mark Zbikowski ". Первая часть - это заголовок MS-DOS старого стиля для исполняемых файлов и используется как заглушка для MS-DOS, говорящая, что программа не является исполняемым MS-DOS. (В двоичном формате вы можете найти текст" Эта программа не может быть запущена в режиме DOS ", что в основном это все: отображение этого сообщения. Следующий заголовок PE, который Windows будет распознавать и использовать вместо MS-DOS заголовок начинается с букв PE для Portable Executable. После этого второго заголовка будет сам исполняемый файл, разделенный на несколько блоков кода и В заголовке содержатся специальные таблицы перераспределения, которые сообщают ОС, где загружать определенный блок. И если вы можете ограничить это, окончательный исполняемый файл может быть меньше 4 КБ, но тогда 90% будет заголовкой и никакой функциональностью.

Ответ 6

Мне нравится, как часто задавали вопросы о DJGPP много лет назад:

В целом, оценка размеров кода при просмотре размеров программ "Hello" бессмысленна, поскольку такие программы состоят в основном из кода запуска.... Большая часть всех этих функций пропадает в программах "Hello". Нет смысла запускать весь этот код только для печати 15-байтовой строки и выхода.

Ответ 7

Какова цель этого упражнения?

Даже при таком низком уровне языка, как C, все еще существует множество настроек, которые должны произойти до того, как можно будет вызвать main. Некоторые из этих настроек обрабатываются загрузчиком (который нуждается в определенной информации), некоторые обрабатываются кодом, который вызывает main. И тогда, вероятно, будет немного кода библиотеки, который должен иметь любая нормальная программа. По крайней мере, возможно, ссылки на стандартные библиотеки, если они находятся в DLL.

Изучение двоичного размера пустой программы - бесполезное упражнение само по себе. Это ничего не говорит. Если вы хотите узнать что-то о размере кода, попробуйте написать непустые (и, желательно, нетривиальные) программы. Сравните программы, которые используют стандартные библиотеки с программами, которые делают все сами.

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

Ответ 8

Что означает "size a.out" о размере сегментов кода, данных и bss? Большая часть кода, вероятно, будет стартовым кодом (классически crt0.o на машинах Unix), который вызывается o/s и настраивает работу (например, сортировку аргументов командной строки в argc, argv) перед вызовом main().

Ответ 9

Запустите полосу в двоичном коде, чтобы избавиться от символов. С gcc версии 3.4.4 (cygming special) я падаю от 10k до 4K.

Вы можете попробовать связать пользовательское время выполнения (часть, которая вызывает main), чтобы настроить среду выполнения. Все программы используют одну и ту же настройку среды выполнения, которая поставляется с gcc, но для исполняемого файла вам не нужны данные или нулевая память. Средства, которые вы могли бы избавиться от неиспользуемых функций библиотеки, таких как memset/memcpy и уменьшить размер CRT0. При поиске информации об этом взгляде на GCC во встроенной среде. Встроенные разработчики - это общие пользователи, которые используют собственные среды выполнения.

Остальные - это накладные расходы для ОС, которая загружает исполняемый файл. Вы не собираетесь туда же, если вы не настроите это вручную?

Ответ 10

Используя GCC, скомпилируйте свою программу, используя -Os, а не один из других флагов оптимизации (-O2 или -O3). Это говорит о том, что он оптимизирует размер, а не скорость. Кстати, иногда программы могут запускаться быстрее, чем оптимизация скорости, если какой-то критический сегмент будет лучше соответствовать друг другу. С другой стороны, -O3 может фактически увеличить размер кода.

Также могут быть некоторые флагов компоновщика, говорящие, что он должен оставить неиспользуемый код из окончательного двоичного файла.