Время на прочтение
6 мин
Количество просмотров 91K
Вступление
Добрый день, уважаемые читатели! Совсем недавно я завершил разработку одного своего приложения на Qt, и мне захотелось создать профессиональную программу установки, чтобы всё было «как у взрослых». Как оказалось, сделать это непросто, учитывая, что на официальном сайте инструментария информации по развёртыванию почти нет. В данной статье рассмотрены некоторые этапы подготовки программ на Qt версии 5.2 или выше для распространения на компьютеры других пользователей. Итак, вот план руководства:
- Подготовка проекта Qt к развёртыванию
- Компоновка дистрибутива программы
- Подписание кода и создание установщика
Не будем терять времени и приступим к работе.
1. Подготовка проекта Qt к развёртыванию
Для того, чтобы было проще следовать инструкциям, создадим простой проект Qt Widgets. Все последующие операции будут относиться к этому проекту. Ниже приведено содержимое исходных файлов приложения:
HelloWorld.pro
QT += core gui widgets
TARGET = HelloWorld
TEMPLATE = app
SOURCES += main.cpp
main.cpp
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label("Hello, world!");
label.setAlignment(Qt::AlignCenter);
label.resize(200, 50);
label.show();
return a.exec();
}
Программы выглядят особенно качественно и профессионально, если они несут с собой метаданные о разработчике, версии программного продукта, авторских правах, языке и многом другом. Для примера, обратимся к свойствам файла Photoshop.exe всем известной системы Adobe Photoshop. На рисунке ниже показано окно свойств данного файла:
Добавить подобную информацию можно с помощью файла ресурсов. Файл ресурсов имеет расширение .rc и несёт в себе текстовый код, описывающий используемые в приложении ресурсы. Подобные скрипты используются в проектах Visual Studio, основанных на WinAPI, и содержат различные дескрипторы иконок, строк, идентификаторов и прочего. В проектах Qt всё это имеет мало смысла, однако включение общей информации о программе всё же необходимо. Ниже приведены исходный код файла ресурсов и содержимое файла проекта, который также потребуется изменить:
resources.rc
IDI_ICON1 ICON "icon.ico"
#include <windows.h>
#define VER_FILEVERSION 1,0,0,0
#define VER_FILEVERSION_STR "1.0.0.0\0"
#define VER_PRODUCTVERSION 1,0,0
#define VER_PRODUCTVERSION_STR "1.0.0\0"
#define VER_FILEDESCRIPTION_STR "HelloWorld"
#define VER_INTERNALNAME_STR "Sensor"
#define VER_LEGALCOPYRIGHT_STR "Copyright (C) 2015, MyCompany"
#define VER_ORIGINALFILENAME_STR "HelloWorld.exe"
#define VER_PRODUCTNAME_STR "Hello World"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
HelloWorld.pro
QT += core gui widgets
TARGET = HelloWorld
TEMPLATE = app
SOURCES += main.cpp
RC_FILE = resources.rc
В данном примере важно не забыть добавить файлы resources.rc и icon.ico в папку с исходными файлами проекта. На рисунке ниже показано окно свойств программы после сборки:
Иногда бывает необходимо, чтобы программа запускалась с правами администратора. В рамках Qt это можно реализовать путём использования несложных инструкций в файле проекта. Ниже приведён код, позволяющий программе запрашивать права администратора при запуске:
HelloWorld.pro
QT += core gui widgets
TARGET = HelloWorld
TEMPLATE = app
SOURCES += main.cpp
RC_FILE = resources.rc
win32
{
CONFIG += embed_manifest_exe
QMAKE_LFLAGS_WINDOWS += /MANIFESTUAC:"level='requireAdministrator'"
}
Следует отметить, что все указанные выше инструкции будут гарантированно работать только при использовании комплекта сборки Visual Studio. Подробную информацию о файлах ресурсов можно найти на портале MSDN в разделе «About Resource Files».
2. Компоновка дистрибутива программы
Создание дистрибутива приложения с учётом всех его файлов, которые должны устанавливаться на компьютерах пользователей, вероятно, является самым сложным этапом развёртывания. Требуется тщательно проанализировать исполняемый файл программы на наличие зависимостей, позаботиться о файлах переводов, не забыть про ресурсы приложения. Решить часть этих проблем поможет утилита
windeployqt.exe
, которая поставляется вместе с комплектом сборки. Данный инструмент работает в командной строке и поддерживает некоторые параметры конфигурации. На рисунке ниже показано окно командной строки с запущенной утилитой:
Последним параметром обязательно должен быть указан путь к двоичным файлам собранного приложения или имена этих файлов. В таблице ниже перечислены параметры утилиты, которые можно использовать при работе с ней:
После запуска утилиты возле исполняемого файла программы должны появиться различные библиотеки и служебные файлы, которые позволят приложению корректно запускаться и работать на многих компьютерах. На рисунке ниже показано окно Проводника Windows со структурой дистрибутива:
Следует отметить, что перед использованием windeployqt.exe необходимо добавить путь к этому файлу в переменную среды PATH, в противном случае данный инструмент работать не будет.
3. Подписание кода и создание установщика
После компоновки дистрибутива программы попробуем запустить приложение от имени администратора. На рисунке ниже показано сообщение системной службы User Account Control (UAC) с предупреждением о запуске приложения неизвестного издателя:
Данное предупреждение отпугивает пользователей и создаёт приложению плохую репутацию. Чтобы исправить ситуацию, нужно подписать файлы программы с помощью специального сертификата. Разработчики, подписывая свои программы, как бы дают дополнительные гарантии надёжности приложений с точки зрения информационной безопасности. Разработчики программного обеспечения с открытым исходным кодом могут получить сертификаты для своих проектов бесплатно, к примеру, на сайте Certum. Для использования сертификата понадобиться специальная программа, которая подпишет файлы приложения. Для этого можно использовать удобный инструмент DigiCert Certificate Utility. На рисунке ниже показано окно данной программы со списком сертификатов для подписания кода:
После использования данной утилиты стоить снова попробовать запустить приложение от имени администратора. Ниже показано сообщение UAC с отображением информации об издателе программы:
После проделанной работы пришло время задуматься над выбором системы создания установщика для подготовленного приложения. Существуют как платные, так и бесплатные продукты для выполнения данной задачи. В таблице ниже перечислены некоторые инструменты для создания программ установки:
Сложно дать какие-либо рекомендации по поводу выбора той или иной системы. Разработчики ПО с открытым исходным кодом, вероятно, выберут бесплатные инструменты, в то же время платные продукты часто используются коммерческими компаниями.
Заключение
В заключение нужно сказать, что к подготовке приложений к выпуску следует подходить с большой ответственностью. Перед использованием программы пользователь проходит этап установки продукта на компьютер. Информация, которую он при этом получает, должна произвести благоприятное впечатление.
- 1. Вступление
- 2. Для начала немного теории.
- 3. Зачем это нужно?
- 4. Теперь небольшое описание.
- 5. Возьмем пример.
- 6. MyApp (main.cpp)
- 7. MyApp (main.qml)
- 8. Общее
Вступление
В этой статье мы рассмотрим, как правильно собрать все зависимости qt для вашего приложения, которое было собрано динамически.
Для начала немного теории.
Зачем это нужно?
Существует несколько способов сборки приложений, основные из них:
-
Статическая сборка.
Статическая сборка предполагает создание бинарника, в котором будут все необходимые ссылки на него. Другими словами, в нем будет лежать все, что нужно для его работы. Этот подход подходит для небольших консольных приложений, у которых мало зависимостей, иначе размер конечного бинарного файла будет чрезвычайно большим. -
Динамичная сборка.
Отличается от статического тем, что в бинарнике будет только исходный код вашего приложения (размер бинарника будет минимальным), но при запуске такого приложения ему потребуются сторонние библиотеки, которые использовались при его написании.
Теперь небольшое описание.
Console-QtDeployer — это простая утилита, похожая на
windeployqt
и
macdeployqt
. Но в отличии от аналогов у него гораздо более гибкий интерфейс (флаги запуска) и более высокая скорость, к тому же он поддерживает 2 платформы windows и linux, а значит теперь мы можем строить зависимости для windows на линуксе и наоборот.
Возьмем пример.
Например, я написал простое qt-приложение с использованием qml — MyApp.
MyApp (main.cpp)
#include <QGuiApplication> #include <QQmlApplicationEngine> int main (int argc, char * argv []) { QCoreApplication :: setAttribute (Qt :: AA_EnableHighDpiScaling); QGuiApplication app (argc, argv); QQmlApplicationEngine engine; engine.load (QUrl (QStringLiteral ("qrc: /main.qml"))); if (engine.rootObjects (). isEmpty ()) return -1; return app.exec (); }MyApp (main.qml)
import QtQuick 2.9 import QtQuick.Controls 2.2 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr ("Scroll") ScrollView { anchors.fill: parent ListView { width: parent.width model: 20 delegate: ItemDelegate { text: "Item" + (index + 1) width: parent.width } } } }MyApp подключается динамически, то есть для работы ему нужны библиотеки qt.
Если мы попытаемся запустить приложение, то сразу после сборки получим ошибку:~/build-MyApp-Desktop_Qt_5_11_1_GCC_64bit4-Release $ ./MyApp ./MyApp: /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5: version `Qt_5 'not found (required by ./MyApp) ./MyApp: /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5: version `Qt_5 'not found (required by ./MyApp) ./MyApp: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5: version `Qt_5.11 'not found (required by ./MyApp) ./MyApp: /usr/lib/x86_64-linux-gnu/libQt5Core.so.5: version `Qt_5 'not found (required by ./MyApp)Из подобных текстов мы видим, что приложение зависит от графических библиотек qt и qml. Поиск и сборка всех ресурсов (библиотек и плагинов) займет много времени.
Для экономии времени и сил воспользуемся утилитой CQtDeployer (ее можно скачатьздесь
)
или установить в Snap Storecqtdeployer -bin myApp -qmake /media/D/Qt/5.12.3/gcc_64/bin/qmake -qmlDir ./После выполнения этой команды вы получите полностью готовое приложение для работы с готовым лаунчером, который настроит все необходимые окружения для работы вашего приложения на всех машинах под управлением Linux.
Общее
После запуска Консоли QtDeployer содержимое папки с вашим приложением должно выглядеть так:
drwxr-xr-x 7 andrei andrei 4096 May 24 12:22 ./ drwxrwxr-x 3 andrei andrei 4096 May 24 12:22 ../ drwxr-xr-x 2 andrei andrei 4096 May 24 12:22 bin/ drwxr-xr-x 2 andrei andrei 4096 May 24 12:22 lib/ -rwx---rwx 1 andrei andrei 433 May 24 12:22 myApp.sh* drwxr-xr-x 6 andrei andrei 4096 May 24 12:22 plugins/ drwxr-xr-x 5 andrei andrei 4096 May 24 12:22 qml/ drwxr-xr-x 2 andrei andrei 4096 May 24 12:22 translations/
- myApp.sh — скрипт запуска вашего приложения
- bin — папка с вашим бинарником
- lib — папка со всеми необходимыми зависимостями вашего приложения.
- plugins — qt плагины, необходимые для работы приложения
- qml — qml зависимости.
- translations — стандартные переводы qt.
Таким образом, вы можете подготовить свое приложение к упаковке в deb или snap пакет, после чего можете приступить к его распространению. Обратите внимание, что после запуска cqtdeployer ваше приложение должно быть запущено с помощью скрипта sh, который настроит необходимое окружение для вашего приложения.
Вступление
Добрый день, уважаемые читатели! Совсем недавно я завершил разработку одного своего приложения на Qt, и мне захотелось создать профессиональную программу установки, чтобы всё было «как у взрослых». Как оказалось, сделать это непросто, учитывая, что на официальном сайте инструментария информации по развёртыванию почти нет. В данной статье рассмотрены некоторые этапы подготовки программ на Qt версии 5.2 или выше для распространения на компьютеры других пользователей. Итак, вот план руководства:
- Подготовка проекта Qt к развёртыванию
- Компоновка дистрибутива программы
- Подписание кода и создание установщика
Не будем терять времени и приступим к работе.
1. Подготовка проекта Qt к развёртыванию
Для того, чтобы было проще следовать инструкциям, создадим простой проект Qt Widgets. Все последующие операции будут относиться к этому проекту. Ниже приведено содержимое исходных файлов приложения:
HelloWorld.pro
QT += core gui widgets
TARGET = HelloWorld
TEMPLATE = app
SOURCES += main.cpp
main.cpp
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel label("Hello, world!");
label.setAlignment(Qt::AlignCenter);
label.resize(200, 50);
label.show();
return a.exec();
}
Программы выглядят особенно качественно и профессионально, если они несут с собой метаданные о разработчике, версии программного продукта, авторских правах, языке и многом другом. Для примера, обратимся к свойствам файла Photoshop.exe всем известной системы Adobe Photoshop. На рисунке ниже показано окно свойств данного файла:
Добавить подобную информацию можно с помощью файла ресурсов. Файл ресурсов имеет расширение .rc и несёт в себе текстовый код, описывающий используемые в приложении ресурсы. Подобные скрипты используются в проектах Visual Studio, основанных на WinAPI, и содержат различные дескрипторы иконок, строк, идентификаторов и прочего. В проектах Qt всё это имеет мало смысла, однако включение общей информации о программе всё же необходимо. Ниже приведены исходный код файла ресурсов и содержимое файла проекта, который также потребуется изменить:
resources.rc
IDI_ICON1 ICON "icon.ico"
#include <windows.h>
#define VER_FILEVERSION 1,0,0,0
#define VER_FILEVERSION_STR "1.0.0.0\0"
#define VER_PRODUCTVERSION 1,0,0
#define VER_PRODUCTVERSION_STR "1.0.0\0"
#define VER_FILEDESCRIPTION_STR "HelloWorld"
#define VER_INTERNALNAME_STR "Sensor"
#define VER_LEGALCOPYRIGHT_STR "Copyright (C) 2015, MyCompany"
#define VER_ORIGINALFILENAME_STR "HelloWorld.exe"
#define VER_PRODUCTNAME_STR "Hello World"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
HelloWorld.pro
QT += core gui widgets
TARGET = HelloWorld
TEMPLATE = app
SOURCES += main.cpp
RC_FILE = resources.rc
В данном примере важно не забыть добавить файлы resources.rc и icon.ico в папку с исходными файлами проекта. На рисунке ниже показано окно свойств программы после сборки:
Иногда бывает необходимо, чтобы программа запускалась с правами администратора. В рамках Qt это можно реализовать путём использования несложных инструкций в файле проекта. Ниже приведён код, позволяющий программе запрашивать права администратора при запуске:
HelloWorld.pro
QT += core gui widgets
TARGET = HelloWorld
TEMPLATE = app
SOURCES += main.cpp
RC_FILE = resources.rc
win32
{
CONFIG += embed_manifest_exe
QMAKE_LFLAGS_WINDOWS += /MANIFESTUAC:"level='requireAdministrator'"
}
Следует отметить, что все указанные выше инструкции будут гарантированно работать только при использовании комплекта сборки Visual Studio. Подробную информацию о файлах ресурсов можно найти на портале MSDN в разделе «About Resource Files».
2. Компоновка дистрибутива программы
Создание дистрибутива приложения с учётом всех его файлов, которые должны устанавливаться на компьютерах пользователей, вероятно, является самым сложным этапом развёртывания. Требуется тщательно проанализировать исполняемый файл программы на наличие зависимостей, позаботиться о файлах переводов, не забыть про ресурсы приложения. Решить часть этих проблем поможет утилита
windeployqt.exe
, которая поставляется вместе с комплектом сборки. Данный инструмент работает в командной строке и поддерживает некоторые параметры конфигурации. На рисунке ниже показано окно командной строки с запущенной утилитой:
Последним параметром обязательно должен быть указан путь к двоичным файлам собранного приложения или имена этих файлов. В таблице ниже перечислены параметры утилиты, которые можно использовать при работе с ней:
Параметр | Описание |
-?, -h, —help | Вывод справки |
-v, —version | Вывод информации о версии |
—dir <каталог> | Использовать указанный каталог вместо каталога файлов |
—libdir <путь> | Каталог, в который будут скопированы библиотеки |
—debug | Использовать отладочные версии файлов |
—release | Использовать файлы для выпуска |
—release-with-debug-info | Использовать файлы для выпуска с отладочной информацией |
—force | Заменить уже существующие файлы |
—dry-run | Провести работу с целью проверки |
—no-plugins | Пропустить копирование плагинов |
—no-libraries | Пропустить копирование библиотек |
—qmldir <каталог> | Сканировать импорт QML, начиная с указанного каталога |
—no-quick-import | Пропустить Qt Quick |
—no-translations | Пропустить копирование файлов перевода |
—no-system-d3d-compiler | Пропустить копирование компилятора Direct3D |
—compiler-runtime | Копировать зависимости компилятора |
—no-compiler-runtime | Пропустить зависимости компилятора |
—webkit2 | Копировать файлы WebKit2 |
—no-webkit2 | Пропустить WebKit2 |
—json | Печатать вывод в формате JSON |
—angle | Копировать файлы ANGLE |
—no-angle | Пропустить ANGLE |
—list <режим> | Печатать только имена копируемых файлов. Режимы: source, target, relative, mapping |
—verbose <уровень> | Уровень отладки |
-<имя библиотеки> | Добавить указанную библиотеку |
—no-<имя библиотеки> | Не добавлять указанную библиотеку |
После запуска утилиты возле исполняемого файла программы должны появиться различные библиотеки и служебные файлы, которые позволят приложению корректно запускаться и работать на многих компьютерах. На рисунке ниже показано окно Проводника Windows со структурой дистрибутива:
Следует отметить, что перед использованием windeployqt.exe необходимо добавить путь к этому файлу в переменную среды PATH, в противном случае данный инструмент работать не будет.
3. Подписание кода и создание установщика
После компоновки дистрибутива программы попробуем запустить приложение от имени администратора. На рисунке ниже показано сообщение системной службы User Account Control (UAC) с предупреждением о запуске приложения неизвестного издателя:
Данное предупреждение отпугивает пользователей и создаёт приложению плохую репутацию. Чтобы исправить ситуацию, нужно подписать файлы программы с помощью специального сертификата. Разработчики, подписывая свои программы, как бы дают дополнительные гарантии надёжности приложений с точки зрения информационной безопасности. Разработчики программного обеспечения с открытым исходным кодом могут получить сертификаты для своих проектов бесплатно, к примеру, на сайте Certum. Для использования сертификата понадобиться специальная программа, которая подпишет файлы приложения. Для этого можно использовать удобный инструмент DigiCert Certificate Utility. На рисунке ниже показано окно данной программы со списком сертификатов для подписания кода:
После использования данной утилиты стоить снова попробовать запустить приложение от имени администратора. Ниже показано сообщение UAC с отображением информации об издателе программы:
После проделанной работы пришло время задуматься над выбором системы создания установщика для подготовленного приложения. Существуют как платные, так и бесплатные продукты для выполнения данной задачи. В таблице ниже перечислены некоторые инструменты для создания программ установки:
Платные | Бесплатные |
InstallShield | NSIS |
SetupBuilder | Inno Setup |
Smart Install Maker | WiX |
Сложно дать какие-либо рекомендации по поводу выбора той или иной системы. Разработчики ПО с открытым исходным кодом, вероятно, выберут бесплатные инструменты, в то же время платные продукты часто используются коммерческими компаниями.
Заключение
В заключение нужно сказать, что к подготовке приложений к выпуску следует подходить с большой ответственностью. Перед использованием программы пользователь проходит этап установки продукта на компьютер. Информация, которую он при этом получает, должна произвести благоприятное впечатление.
This entry passed through the Full-Text RSS service — if this is your content and you’re reading it on someone else’s site, please read the FAQ at http://ift.tt/jcXqJW.
Development is not an only part of product delivering – deployment and maintenance are both equally important parts of the product lifecycle. That is why Qt lend us a hand by providing Installer Framework. It is a set of tools that allows not only to create good-looking and functional installers but also update the app, provide tools for maintaining it, and much more. In this tutorial, you will learn the basics of Qt Installer Framework and find out how to generate your first offline installer for Windows. Let’s go!
How to get Qt Installer Framework?
Qt Installer framework can be easily installed via Qt Maintenance tool or downloaded from Qt repository. When using a maintenance tool, it can be found in the Developer and Designer Tools section:
After download it should be stored in [QtDirectory]/Tools/QtInstallerFramework
How to generate installer with Qt Installer Framework?
1. Create a deployment folder
Before generating an installer, you have to prepare your app for deployment. The first step is to create a deployment folder where all necessary files for app execution and installer generation will be stored. Inside it, you should create two directories: „config” and „packages”.
As the name suggests, the first directory will contain configuration files for your installer – in this case a single XML file. What should this file contain?
2. Create a config file
The configuration file consists of some general information about the app: installation directory, name of the installer, etc. You can make some interesting things by modifying this file – for example, add a „run after installation” checkbox, modify installer UI or even add remote repositories for fetching app updates. You can learn about all the available tags in the Qt Installer documentation.
Let’s create such a file. The basic one should look like this:
<?xml version="1.0" encoding="UTF-8"?> <Installer> <Name>APP NAME</Name> <Version>1.0.0</Version> <Title>INSTALLER WINDOW TITLE</Title> <Publisher>Scythe Studio</Publisher> <StartMenuDir>START_MENU_DIR</StartMenuDir> <TargetDir>@HomeDir@/APP_DIR</TargetDir> </Installer>
Although it is minimalistic, for now, this would be enough.
3. Create a package
Before you go any further, you should learn what the package actually is. The package is a module that contains a certain version or some parts of the app. If you include many packages, the installation can be customized – users can select what they want to install. Qt itself is a great example of such approach. Let’s take a look at the tree structure in the Qt installer:
As you see, the framework is divided into several packages containing kits for different platforms and modules with optionals functionality like a web engine.
According to the documentation, the packages directory should have following structure:
-packages - com.vendor.root - data - meta - com.vendor.root.component1 - data - meta - com.vendor.root.component1.subcomponent1 - data - meta - com.vendor.root.component2 - data - meta
With this knowledge, you can now start creating the first packages for our app. To make things clear and simple, for now, we’ll roll on with only two packages: a 64-bit app version and a 32-bit one.
Begin by creating proper directories for the packages. We will stick to the „com.developername.shortpackagename” naming pattern:
What about packages content? Let’s begin populating them!
4. Add metadata
Each package should contain two main directories inside: „data” and „meta”. First will contain executables, libraries, and other files necessary for running the app, while second hold information about the package. The „Meta” folder will contain only two files, in this case, so start with it.
Metadata should consist of „license.txt” and „package.xml” files. The text file is obvious – it provides the installer with license content. It doesn’t have any required format, but HTML tags are supported if you need some styling.
Now let’s talk about „package.xml” – this one is more interesting. This file contains information about the package, which will be presented in the installer window. By putting additional tags you can add custom installer pages, translations, dependencies between other packages and many more. We will talk about this file again, in another part of the tutorial, which will be published in the future. The „package.xml” content should look like this for now:
<?xml version="1.0" encoding="UTF-8"?> <Package> <DisplayName>PACKAGE NAME</DisplayName> <Description>This is going to install APP NAME on your machine</Description> <Version>1.0.0</Version> <ReleaseDate>2020-06-17</ReleaseDate> <Licenses> <License name="LICENSE TITLE" file="license.txt" /> </Licenses> <Default>true</Default> </Package>
Most of the tags are self-explanatory. If you want to learn more about other tags see documentation.
5. Fill data directory
When you add necessary files to the „meta” directory, move one to the „data” folder. This directory contains all the app files that the package holds. When installing the package, its contents will be unpacked to the target directory. In order to keep the installation folder clear, we suggest creating an additional subfolder in the data directory.
As there is already a large number of folders we talked about, we’ll call this one „package files directory”. With that keeping track would be simpler.
Now the crucial part of deployment preparation begins. Inside the package files directory, you need to add a substantial amount of files needed to run an app outside the Qt Creator IDE: all the executables, Qt and external libraries, dll files, etc. Fortunately, the Qt Framework will help us achieve this by providing a set of tools for deployment.
Now add the executable file to the package files directory. Simply copy it from the build folder. Now open the command line terminal in the package files directory. It is needed to run „windeployqt.exe” – a tool created for automatic loading of all the Qt dll files needed for running the app. To run this tool use this command:
[QtFolder]\[QtVersionThatYouUse]\[SelectedKitDirectory]\bin\windeployqt.exe APPNAME.exe --qmldir [DirectoryContainingProjectQMLSourcecode] --compiler-runtime
This command adds (almost) all necessary binaries and files that you need to launch a QML based app. The -qmldir flag is used to scan your QML code and add all the needed runtime libraries from the Qt Quick module. After this flag put your project directory – don’t worry it will be scanned recursively. If your app is not QML based, you can skip this flag.
In the tutorial case the full command should look like this:
C:\Qt\5.15.0\mingw81_64\bin\windeployqt.exe QtInstallerTutorial.exe --qmldir C:\Projects\QtInstallerTutorial --compiler-runtime
When the tool finishes its work you can see that now the package files directory is getting crowded.
Currently, windeployqt tool tends to ship a lot of unnecessary files here, but even now there is no every file you need. Not yet…
6. Add the compiler-specific files
If you try to run the application now you’ll get an error pop-up showing info about missing files. Depending on the configuration, compiler-specific and some other libraries must be redistributed along with your application. According to the documentation, the basic ones are:
- Qt
-
QT5CORE.DLL – The QtCore runtime
-
QT5GUI.DLL – The QtGui runtime
-
QT5WIDGETS.DLL – The QtWidgets runtime
-
-
VC++ 14.0 (2015)
-
VCCORLIB140.DLL, VCRUNTIME140D.DLL – The C runtime
-
MSVCP140.DLL – The C++ runtime
-
- MinGW
-
LIBWINPTHREAD-1.DLL
-
LIBGCC_S_DW2-1.DLL
-
LIBSTDC++-6.DLL
-
However, to make sure that you didn’t miss anything, following Qt docs advice, we suggest using the Dependency Walker tool. After running it you can easily see what dependencies are missing.
In this case, the LIBGCC_S_SEH-1.DLL and LIBSTDC++-6.DLL are missing. You can find them in the Qt folder, inside the kit directory:
Just copy them to your package files directory. Before finishing the deployment preparation, you should try running the .exe file, as a good practice. This way you will make sure that the app has all the dependencies in place. Currently, the app is still unable to run. We skipped copying LIBWINPTHREAD-1.DLL on purpose, to show that checking if everything is fine, before ending this step is essential. To end this step simply copy LIBWINPTHREAD-1.DLL from the kit directory and your package should be ready for distribution!
Note that the dll files we mentioned before may differ depending on the compiler you use. Also do not forget about applying steps 4 to 7 for all packages you created: in this case, we repeated everything for the 32-bit package.
7. Generate installer
When all of the packages are prepared for deployment you can finally generate an installer. To do it, the „binarycreator” tool from Qt Installer Framework will be needed.
First, open the terminal inside the deployment folder.
Now launch binarycreator.exe using the following command:
[Qt folder]\Tools\QtInstallerFramework\[QtInstallerVersion]\bin\binarycreator.exe -c config/config.xml -p packages -f NAMEOFTHEINSTALLER
The -c flag tells binarycreator where to look for the config file, the -p flag informs where the packages are located, while -f shows binarycreator that you are creating an offline installer. To learn more about available flags look at the documentation.
In the case of the tutorial full command looks like this:
C:\Qt\Tools\QtInstallerFramework\4.0\bin\binarycreator.exe -c config/config.xml -p packages -f QtInstallerTutorial
Don’t worry after hitting enter – your terminal is not frozen. Installer generator can take some time to finish its work. After a while a fresh installer should appear in your deployment directory:
The functional installer should look as follows:
Notice that the installer language was automatically changed to system language – Polish, in this case.
Congratulations – you have generated your first installer! Now feel free to test it out and make sure that everything was set up properly. Installer generated this way can be handled directly to the end-user. The only thing that users need to do is to launch it and proceed with the provided instructions.
It is also worth mentioning that after installing an app with your new installer the maintenance tool for your app is automatically provided. It allows users to add or delete packages, update app (if you set up repositories) or uninstall the whole app.
Other purposes
A good application for the installer generator is definitely using it with the CI/CD system on your repository. With that you can automate the whole process, so the client would always have the newest version of the installer. Every time you merge any changes to the master, proper commands would be executed, without the need of doing anything manually.
Another interesting fact is that with the newest version of the Qt Installer Framework 4.0 the new CLI has been added, allowing you to do some interesting things. The main functionality it provides is interacting with installers and maintenance tools: installing, updating, and modifying the app with command lines.
It can come in handy in cases like auto-updating – your app can simply run a maintenance tool when it gets information from the API that the new version is available or even check for updates directly from the maintenance tool. You can also call functions like uninstaller from the app. If you want to learn more about it, check out the CLI documentation page.
Summary
That is all for this entry. Now you know how to generate an offline installer for the Windows Qt app using Qt Installer Framework. Make sure to check out other entries on the Scythe-Studio blog and like our Facebook profile to make sure you won’t miss future Qt tutorials.
Для распространения программы, написанной на Qt под Windows, кроме исполняемого файла необходимо вместе с ним предоставлять множество DLL. Раньше (до Qt 5.2) приходилось вручную искать DLL в папке Qt и размещать их рядом с исполняемым файлом. Теперь, для автоматизации этого процесса, есть программа windeployqt, которая поставляется вместе с Qt.
windeployqt — консольная программа, поэтому для ее запуска нужно воспользоваться командной строкой.
Командную строку не стоит запускать так, как это обычно делается в Windows. Qt предоставляет свой способ запуска командной строки, который позволяет вызывать консольные программы Qt без лишних телодвижений. В программах меню «Пуск» должен быть соответствующий пункт в разделе Qt. Например, для Qt 5.7.0 (MinGW 5.3.0) этот пункт называется
Qt 5.7 for Desktop (MinGW 5.3.0 32 bit)
и имеет характерную иконку командной строки.
Запуск windeployqt выглядит следующим образом:
windeployqt <путь>
где <путь> — это путь к исполняемому файлу вашей программы или папке, в которой этот файл находится.
Пример:
windeployqt C:\example\build\release\example.exe
После завершения, все файлы, требуемые для работы вашей программы, будут находиться в папке исполняемого файла.
Рекомендации
Разделение файлов сборки и рабочих файлов
По умолчанию исполняемый файл создается в папке сборки, где, кроме него, создается множество других файлов, которые необходимы для сборки, но не нужны для работы программы. А windeployqt примешает к ним файлы, которые нужны только для работы программы.
Рекомендация состоит в том, чтобы разделить файлы сборки от рабочих файлов. Для этого в файле проекта необходимо добавить строчку
DESTDIR = папка_программы
где папка_программы — это имя папки, где будет размещен исполняемый файл, отдельно от файлов сборки. После выполнения windeployqt в этой папке будут находиться только файлы необходимые для работы программы. Что облегчит их распространение или создание установщика.
Примечание: имя папки не должно содержать кириллицу.
Автоматическое развертывание
Чтобы windeployqt запускалась автоматически, можно в файл проекта *.pro добавить следующую строчку:
win32:QMAKE_POST_LINK += windeployqt $$OUT_PWD/$$DESTDIR
где $$OUT_PWD/$$DESTDIR
задает папку с исполняемым файлом. Задание папки не универсально и работает если в DESTDIR
указан относительный путь.
Ссылки
Описание windeployqt на официальном сайте.