How to deploy Qt applications for Linux
But I still couldn’t make static Qt application, the executable generated by the above documented steps still needs Qt shared objects on other system.
After you’ve build Qt itself with the -static flag, are you sure that you built your own application using the correct Qt version, and that the static libs were linked?
i did ldd to see if executable is not link with any system shared object but putting all efforts its stil linked to a system’s Qt shared objects, I also tried it to run on other Linux system but it doesn’t work
I’m not sure you can completely statically link to the QML libraries and .qml file. I am using static linking to Qt, but I still need to deploy some QML components
2 Answers 2
You need to deploy the application, for this purpose I use the utility cqtdeployer
This utility itself collects all the necessary dependencies of your application and you do not have to spend your time on it, or you can automate this process.
You can install from github releases (Windows)
sudo snap install cqtdeployer
%cqtdeployer% -bin myApp -qmake path/to/Qt/5.x.x/build/bin/qmake.exe -qmlDir path/to/my/qml/files/dir
cqtdeployer -bin myApp -qmake path/to/Qt/5.x.x/build/bin/qmake -qmlDir path/to/my/qml/files/dir
- path/to/Qt/5.x.x/build/bin/qmake — This is the way qmake is used to build your program.
- path/to/my/qml/files/dir — this is the path directly to your qml file (which you wrote)
And Run application with sh script (Linux) or exe (Windows)
If you’ll use the version from snap then make sure that you have all the permissions.
If you need use windows version just install application from installer
Updated
If you want create a simple installer for you application just add qif option for command of cqtdeployer. Example :
cqtdeployer -bin myApp -qmake path/to/Qt/5.x.x/build/bin/qmake -qmlDir path/to/my/qml/files/dir qif
Details on all the intricacies of cqtdeployer can be found on the official wiki project.
@Silicomancer if you about creating packages with cqtdeployer then it is only QIF installers and zip arhive (from version 1.5). There are plans to add support for snaps and deb packages. If you about packages of cqtdeployer then the cqtdeployer can be installed from the snap package and qif installer.
@Silicomancer I plan to add support for creating snap packages, but I still did not undertake this task. on the way now is the creation of self-contained deb packages.
Finally found an answer that actually works! Entirely automatic, allows you to distribute a QT project on Ubuntu Linux without violating the GPL license.
The best way to deploy your application is not necessarily to statically link it for the following reasons:
- LGPL licencing means that your application must now be made public and may not sold (I think) — i.e. since its statically linked and the qt libs are within your executable your executable is now part of the open source.
- Its a massive pain in the arse. I have gone around this loop and know the pain well.
Installing qt-everywhere is also not so great, I just don’t see how you can garantee that the libraries will be the same version as the ones that your program needs.
So what I started to do was create my own script to deploy qt for me. The basic «jist» of this is that you use ldd to find out which qt libraries you need and copy them into a sub folder ( ./lib ) within the same folder as your executable to make an install bundle.
Note: on Windows there is a deployqt application which does somthing similar (can’t remember exactly what it is called).
Below I have copied a version of my deploy script. Note that it is quite old now, but I don’t see why it should not work (its not written particularly well), but if not it will give you a start place. Also look out for the plugin’s. In this script I have added code to copy the audio plugin since I was using that. If you are using other plugins then you will need to copy those (they are usually in sub dir’s of the qt libs like . /audio). I had a todo to try to figure out what plugins are needed from the .pro file but I never got around to that (I would have to pass in the .pro file to this script as well).
To run, just run this script and pass in the directory that your executable lives in.
#!/bin/bash # Rememeber start dir START_DIR=$PWD # Determine which dir to deploy in and cd to that dir if [ -d "$1" ]; then DEPLOY_DIR=$1 else DEPLOY_DIR=$PWD fi echo "Deploy dir: $DEPLOY_DIR" cd $DEPLOY_DIR # Run ldd on all files in the directory and create a list of required qt libs flag=false for entry in `ldd $DEPLOY_DIR/* | grep -i qt`; do if $flag; then # Only add to the array if it is not already in it if ! [[ $libsArray =~ $entry ]]; then echo "adding $entry" libsArray="$libsArray $entry" fi flag=false fi # If we see a "=>" then the next line will be a library if [ $entry == "=>" ]; then flag=true fi done echo echo # Create the required folder structure. Note here we are need the qt audio plugin so we are going to manually copy that as well. mkdir -p lib mkdir -p lib/audio # Now copy these files to the deploy directory for entry in $libsArray; do echo "cp -v -f $entry $DEPLOY_DIR/lib" cp -v -f $entry $DEPLOY_DIR/lib done # Now get the audio lib - this is a plugin that we are using so we need these libs as well. # Add other plugins here as well. # TODO: maybe we can read this in from the *.pro file. cp -v -f `qmake -query QT_INSTALL_BINS`/../plugins/audio/* $DEPLOY_DIR/lib/audio # Go back to start dir cd $START_DIR
Once you have all the files you need you should be able to copy the whole lot to another PC and run it. Note: you may have to set the export LD_LIBRARY_PATH= so that the libs can be found. or install the libs into somewhere like /usr/lib/your-appplication/ .
But installing libs is another question/subject!
Развертывание Qt и QML приложений в Linux и Windows
В этой статье мы рассмотрим, как правильно собрать все зависимости qt для вашего приложения, которое было собрано динамически.
Для начала немного теории.
Зачем это нужно?
- Статическая сборка.
Статическая сборка предполагает создание бинарника, в котором будут все необходимые ссылки на него. Другими словами, в нем будет лежать все, что нужно для его работы. Этот подход подходит для небольших консольных приложений, у которых мало зависимостей, иначе размер конечного бинарного файла будет чрезвычайно большим. - Динамичная сборка.
Отличается от статического тем, что в бинарнике будет только исходный код вашего приложения (размер бинарника будет минимальным), но при запуске такого приложения ему потребуются сторонние библиотеки, которые использовались при его написании.
Теперь небольшое описание.
Console-QtDeployer — это простая утилита, похожая на windeployqt и macdeployqt . Но в отличии от аналогов у него гораздо более гибкий интерфейс (флаги запуска) и более высокая скорость, к тому же он поддерживает 2 платформы windows и linux, а значит теперь мы можем строить зависимости для windows на линуксе и наоборот.
Возьмем пример.
Например, я написал простое qt-приложение с использованием qml — MyApp.
MyApp (main.cpp)
#include #include 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, который настроит необходимое окружение для вашего приложения.
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
Рекомендуемые статьи по этой тематике
По статье задано0 вопрос(ов)
Вам это нравится? Поделитесь в социальных сетях!