Я пытаюсь выяснить, как уменьшить размеры EXE-файлов, скомпилированных с использованием новейшего QT SDK (4.8.2) (на основе mingw / g ++). Я работал над консольным приложением vanilla c ++, которое имеет простой цикл и только #include iostream, когда заметил, что сгенерированный им exe составляет около 465 КБ; намного больше, чем они должны быть! Комментирование всех потоковых вещей приводит к ожидаемому диапазону 5 КБ (хотя оставшийся код будет в основном мертвым). Это не кажется правильным, тем более, что другой, полный проект, над которым я работаю, имеет QGLwidget, управление окнами, дюжину структур данных и ~ 3000 операторов, и работает только на 126Kb. Есть какие-то настройки или флаг, который я пропускаю? Вот .pro, в то время как cpp тривиален и не содержит Qt (в основном, getline и cout с полдюжиной подстановок в char):
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += main.cpp
QMAKE_CXXFLAGS_RELEASE += -O2
QMAKE_CXXFLAGS_RELEASE += -Os
Я попробовал несколько других конфигураций, и он определенно компилируется в режиме выпуска (отладка> 3 Мб), но я не могу понять, почему это так раздуто.
Я также посмотрел на PE-заголовок и вижу, что он импортирует некоторые функции из libgcc_s_dw2-1.dll и mingwm10.dll, и было бы неплохо, если бы я мог устранить и эти зависимости в целом, тем более что никто не должен потребоваться в любом случае. Я могу заставить libgcc один уйти (за счет 17kb размера exe), добавив QMAKE_LFLAGS_RELEASE += -static
в .pro, но mingwm10.dll остается в любом случае, вызывая одну функцию.
На основе общего вздутия и всех бесполезных вещей в фреймворке, в которые пытается проникнуть компилятор (по крайней мере, в сети). Я предполагаю, что это просто вопрос нескольких настроек, которые являются искаженными, особенно с некоторыми флагами компилятора по умолчанию, такими как -DQT_LARGEFILE_SUPPORT или -mthreads. Вот результат компиляции (маркеры добавлены для акцента):
Одна из проблем использования mingw заключается в том, что версия binutils для w32 не поддерживает удаление мертвого кода (он удаляет части библиотек, которые вы на самом деле не используете.) Чтобы уменьшить размеры моих исполняемых файлов, я пришлось патчить и собирать binutils из исходного кода, используя патчи здесь:
http://sourceware.org/bugzilla/show_bug.cgi?id=11539
Это помогло. Но для того, чтобы это работало, вам нужно будет восстановить все с помощью:
-fdata-секции -функция-секции
в флагах компиляции всего (включая GCC, Qt, другие библиотеки а также ваше собственное приложение) и:
-Wl, - ГЦ-секция
только в ссылочных флагах вашего приложения. Это стоило того для меня, так как раньше мои исполняемые файлы весили около 20 МБ, а теперь их вдвое меньше, а они — около 10 МБ. Это включает все библиотеки (я связываю статически), включая Qt, SDL и различные библиотеки мультимедиа (такие как Vorbis, mpg123, FLAC и другие).
Хотя я полагаю, что если вы будете использовать Windows, это будет нелегко. Я использовал Linux для создания версий для кросс-компиляции w32, что намного проще.
Я бы сказал, чтобы добавить в -s
команда.
Эта команда удаляет скомпилированный двоичный файл всех символов отладки. Обычно, когда вы что-то компилируете, компилятор оставляет имена классов и функций в файле .exe для поиска. Эти символы будут включать все включенные заголовки. Таким образом, вы. EXE-файл будет иметь символы из iostream
, включая функции и классы.
МинГВ имеет nm.exe
который может быть выполнен из cmd для вывода списка всех символов в файле. Вместе с strip.exe
раздеть уже созданные файлы своих символов.