Russian Qt Forum
Ноябрь 23, 2024, 10:13 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 ... 9   Вниз
  Печать  
Автор Тема: Статическая сборка Qt 5.4 для Win 7. Сжатие exe до мин. размера с помощью upx  (Прочитано 127810 раз)
8Observer8
Гость
« : Январь 22, 2014, 16:09 »

Примечание. После того, как соберёте по инструкции ниже посмотрите, как использовать сборку на практике: Создание оконного приложения на С++ (Qt). Запуск приложения на компьютере пользователя в релизе

Перед тем как научиться собирать приложения в один exe необходимо собрать саму библиотеку Qt статически из исходников. На вашем копьютере будет две версии динамическая (которую вы установили) и статическая. Вы сможете переключаться межну этими сборками из Qt Creator

Инструментарий:
- Версия Qt: Qt 5.4.0 for Windows 32-bit (MinGW 4.9.1, 852 MB)
- ОС Win7

Примечание. Предполагается, что у вас есть папка с исходниками Qt. Для того, чтобы она появилась нужно было на этапе установки поставить голочку "Source Components". Либо найти и скачать исходники Qt отдельно

- переходим в каталог "C:\Qt\Qt5.4.0\5.4\mingw491_32\mkspecs\win32-g++" и создаём резервную копию файла "qmake.conf"

- в файле "qmake.conf" и проводим следующие изменения:

Цитировать
QMAKE_LFLAGS += -static-libgcc -static -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
DEFINES += QT_STATIC_BUILD

Примечание. Эти значения я взял из скрипта "windows-build-qt-static.ps1" из этой инструкции: http://qt-project.org/wiki/How-to-build-a-static-Qt-for-Windows-MinGW

- создаём резервную копию исходников Qt, то есть каталога: C:\Qt\Qt5.4.0\5.4\Src\

- отрываем терминал "Start" -> "All Programs" -> "Qt 5.4.0" -> "5.4" -> "MinGW 4.9 (32 bit)" -> "Qt 5.4.0 for Desktop (MinGW 4.9 32 bit)"

- переходим в директорию с исходниками. Для этого вводим команду и нажимаем "Enter":

Цитировать
cd C:\Qt\Qt5.4.0\5.4\Src\

- конфигурируем этапы установки, для этого вводим команду и нажимаем "Enter":

Цитировать
configure -static -platform win32-g++ -prefix "C:\Qt\Qt5.4.0_Static" -release -opensource -confirm-license -nomake examples -nomake tests -nomake tools -opengl desktop -no-angle -qt-sql-sqlite -make libs -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype

- ожидаем окончания конфигурирования, примерно, 10 мин. (время зависит от мощности компьютера)

- производим компиляцию исходников Qt, для этого вводим команду и нажимаем "Enter":

Цитировать
mingw32-make

- ожидаем окончания компиляции исходников (на моей машине это заняло 1 час 20 минут)

Примечание. В конце построения вылезут следующие ошибки, но вы не обращайте на них внимания:

Код:
g++ -c -pipe -fno-keep-inline-dllexport -msse2 -mstackrealign -mfpmath=sse -O2 -
std=c++0x -fno-exceptions -frtti -Wall -Wextra -DUNICODE -DQT_NO_URL_CAST_FROM_S
TRING -DQT_NO_INTEGER_EVENT_COORDINATES -DQT_BUILD_QML_LIB -DQT_BUILDING_QT -D_C
RT_SECURE_NO_WARNINGS -D_USE_MATH_DEFINES -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_
WARNINGS -DQT_MOC_COMPAT -DQT_USE_QSTRINGBUILDER -DQT_DEPRECATED_WARNINGS -DQT_D
ISABLE_DEPRECATED_BEFORE=0x040800 -DWTF_EXPORT_PRIVATE= -DJS_EXPORT_PRIVATE= -DW
TFReportAssertionFailure=qmlWTFReportAssertionFailure -DWTFReportBacktrace=qmlWT
FReportBacktrace -DWTFInvokeCrashHook=qmlWTFInvokeCrashHook -DNOMINMAX -DENABLE_
LLINT=0 -DENABLE_DFG_JIT=0 -DENABLE_DFG_JIT_UTILITY_METHODS=1 -DENABLE_JIT_CONST
ANT_BLINDING=0 -DBUILDING_QT__ -DWTF_USE_UDIS86=0 -DNDEBUG -DQT_NO_EXCEPTIONS -D
QT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -I'../../include' -I'../../includ
e/QtQml' -I'../../include/QtQml/5.4.0' -I'../../include/QtQml/5.4.0/QtQml' -I'tm
p' -I'compiler' -I'.' -I'../3rdparty/masm/jit' -I'../3rdparty/masm/assembler' -I
'../3rdparty/masm/runtime' -I'../3rdparty/masm/wtf' -I'../3rdparty/masm/stubs' -
I'../3rdparty/masm/stubs/wtf' -I'../3rdparty/masm' -I'../3rdparty/masm/disassemb
ler' -I'../3rdparty/masm/disassembler/udis86' -I'jit' -I'.' -I'jsruntime' -I'.'
-I'../3rdparty/double-conversion' -I'debugger' -I'animations' -I'C:/Qt/Qt5.4.0/5
.4/Src/qtbase/include/QtCore/5.4.0' -I'C:/Qt/Qt5.4.0/5.4/Src/qtbase/include/QtCo
re/5.4.0/QtCore' -I'C:/Qt/Qt5.4.0/5.4/Src/qtbase/include' -I'C:/Qt/Qt5.4.0/5.4/S
rc/qtbase/include/QtNetwork' -I'C:/Qt/Qt5.4.0/5.4/Src/qtbase/include/QtCore' -I'
.moc/release' -I'C:/Qt/Qt5.4.0/5.4/Src/qtbase/mkspecs/win32-g++' -o .obj/release
/YarrJIT.o ../3rdparty/masm/yarr/YarrJIT.cpp
python C:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/src/3rdparty/masm/create_regex_tables
 > RegExpJitTables.h
/c/cygwin64/bin/python: /c/cygwin64/bin/python: cannot execute binary file
Makefile.Release:1093: recipe for target 'RegExpJitTables.h' failed
mingw32-make[4]: *** [RegExpJitTables.h] Error 126
mingw32-make[4]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/src/qml'

Makefile:34: recipe for target 'release' failed
mingw32-make[3]: *** [release] Error 2
mingw32-make[3]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/src/qml'

Makefile:45: recipe for target 'sub-qml-make_first-ordered' failed
mingw32-make[2]: *** [sub-qml-make_first-ordered] Error 2
mingw32-make[2]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/src'
Makefile:41: recipe for target 'sub-src-make_first' failed
mingw32-make[1]: *** [sub-src-make_first] Error 2
mingw32-make[1]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative'
makefile:217: recipe for target 'module-qtdeclarative-make_first' failed
mingw32-make: *** [module-qtdeclarative-make_first] Error 2

C:\Qt\Qt5.4.0\5.4\Src>

- копируем файлы в каталог установки (каталог установки мы указали на этапе конфигурирования C:\Qt\Qt5.4.0_Static), для этого вводим команду и нажимаем "Enter":

Цитировать
mingw32-make install

- ожидаем окончания копирования. Статическая сборка теперь будет храниться в папке C:\Qt\Qt5.4.0_Static

Примечание. В конце установки вылезут следующие ошибки, но вы не обращайте на них внимания:

Код:
g++ -Wl,--gc-sections -Wl,-s -Wl,-subsystem,console -o ../../bin/qml.exe .obj/re
lease/main.o .obj/release/qml_qml_plugin_import.o .obj/release/qml_plugin_import
.o .obj/release/qrc_qml.o .obj/release/moc_conf.o  -LC:/Qt/Qt5.4.0/5.4/Src/qtdec
larative/lib -LC:/Qt/Qt5.4.0/5.4/Src/qtbase/lib -lQt5Widgets -LC:/Qt/Qt5.4.0/5.4
/Src/qtdeclarative/plugins/qmltooling -lqmldbg_qtquick2 -lQt5Quick -lqmldbg_tcp
-lQt5Qml -LC:/Qt/Qt5.4.0/5.4/Src/qtbase/plugins/bearer -lqgenericbearer -lqnativ
ewifibearer -lQt5Network -ldnsapi -LC:/Qt/Qt5.4.0/5.4/Src/qtbase/plugins/platfor
ms -lqwindows -lwinspool -lshlwapi -lQt5PlatformSupport -LC:/Qt/Qt5.4.0/5.4/Src/
qtbase/plugins/imageformats -lqico -lQt5Gui -lcomdlg32 -loleaut32 -limm32 -lwinm
m -lglu32 -lopengl32 -lgdi32 -lqtharfbuzzng -lQt5Core -lole32 -luuid -lws2_32 -l
advapi32 -lshell32 -luser32 -lkernel32 -lmpr
C:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/lib/libQt5Qml.a(YarrInterpreter.o):YarrInter
preter.cpp:(.text+0x622): undefined reference to `JSC::Yarr::wordcharCreate()'
C:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/lib/libQt5Qml.a(YarrInterpreter.o):YarrInter
preter.cpp:(.text+0x693): undefined reference to `JSC::Yarr::newlineCreate()'
c:/Qt/Qt5.4.0/Tools/mingw491_32/bin/../lib/gcc/i686-w64-mingw32/4.9.1/../../../.
./i686-w64-mingw32/bin/ld.exe: C:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/lib/libQt5Qml
.a(YarrInterpreter.o): bad reloc address 0x12 in section `.text$_ZN3WTF15BumpPoi
nterPool6createEj[__ZN3WTF15BumpPointerPool6createEj]'
collect2.exe: error: ld returned 1 exit status
Makefile.Release:86: recipe for target '../../bin/qml.exe' failed
mingw32-make[4]: *** [../../bin/qml.exe] Error 1
mingw32-make[4]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/tools/qm
l'
Makefile:44: recipe for target 'release-install' failed
mingw32-make[3]: *** [release-install] Error 2
mingw32-make[3]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/tools/qm
l'
Makefile:107: recipe for target 'sub-qml-install_subtargets' failed
mingw32-make[2]: *** [sub-qml-install_subtargets] Error 2
mingw32-make[2]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative/tools'
Makefile:78: recipe for target 'sub-tools-install_subtargets' failed
mingw32-make[1]: *** [sub-tools-install_subtargets] Error 2
mingw32-make[1]: Leaving directory 'c:/Qt/Qt5.4.0/5.4/Src/qtdeclarative'
makefile:229: recipe for target 'module-qtdeclarative-install_subtargets' failed

mingw32-make: *** [module-qtdeclarative-install_subtargets] Error 2

C:\Qt\Qt5.4.0\5.4\Src>

- удаляем файл C:\Qt\Qt5.4.0\5.4\mingw491_32\mkspecs\win32-g++\qmake.conf и восстанавливаем резервный "qmake.conf"

- удаляем каталог C:\Qt\Qt5.4.0\5.4\Src и восстанавливаем резервный

Регистрируем сборку в Qt Creator статическую сборку. Для этого:
- запускаем QtCreator
- в меню нажимаем "Tools" -> нажимаем "Options"
- слева выбираем "Build & Run", а справа выбираем вкладку "Qt Vertions"
- нажимаем кнопку "Add..." и указываем путь до qmake.exe "C:\Qt\Qt5.4.0_Static\bin\qmake.exe"
- нажимаем кнопку "Apply"
- переходим на вкладку "Kits" и нажимаем кнопку "Add"
- в поле "Name" вводим имя Desktop Qt 5.4.0 Static MinGW 32 bit
- если поле "Debugger" пусто, то нажимаем кнопку "Manage..."
- нажимаем кнопку "Add", вводим название (например gdb) и указываем путь к отладчику "C:\Qt\Qt5.4.0\Tools\mingw49_32\bit\gdb.exe"
- нажимаем кнопку "Apply"
- возвращаемся на на вкладку "Kits"
- в выпадающем списке "Qt versions" выбираем "Desktop Qt 5.4.0 Static MinGW 32 bit"
- нажимаем кнопку "OK"

Теперь мы можем создать новый проект и указать две сборки при создании: динамическую (для отладчки) и статическую (для использования)

Для сборки статической версии приложения нужно:

- перед сборкой выбрать Release
- отрыть файл проекта (*.pro) и добавить строку:

Код
C++ (Qt)
QMAKE_LFLAGS += -static -static-libgcc
 

Нажмите кнопку "Build" (или Ctrl+B) и вы видите, что полученный exe весит, как минимум 15 МБайт. Мы его можем сжать до 5.5 Мбайт с помощью программы upx:

Цитировать
upx.exe -9 -o ПолноеИмяНовогоФайлаEXE ПолноеИмяСтарогоФайлаExe

К примеру, мы собрали статически файл Boxes.exe (15 МБайт). Переименуем его в Boxes1.exe и выполним команду:
Цитировать
D:\_soft\upx391w\upx391w\upx.exe -9 -o C:\Users\Ivan\GoogleDrive\Qt\Bullet\build-Boxes-Desktop_Qt_5_4_MinGW_32bit_Static-Release\release\Boxes.exe C:\Users\Ivan\GoogleDrive\Qt\Bullet\build-Boxes-Desktop_Qt_5_4_MinGW_32bit_Static-Release\release\Boxes1.exe

После этой команды будет создан Boxes.exe весом 5.5 МБайт

Instruction for Linux Mint (and Ubuntu)

Links:
http://help.ubuntu.ru/wiki/qt_static
http://qt-project.org/wiki/Building_Qt_5_from_Git
http://qt-project.org/forums/viewthread/30708/

sudo apt-get install build-essential

sudo apt-get install mesa-common-dev

sudo apt-get install build-essential ^libxcb.* libx11-xcb-dev libglu1-mesa-dev libxrender-dev libfontconfig1-d

cd qt-everywhere-opensource-src-5.4.0

Note. Replace "/home/ivan/Qt5.4.0_Static"

./configure -static -platform linux-g++ -prefix "/home/ivan/Qt5.4.0_Static" -release -opensource -confirm-license -fontconfig -nomake examples -nomake tests -nomake tools -opengl desktop -qt-sql-sqlite -make libs -qt-zlib -qt-pcre -qt-libpng -qt-libjpeg -qt-freetype

make

make install
« Последнее редактирование: Февраль 20, 2015, 17:11 от 8Observer8 » Записан
Serr500
Гость
« Ответ #1 : Январь 22, 2014, 16:29 »

Да уж... Скачай откомпилированную версию Qt и перекомпилируй... Да ещё и папку с исходниками компилятор изгадит. Думаю, инструкция должна быть несколько иной: скачать архив исходников и скомпилировать. И почему собираем только QtBase?

P.S. Никто не пробовал в 5.2 WebKit собирать статически? В четвёрке не собиралось. Интересно, изменилась ли ситуация.
« Последнее редактирование: Январь 22, 2014, 17:11 от Serr500 » Записан
alex312
Хакер
*****
Offline Offline

Сообщений: 606



Просмотр профиля
« Ответ #2 : Январь 22, 2014, 16:56 »

P.S. Никто не пробовал в 5.2 WebKit собирать статически. В четвёрке не собиралось. Интересно, изменилась ли ситуация.
Как-то собирал, не помню какую версию. Но прикол в том что статическая либа WebKit-а весила 100 мегабайт. Пример FunnyBrowser весил около 40 Мб, запускался минут 5.  Шокированный
Записан
8Observer8
Гость
« Ответ #3 : Январь 22, 2014, 17:22 »

> Да уж... Скачай откомпилированную версию Qt и перекомпилируй...
Я скачал откомпилированную версию вместе с исходниками, чтобы была возможность и в обычном режиме собирать приложения, то есть переключаться между статической и динамической версиями сборок.

> Да ещё и папку с исходниками компилятор изгадит.
Да, возможно загаживаются папки с исходниками, но меня это пока не беспокоит. По-моему есть какая-то команда, чтобы почистить папки с исходниками от ненужных файлов. Если кто помнит эту команду, то напишите.

> И почему собираем только QtBase?
Не знаю, что входит в QtBase. Если чего-то не будет хватать, то изменю инструкцию. Добавлю как дополнительные модули подключать к сборке.
« Последнее редактирование: Январь 22, 2014, 17:26 от 8Observer8 » Записан
Serr500
Гость
« Ответ #4 : Январь 22, 2014, 17:35 »

Да, возможно загаживаются папки с исходниками, но меня это пока не беспокоит. По-моему есть какая-то команда, чтобы почистить папки с исходниками от ненужных файлов. Если кто помнит эту команду, то напишите.
А почему Вы считаете, что других это тоже не беспокоит? Папки чистятся от мусора почти полностью командой make clean, но и после этого остаются скомпилированные либы, которые имеют весьма немаленький объём.

Не знаю, что входит в QtBase.
Шедеврально! Смеющийся Больше мне сказать нечего. Надеюсь, что на серьёзных ресурсах подобные инструкции появляться не будут. Засим откланиваюсь.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Январь 22, 2014, 17:47 »

Инструкция для сборки приложений на Qt в один exe без зависимостей от libstdc++-6.dll, libgcc_s_dw2-1.dll, Qt5Core.dll, Qt5Gui.dll и т.д.
Дело хорошее, может сэкономить людям время, НО платформу и компилятор надо обязательно указывать, тоже жирным и желательно первым
Записан
8Observer8
Гость
« Ответ #6 : Январь 22, 2014, 18:08 »

Igors, спасибо за одобрение! Добавил. Я сам, когда собирать пытался, то много помучился и искал вот такую инструкцию. Да, возможно в ней не всё учтено, но я и написал здесь, чтобы мне указали на недостатки. Если у меня в процессе сборок или запуска на другой машине появятся проблемы (не будет хватать других модулей), то я дополню инструкцию. Как уже указали, тут есть проблемка, что QtBase может   если нужны будут дополнительные модули.
Записан
Serr500
Гость
« Ответ #7 : Январь 22, 2014, 18:25 »

- выбираем тип лицензии "Open Source Edition" и подтверждаем лицензию
Код:
configure -static -prefix "C:\Qt\Qt5.2.0_static" -opengl desktop -nomake examples -nomake tests

Дарю:
Код:
-opensource -confirm-license
И ничего выбирать и подтверждать не надо.
Записан
8Observer8
Гость
« Ответ #8 : Январь 22, 2014, 18:31 »

Serr500, спасибо! Пока так оставлю. Когда ещё что-то появится существенное, то проверю работу и тогда изменю Улыбающийся
Записан
Akon
Гость
« Ответ #9 : Январь 23, 2014, 01:02 »

Если для configure указан ключ static, зачем его еще и во флаг компоновщика помещать?
Записан
Serr500
Гость
« Ответ #10 : Январь 23, 2014, 07:35 »

Потому что при -static в configure статическими будут только сами библиотеки Qt, а libstdc++, libgcc и libwinpthread будут связываться динамически. Чтобы убрать зависимость от этих библиотек и меняют флаги компоновщика.
Записан
xintrea
Moderator
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #11 : Январь 23, 2014, 10:40 »

Тебую такую же инструкцию под Linux. А то никакие statifier-ы не работают.
Записан

Собираю информацию по крупицам
http://webhamster.ru
8Observer8
Гость
« Ответ #12 : Январь 23, 2014, 10:52 »

xintrea, это в списке моих приоритетов. Жизненно необходимо для моей будущей работы Улыбающийся Надеюсь получить её. Там нужно будет работать и на Windows и на Linux. Через месяц собеседование. Дали список вопросов и самый первый такой:

Цитировать
1. Деплоймент приложений, написанных с использованием Qt5.2 на Windows, Linux и других платформах.
Записан
Akon
Гость
« Ответ #13 : Январь 23, 2014, 22:18 »

Цитировать
Потому что при -static в configure статическими будут только сами библиотеки Qt, а libstdc++, libgcc и libwinpthread будут связываться динамически. Чтобы убрать зависимость от этих библиотек и меняют флаги компоновщика.
Согласен, спасибо.
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


Просмотр профиля
« Ответ #14 : Январь 25, 2014, 07:25 »

Недостаток статической сборки - большие обновления
В случаи .dll/.so - придется обновить (выслать заказчику/клиенту) только exe файл (+ скрипт обновления), что на порядки меньше всего дистрибутива
Если не gpl/lgpl то нельзя линковать статически (поправьте если не так)
Записан
Страниц: [1] 2 3 ... 9   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.267 секунд. Запросов: 24.