Introduction
In this article we will look at how to properly collect all qt dependencies for your application, which was collected dynamically.
For a start, a little theory.
Why is this needed?
There are several ways to build applications, the main ones are:
Static build.
Static assembly involves the creation of a binary, which will be all the necessary links to it. In other words, all that is needed for his work will lie in it. This approach is suitable for small console applications that have few dependencies, otherwise the size of the final binary will be extremely large.Dynamic build.
It differs from static in that only the source code of your application will be in the binary (the size of the binary will be minimal), but when you run such an application it will need third-party libraries that were used when writing it.
Now a little description.
Console-QtDeployer is a simple utility similar to windeployqt and macdeployqt . But unlike analogs, it has a much more flexible interface (launch flags) and higher speed, besides it supports 2 windows and linux platforms, which means that now we can build dependencies for windows on Linux and vice versa.
Let's take an example.
For example, I wrote a simple qt application using 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 is linked dynamically, that is, it needs qt libraries to work.
If we try to start the application, right after the build we get an error:
~/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)
From similar texts, we see that the application depends on the GUI qt libraries and qml libraries. Search and build all resources (libraries and plugins) will take a lot of time.
To save time and effort, we will use the CQtDeployer utility (you can download it
here
)
or install in Snap Store
cqtdeployer -bin myApp -qmake /media/D/Qt/5.12.3/gcc_64/bin/qmake -qmlDir ./
After executing this command, you will receive a fully ready application for work with a ready launcher, which will set up all the necessary environments for your application to work on all machines running Linux.
Total
After running the QtDeployer Console, the contents of the folder with your application should look like this:
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 - your application launch script
- bin - folder with your binary
- lib - a folder with all the necessary dependencies of your application.
- plugins - qt plugins needed for the application to work
- qml - qml dependencies.
- translations - standard qt translations.
Thus, you can prepare your application for packaging in a deb or snap package, after which you can begin to distribute it. Note that after running cqtdeployer, your application must be launched using the sh script, which will set up the necessary environment for your application.
Напишите прожалуйста пример запуска для 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 не подтянул ни библиотеки, ни плагиины