LINUX.ORG.RU

Qt5 deploy проекта на другой рабочей станции.

 , ,


0

1

Добрый день. входные данные:
Рабочая станция: Ubuntu 18.04 Среда разработки Qt5.12.1 Приложение GUI для работы с postgresql
Приложение собирается динамически. Для переноса на другую рабочую станцию написал небольшое приложение которое берет вывод ldd nameapp разбирает и копирует в папку lib в папке с приложением все необходимые библиотеки. Структура приложения получилась следующая

  • Myapp/ - папка приложения
    • myapp - приложение
    • myapp.sh - скрипт запуска приложения
      • lib/ - папка для библиотек
      • platforms/ - папка плагинов Qt5

Создал скрипт для запуска приложения в котором основным является указание приложению где брать библиотеки

LD_LIBRARY_PATH=${dirname}/lib
export LD_LIBRARY_PATH
При переносе на рабочую станцию с такой же системой все отлично работает, а вот при переносе на более старую систему возникла проблема.

user@UBUNTU18-OVIRT:~/TEST$ ./OMSStatistic.sh
Вывод команды 'ldd myapppname'
	linux-vdso.so.1 (0x00007ffe62a4c000)
	libQt5Widgets.so.5 => /home/user/TEST/lib/libQt5Widgets.so.5 (0x00007fb897f47000)
	libQt5Gui.so.5 => /home/user/TEST/lib/libQt5Gui.so.5 (0x00007fb897721000)
	libQt5Sql.so.5 => /home/user/TEST/lib/libQt5Sql.so.5 (0x00007fb8974d9000)
	libQt5Core.so.5 => /home/user/TEST/lib/libQt5Core.so.5 (0x00007fb896d46000)
	libstdc++.so.6 => /home/user/TEST/lib/libstdc++.so.6 (0x00007fb8969bd000)
	libm.so.6 => /home/user/TEST/lib/libm.so.6 (0x00007fb89661f000)
	libgcc_s.so.1 => /home/user/TEST/lib/libgcc_s.so.1 (0x00007fb896407000)
	libc.so.6 => /home/user/TEST/lib/libc.so.6 (0x00007fb896016000)
	libpthread.so.0 => /home/user/TEST/lib/libpthread.so.0 (0x00007fb895df7000)
	libGL.so.1 => /home/user/TEST/lib/libGL.so.1 (0x00007fb895b6b000)
	libz.so.1 => /home/user/TEST/lib/libz.so.1 (0x00007fb89594e000)
	libicui18n.so.56 => /home/user/TEST/lib/libicui18n.so.56 (0x00007fb8954b5000)
	libicuuc.so.56 => /home/user/TEST/lib/libicuuc.so.56 (0x00007fb8950fd000)
	libicudata.so.56 => /home/user/TEST/lib/libicudata.so.56 (0x00007fb89371a000)
	libdl.so.2 => /home/user/TEST/lib/libdl.so.2 (0x00007fb893516000)
	libgthread-2.0.so.0 => /home/user/TEST/lib/libgthread-2.0.so.0 (0x00007fb893314000)
	libglib-2.0.so.0 => /home/user/TEST/lib/libglib-2.0.so.0 (0x00007fb892ffe000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb898b4b000)
	libGLX.so.0 => /home/user/TEST/lib/libGLX.so.0 (0x00007fb892dcd000)
	libGLdispatch.so.0 => /home/user/TEST/lib/libGLdispatch.so.0 (0x00007fb892b17000)
	libpcre.so.3 => /home/user/TEST/lib/libpcre.so.3 (0x00007fb8928a5000)
	libX11.so.6 => /home/user/TEST/lib/libX11.so.6 (0x00007fb89256d000)
	libxcb.so.1 => /home/user/TEST/lib/libxcb.so.1 (0x00007fb892345000)
	libXau.so.6 => /home/user/TEST/lib/libXau.so.6 (0x00007fb892141000)
	libXdmcp.so.6 => /home/user/TEST/lib/libXdmcp.so.6 (0x00007fb891f3b000)
	libbsd.so.0 => /home/user/TEST/lib/libbsd.so.0 (0x00007fb891d26000)
	librt.so.1 => /home/user/TEST/lib/librt.so.1 (0x00007fb891b1e000)
Вывод команды 'ldd platforms/libqxcb.so'
	linux-vdso.so.1 (0x00007ffec8aa4000)
	libQt5XcbQpa.so.5 => /home/user/TEST/lib/libQt5XcbQpa.so.5 (0x00007f63a68e2000)
	libfontconfig.so.1 => /home/user/TEST/lib/libfontconfig.so.1 (0x00007f63a669d000)
	libfreetype.so.6 => /home/user/TEST/lib/libfreetype.so.6 (0x00007f63a63e9000)
	libz.so.1 => /home/user/TEST/lib/libz.so.1 (0x00007f63a61cc000)
	libQt5Gui.so.5 => /home/user/TEST/lib/libQt5Gui.so.5 (0x00007f63a59a6000)
	libQt5DBus.so.5 => /home/user/TEST/lib/libQt5DBus.so.5 (0x00007f63a571a000)
	libQt5Core.so.5 => /home/user/TEST/lib/libQt5Core.so.5 (0x00007f63a4f87000)
	libGL.so.1 => /home/user/TEST/lib/libGL.so.1 (0x00007f63a4cfb000)
	libpthread.so.0 => /home/user/TEST/lib/libpthread.so.0 (0x00007f63a4adc000)
	libX11-xcb.so.1 => /home/user/TEST/lib/libX11-xcb.so.1 (0x00007f63a48da000)
	libxcb.so.1 => /home/user/TEST/lib/libxcb.so.1 (0x00007f63a46b2000)
	libXrender.so.1 => /home/user/TEST/lib/libXrender.so.1 (0x00007f63a44a8000)
	libXext.so.6 => /home/user/TEST/lib/libXext.so.6 (0x00007f63a4296000)
	libX11.so.6 => /home/user/TEST/lib/libX11.so.6 (0x00007f63a3f5e000)
	libm.so.6 => /home/user/TEST/lib/libm.so.6 (0x00007f63a3bc0000)
	libxkbcommon-x11.so.0 => /home/user/TEST/lib/libxkbcommon-x11.so.0 (0x00007f63a39b8000)
	libxkbcommon.so.0 => /home/user/TEST/lib/libxkbcommon.so.0 (0x00007f63a3779000)
	libdl.so.2 => /home/user/TEST/lib/libdl.so.2 (0x00007f63a3575000)
	libstdc++.so.6 => /home/user/TEST/lib/libstdc++.so.6 (0x00007f63a31ec000)
	libgcc_s.so.1 => /home/user/TEST/lib/libgcc_s.so.1 (0x00007f63a2fd4000)
	libc.so.6 => /home/user/TEST/lib/libc.so.6 (0x00007f63a2be3000)
	libgthread-2.0.so.0 => /home/user/TEST/lib/libgthread-2.0.so.0 (0x00007f63a29e1000)
	libglib-2.0.so.0 => /home/user/TEST/lib/libglib-2.0.so.0 (0x00007f63a26cb000)
	libexpat.so.1 => /home/user/TEST/lib/libexpat.so.1 (0x00007f63a2499000)
	libpng16.so.16 => /home/user/TEST/lib/libpng16.so.16 (0x00007f63a2267000)
	libdbus-1.so.3 => /home/user/TEST/lib/libdbus-1.so.3 (0x00007f63a201a000)
	libicui18n.so.56 => /home/user/TEST/lib/libicui18n.so.56 (0x00007f63a1b81000)
	libicuuc.so.56 => /home/user/TEST/lib/libicuuc.so.56 (0x00007f63a17c9000)
	libicudata.so.56 => /home/user/TEST/lib/libicudata.so.56 (0x00007f639fde6000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f63a6e7d000)
	libGLX.so.0 => /home/user/TEST/lib/libGLX.so.0 (0x00007f639fbb5000)
	libGLdispatch.so.0 => /home/user/TEST/lib/libGLdispatch.so.0 (0x00007f639f8ff000)
	libXau.so.6 => /home/user/TEST/lib/libXau.so.6 (0x00007f639f6fb000)
	libXdmcp.so.6 => /home/user/TEST/lib/libXdmcp.so.6 (0x00007f639f4f5000)
	libxcb-xkb.so.1 => /home/user/TEST/lib/libxcb-xkb.so.1 (0x00007f639f2d9000)
	libpcre.so.3 => /home/user/TEST/lib/libpcre.so.3 (0x00007f639f067000)
	libsystemd.so.0 => /home/user/TEST/lib/libsystemd.so.0 (0x00007f639ede3000)
	libbsd.so.0 => /home/user/TEST/lib/libbsd.so.0 (0x00007f639ebce000)
	librt.so.1 => /home/user/TEST/lib/librt.so.1 (0x00007f639e9c6000)
	liblzma.so.5 => /home/user/TEST/lib/liblzma.so.5 (0x00007f639e7a0000)
	liblz4.so.1 => /home/user/TEST/lib/liblz4.so.1 (0x00007f639e584000)
	libgcrypt.so.20 => /home/user/TEST/lib/libgcrypt.so.20 (0x00007f639e269000)
	libgpg-error.so.0 => /home/user/TEST/lib/libgpg-error.so.0 (0x00007f639e054000)
user@UBUNTU18-OVIRT:~/TEST$ 

Как видно из вывода, единственная библиотека которая берется не из моей папки библиотек /lib64/ld-linux-x86-64.so.2 (0x00007fb898b4b000) эта ссылка указывает на библиотеку /lib/x86_64-linux-gnu/ld-2.27.so Это системная библиотека в 18 ubuntu ld-2.27.so в 16 ubuntu ld-2.23.so в Debian 8 ld-2.19.so.
поэтому приложение и не работает на более старых системах. можно ли это как то обойти или единственный выход собрать приложение на более старой ОС , например 12 ubuntu ? Я так понимаю совместимость снизу вверх присутствует ?

что мешает собирать нормальные пакеты под нужные версии дистрибутива? (собирать в докер контейнере)

anonymous ()

Проще всего сделать AppImage твоей программы, вместо этих выкрутасов.

Тем более есть утилита, которая делает это условно в один клик:

https://github.com/probonopd/linuxdeployqt

Буквально ./linuxdeployqt -appimage <app executable>.

EXL ★★★★★ ()

поэтому приложение и не работает на более старых системах

А что пишет-то? Что-то вроде GLIBCXX_NOTFOUND? Если да, то это проблема старой glibc, да. И пересобирать нужно либо на старой версии дистра, либо статически.

на библиотеку /lib/x86_64-linux-gnu/ld-2.27.so Это системная библиотека в 18 ubuntu ld-2.27.so

Не, это «интерпретатор», динамический линкер для ELF-файлов, это влиять не должно.

EXL ★★★★★ ()
Ответ на: комментарий от anonymous

Я вообщето в линуксе новичок, так что пока это для меня сложновато. А разбираться банально нет времени. Вот сделал костыль и дальше пилить задачи.

Honey12345 ()

Если нужно таскать между разными версиями дистрибутивов, которые заранее не определены, и их больше 2-3, целесообразно собрать статикой и не таскать кучу либ. Будет в разы компактнее. И да, собирать это желательно на дистрибутиве постарше, чтобы не столкнуться с проблемой слишком нового glibc.

Только LGPL внимательно читай. Если программа открытая, то пофиг. Если закрытая и пишется сугубо под себя, тоже пофиг. А если закрытая и ты делаешь её куда-то на сторону — то для статики надо обеспечить пользователю слинковать твою программу с другой версией Qt (простейший способ — предоставить объектники).

Если же целевых платформ у тебя 1-2, целесообразно сделать сборку конкретно под них (например, в виртуалке), используя версии Qt из их репозиториев. Будет компактный пакет, зависящий от кутешного. Как, собственно, в линуксе и принято.

hobbit ★★★★★ ()
Ответ на: комментарий от hobbit

целесообразно собрать статикой

Только для этого ещё Qt нужно правильно собрать статически. В Windows, кстати, статический пакет с Qt ставится одной строкой, а в Linux мейнтейнеры популярных дистров пакета qt5-static не завезли.

EXL ★★★★★ ()
Ответ на: комментарий от hobbit

Статическая сборка.

Я вначале и хотел сделать статическую сборку, но с этим какието непонятные проблемы. Скачал исходники, сконфигурил

$ sudo mkdir -p /usr/lib/Qt5_static && ./configure -platform linux-g++ -release -static -opensource -confirm-license -nomake examples -nomake tests -no-openssl -skip qtwebengine -c++std c++14 -nomake tests -qt-zlib -qt-libpng -qt-libjpeg -opengl desktop -prefix ~/MyProject/Qt5_static
собрал библиотеки. Собрал проект, но он не запускается даже на этой же мкашине, вот вывод:
$ ./OMSStatistic
qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Аварийный останов (стек памяти сброшен на диск)
Почемуто не находжит плагин xcb хотя папка plstforms/ присутствует в пвпке программы. пробовал использовать ключ -qt-xcb при конфигурировании Qt, ругается.
Note: Using static linking will disable the use of dynamically
loaded plugins. Make sure to import all needed static plugins,
or compile needed modules into the library.

Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.

WARNING: QDoc will not be compiled, probably because libclang could not be located. This means that you cannot build the Qt documentation.

Either ensure that llvm-config is in your PATH environment variable, or set LLVM_INSTALL_DIR to the location of your llvm installation.
On Linux systems you may be able to install libclang from a package. On macOS you could use Homebrew's llvm package.
On Windows you need to set LLVM_INSTALL_DIR to the installation path.

ERROR: Feature 'xcb' was enabled, but the pre-condition 'features.thread && features.xkbcommon && libs.xcb' failed.

Check config.log for details.
Написано, что при статической сборке запрещено использование динамически загружаемых плагинов, но как их запихать туда статически я не понимаю. Попробовал в файле проекта LIBS += -L/usr/lib/x86_64-linux-gnu -llibxcb

пишет : ошибка: cannot find -llibxcb, [jnz afqk libxcb.a присутствует в данном месторасположении.

Honey12345 ()
Ответ на: Статическая сборка. от Honey12345

Сейчас в Qt какие-то изменения со статической линковкой, поэтому такие сложности.

Попробуй добавить в main.cpp конструкцию:

#include <QtPlugin>
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)

Возможно поможет. При статической линковки твоё приложение не должно зависеть от каких-либо Qt-шных *.so-плагинов или библиотек.

Где-то у тебя ошибка.

P.S. в проектном *.pro файле должны быть директивы вида:

QT += core gui
QTPLUGIN.platforms = qminimal qxcb
CONFIG -= import_plugins
CONFIG += static

Для твоей Linux-сборки.

EXL ★★★★★ ()
Последнее исправление: EXL (всего исправлений: 3)
Ответ на: Статическая сборка. от Honey12345

С самыми последними кутями дела не имел. Я бы рассмотрел возможность взять пока версию постарше (если тебе не нужны кровь-из-носу самые распоследние плюшки) либо вернулся к вопросу об использовании системных либ (но это если у тебя определён набор дистрибутивов, с которыми работает твоя программа).

С первым вариантом как? Что-то мешает?

hobbit ★★★★★ ()
Ответ на: комментарий от hobbit

Вобщем попробовал варианты от EXL, не пашет потомучто в статической сборке Qt нет статически собранных плагинов xcb.

user@kubuntuit01:~/MyProject/Qt5_static/plugins/platforms$ ls -al
итого 1840
drwxr-xr-x  2 user пользователи домена    4096 мар 14 14:26 .
drwxr-xr-x 24 user пользователи домена    4096 мар 18 17:03 ..
-rw-r--r--  1 user пользователи домена  155762 мар 12 16:30 libqlinuxfb.a
-rw-r--r--  1 user пользователи домена    1793 мар 14 14:26 libqlinuxfb.prl
-rw-r--r--  1 user пользователи домена   49170 мар 12 16:30 libqminimal.a
-rw-r--r--  1 user пользователи домена    1658 мар 14 14:26 libqminimal.prl
-rw-r--r--  1 user пользователи домена  122518 мар 12 16:30 libqoffscreen.a
-rw-r--r--  1 user пользователи домена    1746 мар 14 14:26 libqoffscreen.prl
-rw-r--r--  1 user пользователи домена  176456 мар 12 16:30 libqvnc.a
-rw-r--r--  1 user пользователи домена    1755 мар 14 14:26 libqvnc.prl
-rw-r--r--  1 user пользователи домена 1337156 мар 12 16:40 libqwebgl.a
-rw-r--r--  1 user пользователи домена    1730 мар 14 14:26 libqwebgl.prl

Развернул виртуалку завтра попробую сконфигурить статически Qt с ключом -qt-xcb

какую версию Qt лучше использовать, посоветуйте 5.5 или 5.9

Honey12345 ()
Ответ на: комментарий от Honey12345

какую версию Qt лучше использовать, посоветуйте 5.5 или 5.9

https://wiki.qt.io/New_Features_in_Qt_5.6
https://wiki.qt.io/New_Features_in_Qt_5.7
https://wiki.qt.io/New_Features_in_Qt_5.8
https://wiki.qt.io/New_Features_in_Qt_5.9
Если не нужно ничего из перечисленного и исправленные/внесенные баги от 5.5 к 5.9 не словил, то 5.5 )

x905 ★★★★★ ()
Ответ на: комментарий от Honey12345

Qt5.x.x Статическая сборка.

короче разобрался я со статической сборкой. Собрал на Debian8, Ubuntu16 и на рабочей машине с ubuntu18. Сборки с машин со старыми ОС на новых работают без проблем, наоборот нужно доинсталлировать дополнительные пакеты, не хватает библиотек некоторых. Проблема с моей ошибкой выше решалась просто, configure анализируя систему почему то не видел библиотеки xcb, нужно было в явную указать путь к ней при запуске configure и все замечательно собралось

$ ./configure -platform linux-g++ -release -static -opensource -confirm-license -nomake examples -nomake tests -no-openssl -skip qtwebengine -c++std c++14 -nomake tests -qt-zlib -qt-libpng -qt-libjpeg -opengl desktop -qt-xcb -I /usr/include/xcb/ -L /usr/lib/x86_64-linux-gnu/  -fontconfig -sql-psql -prefix ~/MyProject/Qt5_static

Тренируясь на виртуалках написал инструкцию, протоколируя свои действия, для Debian8 и Ubuntu. Может кому пригодится. Использовал Qt5.9.5 и Qt5.12.1
[cut]
>>>
Qt5.x.x статическая сборка Debian8, Ubuntu16,Ubuntu18
Мой проект использует GUI и работает с БД postgresql
Настройка статической сборки на Debian 8, Ubuntu 16.04.LTS, Ubuntu 18.04.2 LTS
Использовалась версия Qt 5.9.5 на Debian 8, Ubuntu 18 и Qt 5.12.1 на Ubuntu 18


1. Разворачиваем новую виртуальную машину с нужной ОС, обновляем систему:
	$ sudo apt-get update
	$ sudo apt-get upgrade

2. Для сборки статических библиотек проверяем установку следующих пакетов если не стоят доставляем:

	libfontconfig1-dev
	libfreetype6-dev
	libx11-dev
	libxext-dev
	libxfixes-dev
	libxi-dev
	libxrender-dev
	libxcb1-dev
	libx11-xcb-dev
	libxcb-glx0-dev
	libxkbcommon-dev

	$ sudo apt-get install libfontconfig1-dev libfreetype6-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev libxkbcommon-dev


3. Ставим пакеты для postgresql:

	libpq-dev
	postgresql-client
	postgresql-contrib

	$ sudo apt-get install libpq-dev postgresql-client postgresql-contrib

4. Ставим пакеты для opengl-desktop:

	libgl1-mesa-dev

	$ sudo apt-get install libgl1-mesa-dev

5. На Debian 8 пришлось установить пакет build-essential

	$ sudo apt-get install build-essential


6. Копируем в папку в домашней директории ( я копировал в Downloads, кстати на Debian я скопировал в Загрузки и словил проблемму, поэтому используем названия папок на англ. языке)
файл для установки Qt (qt-opensource-linux-x64-5.12.1.run / qt-opensource-linux-x64-5.9.5.run) и архив с исходниками Qt (qt-everywhere-src-5.12.1-tar.xz / qt-everywhere-opensource-src-5.9.5.tar.xz)
	
	Устанавливаем Qt (при установке я выбирал Desktop gcc 64 bit, Sources, Tools (по умолчанию qtcreator), остальное мне было не нужно)

	$ ./qt-opensource-linux-x64-5.x.x.run

	На Debian 8 пришлось править пути к Qt в файле /usr/lib/x86_64-linux-gnu/qt-default/qtchooser/default.conf
	прописываем путь к Qt (куда вы установили )
		/home/user/Qt5.9.5/5.9.5/gcc_64/bin
		/home/user/Qt5.9.5/5.9.5/gcc_64/lib
	после этого проверяем в консоле $ qmake --version

7. Распаковываем архив с исходниками

	$ tar xJf qt-everywhere-src-5.12.1-tar.xz

8. Переходим в папку с исходниками

	$ cd qt-everywhere-src-5.12.1-tar.xz/

9. Выполняем конфигурирования исходников Qt5.x.x для static сборки.
	$ ./configure -platform linux-g++ -release -static -opensource -confirm-license -nomake examples -nomake tests -no-openssl -skip qtwebengine -c++std c++14 -nomake tests -qt-zlib -qt-libpng -qt-libjpeg -opengl desktop -qt-xcb  -fontconfig -sql-psql -prefix ~/MyProject/Qt5_static
	
	Если все нормально то в конце не будет ошибок. Но на рабочей машине и на виртуалке с 18 убунтой у меня возникли ошибки
	ERROR: Feature 'xcb' was enabled, but the pre-condition 'features.thread && features.xkbcommon && libs.xcb' failed.
	ERROR: Feature 'psql' was enabled, but libs.psql' failed. при этом все библиотеки были установлены. Проблемы решились с
	помощью явного указания пути к заголовочным файлам и библиотекам при запуске configure.
	Для lib.psql:  -sql-psql -I /usr/include/postgresql/ -L /usr/lib/postgresql/9.6/lib/
	Для lib.xcb :  -qt-xcb -I /usr/include/xcb/ -L /usr/lib/x86_64-linux-gnu/

10. Собираем проект
  
	$ make j5		// j5 - количество ядер +1
	$ make install

11. Запускаем QtCreator идем в инструменты->параметры, настраиваем новый профиль со статическим qmake (указываем путь к собранному нами qmake ~/MyProject/Qt5_static/bin/qmake),
тут же в параметрах добавляем комплект с этим профилем.

12. Дедаем новый пустой проект и проверяем.
	
<<<
[/cut]
Honey12345 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.