Вступ
У цій статті ми розглянемо, як правильно зібрати всі qt залежності для вашої програми, яке було зібрано динамічно.
Для початку трохи теорії.
Навіщо це потрібно?
Існує кілька способів складання додатків, основні з них:
Статичне складання.
Статичне складання передбачає створення бінарника, в якому будуть усі необхідні посилання на нього. Іншими словами, у ньому лежатиме все, що потрібно для його роботи. Цей підхід підходить для невеликих консольних додатків, які мають мало залежностей, інакше розмір кінцевого бінарного файлу буде надзвичайно великим.Динамічне складання.
Відрізняється від статичного тим, що в бінарнику буде лише вихідний код вашої програми (розмір бінарника буде мінімальним), але при запуску такого додатка йому потрібні сторонні бібліотеки, які використовувалися під час його написання.
Тепер невеликий опис.
Console-QtDeployer — це проста утиліта, схожа на windeployqt та macdeployqt . Але на відміну від аналогів у нього набагато більш гнучкий інтерфейс (прапори запуску) і більш висока швидкість, до того ж він підтримує дві платформи 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 Store
cqtdeployer -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, який налаштує необхідне оточення для вашої програми.
Напишите прожалуйста пример запуска для Windows :-)
отбой Разобрался.... После линуха сложно :-)
Возможно кому то пригодится
сqtdeployer для windows работает точно так же как и для Linux
разница лишь в команде запуска
Подробная инструкция использования под Windows:
Вот моя строка по которой все отлично сработало
написал приложение, холоворд на qt виджетах, без qml. Из визарда QtCreator. Собрал кросскомпилятором. Нужно перенести на таргет.
juvf@juvf-VirtualBox:~/qtWs/test/imx6/release$ ~/CQtDeployer/1.5/cqtdeployer.sh -bin test -qmake ~/soft/juvfTool/arm-buildroot-linux-gnueabihf/sysroot/home/juvf/tools/imx6/qt5_15_2_J/bin/qmake -qmlDir ./
Info: Deploy ...
Info: The targetDir option is not used. CQtDeployer will use default target dir :/home/juvf/qtWs/test/imx6/release/DistributionKit
Info: copy :/home/juvf/qtWs/test/imx6/release/test
Warning: Failed to extract qml! The qt qml dir is not initialized!
Warning: Failed to copy standard Qt translations
Info: deploy done!
Info: copy :/home/juvf/qtWs/test/imx6/release/DistributionKit/tmp_data/Application/bin/qt.conf
Info: copy :/home/juvf/qtWs/test/imx6/release/DistributionKit/tmp_data/Application/bin/test
Info: copy :/home/juvf/qtWs/test/imx6/release/DistributionKit/tmp_data/Application/test.sh
juvf@juvf-VirtualBox:~/qtWs/test/imx6/release$
после имею ТОЛЬКО скрипт test.sh и папку bin в которой два файла: само приложение test и файл qt.conf. Всё! Ни паки lib, ни plugin
перенёс всё на таргет. запускаю скриптом
./test.sh
/opt/argo/bin/test: error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory
ну кагбэ неудевительно, что не может найти libQt5Widgets.so.5. Удевительно, что cqtdeployer не подтянул ни библиотеки, ни плагиины