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

Я разрабатывал апплет Java, в котором все записано в Clojure кроме кода апплета, который написан в Java. Апплет вызывает обратные вызовы кода Clojure init, краски, и т.д. от рычагов Java для тех методов, которые определяются моделью апплета. Таким образом, код заканчивает тем, что был Clojure на 99,999 процентов, и Вы не должны думать о крошечной части Java вообще по большей части.

существуют некоторые недостатки к этому подходу, который я надеюсь обсудить более подробно на Clojure Google Group. Я думаю, что разработчики Clojure должны включать собственный способ создать приложения. В настоящее время можно сделать, любой GUI наполняет Вас как от REPL, но если Вы хотите поставляемое приложение GUI, необходимо записать некоторый Java для вызова кода Clojure. Кроме того, это походит на архитектуру вида Апплета Java сил Вы за пределами большего количества идиоматических лучших практик Clojure, требуя, чтобы Вы использовали изменяемое состояние, и т.д.

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

14
задан Rob Kam 13 November 2009 в 09:54
поделиться

10 ответов

Don't follow its suggestions, but for amusement sake, read this 'story' about making the smallest possible ELF binary.

37
ответ дан 1 December 2019 в 05:48
поделиться

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

  • Не делай этого. Вы просто зря теряете время.
  • Используйте флаг -s для удаления символов (gcc -s)
21
ответ дан 1 December 2019 в 05:48
поделиться

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

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

11
ответ дан 1 December 2019 в 05:48
поделиться

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

И они сказали, что Modula-3 никуда не денется из-за 200-килобайтного двоичного файла hello world!


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

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

11
ответ дан 1 December 2019 в 05:48
поделиться

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

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

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

2
ответ дан 1 December 2019 в 05:48
поделиться

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

Что ж, в Windows любой исполняемый файл все равно будет иметь размер, хотя он может быть достаточно маленьким. В старой системе MS-DOS полное бездействующее приложение занимало бы всего пару байтов. (Я думаю, четыре байта, чтобы использовать 21-часовое прерывание для закрытия программы.) И снова это приложение было загружено прямо в память. Когда формат EXE стал более популярным, все немного изменилось. Теперь у исполняемых файлов была дополнительная информация о самом процессе, такая как перемещение сегментов кода и данных, а также некоторые контрольные суммы и информация о версии. The introduction of Windows added another header to the format, to tell MS-DOS that it couldn't execute the executable since it needed to run under Windows. And Windows would recognize it without problems. Of course, the executable format was also extended with resource information, like bitmaps, icons and dialog forms and much, much more.

A do-nothing executable would nowadays be between 4 and 8 kilobytes in size, depending on your compiler and every method you've used to reduce it's size. It would be at a size where UPX would actually result in bigger executables! Additional bytes in your executable might be added because you added certain libraries to your code. Especially libraries with initialized data or resources will add a considerable amount of bytes. Adding debug information also increases the size of the executable.

But while this all makes a nice exercise at reducing size, you could wonder if it's practical to just continue to worry about bloatedness of applications. Modern hard disks will divide files up in segments and for really large disks, the difference would be very small. However, the amount of trouble it would take to keep the size as small as possible will slow down development speed, unless you're an expert developer whom is used to these optimizations. These kinds of optimizations don't tend to improve performance and considering the average disk space of most systems, I don't see why it would be practical. (Still, I do optimize my own code in similar ways but then again, I am experienced with these optimizations.)


Interested in the EXE header? It's starts with the letters MZ, for "Mark Zbikowski". The first part is the old-style MS-DOS header for executables and is used as a stub to MS-DOS saying the program is not an MS-DOS executable. (In the binary, you can find the text 'This program cannot be run in DOS mode.' which is basically all it does: displaying that message. Next is the PE header, which Windows will recognise and use instead of the MS-DOS header. It starts with the letters PE for Portable Executable. After this second header there will be the executable itself, divided in several blocks of code and data. The header contains special reallocation tables which tells the OS where to load a specific block. And if you can keep this to a limit, the final executable can be smaller than 4 KB, but 90% would then be header information and no functionality.
7
ответ дан 1 December 2019 в 05:48
поделиться

I like the way the DJGPP FAQ addressed this many many years ago:

In general, judging code sizes by looking at the size of "Hello" programs is meaningless, because such programs consist mostly of the startup code. ... Most of the power of all these features goes wasted in "Hello" programs. There is no point in running all that code just to print a 15-byte string and exit.

3
ответ дан 1 December 2019 в 05:48
поделиться

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

2
ответ дан 1 December 2019 в 05:48
поделиться

Выполните полосу на двоичном файле, чтобы избавиться от символов. В gcc версии 3.4.4 (специальная cygming) я упал с 10k до 4K.

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

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

1
ответ дан 1 December 2019 в 05:48
поделиться

Using GCC, compile your program using -Os rather than one of the other optimization flags (-O2 or -O3). This tells it to optimize for size rather than speed. Incidentally, it can sometimes make programs run faster than the speed optimizations would have, if some critical segment happens to fit more nicely. On the other hand, -O3 can actually induce code-size increases.

There might also be some linker flags telling it to leave out unused code from the final binary.

0
ответ дан 1 December 2019 в 05:48
поделиться