Добро пожаловать, гость ( Вход | Регистрация )
![]() ![]() |
| -=CHE@TER=- |
Mar 9 2026, 19:19
Сообщение
#1
|
|
Walter Sullivan ![]() ![]() ![]() Группа: Root Admin Сообщений: 1,428 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 327 раз(а) |
Решил написать о том, как собираю программы на сайте в бинарники. На случай, если кому-то понадобится или кто-нибудь решит повторить.
Какие будут отличия от того, что выложено на сайте: 1. В .EXE файле точно будут отличия: это время сборки файла (в заголовках PE, импорта и ещё пары секций). 2. Если компилировалось со старой версией GCC32HACK, то тоже будут различия (в старой версии тупо код подключался перед исполняемым файлом). 3. В старых версиях отсутствует флаг IMAGE_FILE_32BIT_MACHINE в PE заголовке (см. ниже). 4. В паре редких исключений (типа GUI приложений) программы могут компилироваться вручную с использованием строк для компиляции ниже с некоторыми изменениями (типа добавления ключа "-mwindows" для GUI приложения). Для компиляции я использую GCC 3.2 (mingw special 20020817-1) из Bloodshed Dev-C++ 5 beta release 8 (4.9.8.0). Скачать можно здесь: Home / Binaries / Dev-C++ 4.9.8.0 - нужен файл, который называется "devcpp4980.exe" (больший по размеру, 12 мегабайт). Скачиваем, устанавливаем, применяем хак для правильной генерации PE заголовка - добавляем флаг IMAGE_FILE_32BIT_MACHINE: C:\Dev-Cpp\mingw32\bin\ld.exe 00044391: 00 -> 01 Подробнее тут: Software patches. Теперь обычная компиляция у меня запускается так: QUOTE gcc -fwritable-strings -s -Os -Wall -ansi -pedantic "!.!" -o "!.exe" -l advapi32 -l ws2_32 -l winmm -l gdi32 -l psapi -l ole32 -l wininet C:\Dev-Cpp\lib\CRT_noglob.o У меня это делается через меню в FAR Manager, поэтому там "!.!" - это имя и расширение текущего файла, на котором стоит курсор."C:\Dev-Cpp\lib\CRT_noglob.o" нужно, чтобы можно было в качестве аргументов маску файлов использовать ("*.*" например) и они не разворачивались в кучу аргументов, которые будут программе передаваться (это чисто линуксовая приблуда). Получившийся .EXE файл помимо .DLL из ядра системы Windows будет использовать также "MSVCRT.DLL", которого в Windows 98 первой сборки и ранее изначально не было (ставится вместе с некоторыми программами). Релизные же программы на сайт собираются следующим образом: QUOTE gcc -Dmain=_main -fno-exceptions -fno-rtti -fwritable-strings -s -Os -Wall -ansi -pedantic -nostdlib "!.!" -o "!.exe" C:\GCCHACKS\buildlib\libsmall.a C:\Dev-Cpp\lib\gcc-lib\mingw32\3.2\libgcc.a -l kernel32 -l user32 -l advapi32 -l ws2_32 -l gdi32 -l ole32 -l shell32 -l winmm -L"C:\Dev-Cpp\lib" При такой компиляции программа будет ну очень крохотной, но при этом будет работать в любом Windows, где работают 32 битные программы и без зависимости от "MSVCRT.DLL".Содержимое каталога "GCCHACKS" тут: gcchacks.zip. После скачивания и распаковки нужно запустить "buildlib.bat". Я пытался переписать код, чтобы он был максимально компактный, поэтому срезал пару углов тут и там, с обычным кодом ANSI C эта штука в некоторых моментах несовместима (обращаю на это внимание). Поэтому сначала убеждаетесь, что код работает как надо при обычной компиляции, а потому уже с вот этой заменой. Все пути, типа C:\Dev-CPP и C:\GCCHACKS меняете на свои - они здесь для примера. Вроде бы, по GCC всё, ничего не забыл. Почему я не пользуюсь современными GCC из MinGW: 1. Добавляет много лишнего: какие-то .tls секции, .eh_frame секции, .reloc (для .EXE они не нужны), часть можно отключить, часть я сколько не гуглил, так и не нашёл как отключить. 2. Строки и константы, вместо того чтобы пихать в секцию кода где они в первый раз используются, в кои-то веки начали размещать в секции с данными, но, это дополнительно увеличивает размер из-за выравниваний. По нормальному нужно было в конец секции кода добавлять (всё равно константы). Я, собственно, для этой цели ключ -fwritable-strings и использую (в новых версиях GCC его нет) - чтобы строки в одном месте были. |
![]() ![]() |
| Упрощённая версия | Сейчас: 17th April 2026 - 07:27 |