Раздутые размеры EXE и нежелательные зависимости с Qt / MingW

Я пытаюсь выяснить, как уменьшить размеры 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. Вот результат компиляции (маркеры добавлены для акцента):

  • 14:04:00: выполнение шагов для проекта conTest …
  • 14:04:00: Конфигурация не изменилась, пропуская шаг qmake.
  • 14:04:01: Запуск: «C: \ QtSDK \ mingw \ bin \ mingw32-make.exe»
  • C: / QtSDK / mingw / bin / mingw32-make -f Makefile.Release
  • mingw32-make [1]: вход в каталог `C: / Documents and Settings / Администратор / Мои документы / QT / conTest ‘
  • g ++ -c -O2 -O2 -Os -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -I «c: \ QtSDK \ Desktop \ Qt \ 4.8.1 \ mingw \ mkspecs \ win32-g ++» -o выпуск \ main .o main.cpp g ++ -Wl, -s -Wl, -sssystem, консоль -mthreads -o release \ conTest.exe release / main.o
  • mingw32-make [1]: выход из каталога `C: / Documents and Settings / Administrator / Мои документы / QT / conTest ‘
  • 14:04:10: Процесс «C: \ QtSDK \ mingw \ bin \ mingw32-make.exe» завершился нормально.

5

Решение

Одна из проблем использования 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, что намного проще.

3

Другие решения

Я бы сказал, чтобы добавить в -s команда.
Эта команда удаляет скомпилированный двоичный файл всех символов отладки. Обычно, когда вы что-то компилируете, компилятор оставляет имена классов и функций в файле .exe для поиска. Эти символы будут включать все включенные заголовки. Таким образом, вы. EXE-файл будет иметь символы из iostream, включая функции и классы.

МинГВ имеет nm.exe который может быть выполнен из cmd для вывода списка всех символов в файле. Вместе с strip.exe раздеть уже созданные файлы своих символов.

2