Andrei Yankovich
27 травня 2019 р. 10:57

Розгортання додатків Qt і QML на Linux і Windows

Вступ

У цій статті ми розглянемо, як правильно зібрати всі 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

Завантажити з 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/

результат cqtdeployer

  • myApp.sh - скрипт запуску вашої програми
  • bin - папка з вашим бінарником
  • lib - папка з усіма необхідними залежностями вашої програми.
  • plugins - qt плагіни, необхідні для роботи програми
  • qml - qml залежності.
  • translations – стандартні переклади qt.

Таким чином, ви можете підготувати свою програму до упаковки в deb або snap пакет, після чого можете приступити до його поширення. Зверніть увагу, що після запуску cqtdeployer вашу програму має бути запущено за допомогою скрипта sh, який налаштує необхідне оточення для вашої програми.

Вам це подобається? Поділіться в соціальних мережах!

Ruslan Polupan
  • 21 червня 2019 р. 13:54
  • (відредаговано)

Напишите прожалуйста пример запуска для Windows :-)

отбой Разобрался.... После линуха сложно :-)

Andrei Yankovich
  • 21 червня 2019 р. 14:24
  • (відредаговано)

Возможно кому то пригодится

сqtdeployer для windows работает точно так же как и для Linux

разница лишь в команде запуска

  • Linux: cqtdeployer
  • Windows: %cqtdeployer%

Подробная инструкция использования под Windows:

  1. Качаем онлайн истолятор на момент версии 1.2.3 интерполятор не подписан, по этому Windows может ругаться.
  2. Устанавливаем
  3. Открываем cmd
  4. Пишем %cqdeployer%
Ruslan Polupan
  • 21 червня 2019 р. 14:31

Вот моя строка по которой все отлично сработало

%cqtdeployer% -bin c:/CentralMposKeys/CentalMposKeys.exe -qmake c:/Qt/5.12.2/mingw73_64/bin/qmake.exe
juvf
  • 29 грудня 2021 р. 10:56

написал приложение, холоворд на 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 не подтянул ни библиотеки, ни плагиины

Коментарі

Only authorized users can post comments.
Please, Log in or Sign up