Кросс-QT (4/5) приложение.
От: DirtyGarry  
Дата: 21.08.21 12:39
Оценка:
Добрый день.

Есть простое приложение на QT. Собирается как на QT4, так и на QT5 из одних и тех же исходников.

Хочется собрать это приложение для Linux так, чтобы оно работало независимо от того, какая версия библиотеки QT (4 или 5) установлена на машине.

Можно ли
1. это ли сделать какими-то стандартными способами (как хитро скомпоновать или, возможно, у QT есть какие-то собственные средства)?
2. грузить необходимые библиотеки QT динамически самому? Т.е. если установлена библиотека QT5, загружаем ее, если QT4, то ее.

Спасибо
Re: Кросс-QT (4/5) приложение.
От: Bill Baklushi СССР  
Дата: 21.08.21 12:47
Оценка: 2 (1)
DirtyGarry:

DG>Есть простое приложение на QT. Собирается как на QT4, так и на QT5 из одних и тех же исходников.

DG>Хочется собрать это приложение для Linux так, чтобы оно работало независимо от того, какая версия библиотеки QT (4 или 5) установлена на машине.
DG>Можно ли
DG>1. это ли сделать какими-то стандартными способами (как хитро скомпоновать или, возможно, у QT есть какие-то собственные средства)?
Использовать только те средства, которые есть в обеих версиях + использовать условную компиляцию.
Если нужно чтобы бинарник легко переносился, можно слинковать с Qt статически (AFAIK, нужна статическая сборка Qt).

DG>2. грузить необходимые библиотеки QT динамически самому? Т.е. если установлена библиотека QT5, загружаем ее, если QT4, то ее.


Что значит грузить? Qt инсталлируется стандартными средствами, типа apt.
А в рантайме обычно никаких инициализаций не нужно (за исключением может быть, пути к Qt-плагинам, если они используются).
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re[2]: Кросс-QT (4/5) приложение.
От: DirtyGarry  
Дата: 21.08.21 13:16
Оценка:
Здравствуйте, Bill Baklushi, Вы писали:

BB>Если нужно чтобы бинарник легко переносился, можно слинковать с Qt статически (AFAIK, нужна статическая сборка Qt).


Спасибо, попробую. Но для меня очень критичен размер получаемого исполняемого файла (чем меньше, тем лучше).

BB>Что значит грузить? Qt инсталлируется стандартными средствами, типа apt.

BB>А в рантайме обычно никаких инициализаций не нужно (за исключением может быть, пути к Qt-плагинам, если они используются).

Я хотел использовать динамическую компоновку: один раз собрать приложение, а необходимые библиотеки QT (4 или 5) загружать динамически (с помощью dlopen, dlsym).
Re: Кросс-QT (4/5) приложение.
От: K13 http://akvis.com
Дата: 21.08.21 13:31
Оценка: 1 (1) +6
DG>Хочется собрать это приложение для Linux так, чтобы оно работало независимо от того, какая версия библиотеки QT (4 или 5) установлена на машине.

Почти невозможно.

QWidget *q = new QWidget;

требует знать размер QWidget в байтах во время компиляции.
но qt4/qt5 -- не совпадают.

попытка обойти это приведет к раздуванию кода до безобразия.
т.е. нельзя будет просто позвать функцию Qt или метод объекта -- надо будет все заворачивать через макрос, который будет перенаправлять на адрес вызова, полученый через resolve, и тут вылезет еще одна проблема -- список DLL (и в каком моуле искать функцию) у 4 и 5 не совпадают.

нельзя будет использовать автосгенеренные ui_*.cpp, moc_*.cpp -- потому что там генерится код, дергающий методы напрямую.
либо имитировать их содержимое руками, либо править исходники moc.exe / uic.exe

и самое главное -- ЗАЧЕМ? проще иметь два скомпиленных бинарника, и если очень нужно -- маленький лоадер, который проверяет наличие версий кути и запускает подходящий вариант.
Re[3]: Кросс-QT (4/5) приложение.
От: Bill Baklushi СССР  
Дата: 21.08.21 14:31
Оценка:
DirtyGarry:

BB>>Если нужно чтобы бинарник легко переносился, можно слинковать с Qt статически (AFAIK, нужна статическая сборка Qt).


DG>Спасибо, попробую. Но для меня очень критичен размер получаемого исполняемого файла (чем меньше, тем лучше).

Для спасибо есть соответствующая кнопка.

BB>>Что значит грузить? Qt инсталлируется стандартными средствами, типа apt.

BB>>А в рантайме обычно никаких инициализаций не нужно (за исключением может быть, пути к Qt-плагинам, если они используются).

DG>Я хотел использовать динамическую компоновку: один раз собрать приложение, а необходимые библиотеки QT (4 или 5) загружать динамически (с помощью dlopen, dlsym).

Не вижу в этом никакого смысла.

И не так это работает. dlopen и dlsym вызываются системой при старте процесса. замаешься, чтобы все вызовы переделать на динамические.

Проще или статически собрать или указать в дистре зависимость от определенных пакетов Qt.

Или можно создать один snap-пакет и напихать туда все зависимости (Я в снапах не силён, подробностей не знаю).
Модератор-националист Kerk преследует оппонентов по политическим мотивам.
Re: Кросс-QT (4/5) приложение.
От: Zhendos  
Дата: 21.08.21 18:30
Оценка: +1
Здравствуйте, DirtyGarry, Вы писали:

DG>Хочется собрать это приложение для Linux так, чтобы оно работало независимо от того, какая версия библиотеки QT (4 или 5) установлена на машине.

DG>Можно ли
DG>1. это ли сделать какими-то стандартными способами (как хитро скомпоновать или, возможно, у QT есть какие-то собственные средства)?
DG>2. грузить необходимые библиотеки QT динамически самому? Т.е. если установлена библиотека QT5, загружаем ее, если QT4, то ее.

Они бинарно несовместимы, в этом как раз одна из причин изменения мажорной версии.
В рамках одной версии они гарантируют что ABI не сломается и поэтому
для избавления от кучи накопленных костылей из-за того что ABI нельзя ломать
нужно время от времени все сломать.
Re: Кросс-QT (4/5) приложение.
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 21.08.21 18:39
Оценка:
Здравствуйте, DirtyGarry, Вы писали:

DG>Хочется собрать это приложение для Linux так, чтобы оно работало независимо от того, какая версия библиотеки QT (4 или 5) установлена на машине.


Можно с помощью ldd посмотреть какие у приложения зависимости и запихнуть все эти библиотеки в установочник так же как на винде. Есть всякие appimage, run и прочие. Лично я бы не рекомендовал заниматься попыткой совместить разные старшии версии и даже младшие версии Qt.

BB>Если нужно чтобы бинарник легко переносился, можно слинковать с Qt статически (AFAIK, нужна статическая сборка Qt).

DG>Спасибо, попробую. Но для меня очень критичен размер получаемого исполняемого файла (чем меньше, тем лучше).

Статически слинкованное приложение занимает меньше места, чем динамически слинкованное вместе со всеми библиотеками. Но по мне всё это бессмысленно, самый простой способ слинковать всё динамически чтобы не компилировать сам Qt, потом запихнуть это в пакет установки или запуска, а дальше пользователь пусть устанавливает это в папку /opt.

Наиболее встречающиеся подходы, которые работают:
1) Приложение в обычном архиве, которое предлагают разархивировать в ту же папку /opt или ещё куда. Внутри файл запуска ./myapp и папка ./bin в которой находятся динамические библиотеки so, например, ./bin/libQt5Gui.so.5. То есть приложение понимает, что либы лежат в ./bin. Наглядный пример android-studio, anki.
2) Ещё один популярный способ создать установщик run. Используется для установки той же библиотеки Qt, драйверов NVidia и многих других.
3) Можно воспользоваться AppImage. Используется в том же FreeCAD.

Теперь поговорим о разных извращениях:
1) Раньше Skype использовал deb, всё бы ничего, но в новой версии появилось ограничение на зависимость. В общем хочешь проблем себе и пользователям делай как Skype.
2) Потом когда Skype перестал нормально обновляться я воспользовался альтернативным методом, который предлагал Skype.
snap install core
snap install skype

Ну, такое себе.

А как всё это реализовать можно найти послав поисковый запрос в гугле, яндексе и так далее.
Re: Кросс-QT (4/5) приложение.
От: Pzz Россия https://github.com/alexpevzner
Дата: 22.08.21 20:25
Оценка: 3 (1)
Здравствуйте, DirtyGarry, Вы писали:

DG>Можно ли

DG>1. это ли сделать какими-то стандартными способами (как хитро скомпоновать или, возможно, у QT есть какие-то собственные средства)?
DG>2. грузить необходимые библиотеки QT динамически самому? Т.е. если установлена библиотека QT5, загружаем ее, если QT4, то ее.

Qt — довольно капризный зверек. Даже если программа собрана с некоторой версией, а на системе установлена та же версия, но собранная с немного другими опциями, может получиться так, что программа запускается, но глючит. Например, чего-нибудь неправильно прорисовывается.

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

Но чисто теоретически, я бы решал эту проблему следующим образом. Я бы вынес все взаимодействие с Qt в отдельную динамическую библиотеку, собрал бы две версии этой библиотеки, под разные Qt, и нужную из них динамически грузил.
Re[2]: Кросс-QT (4/5) приложение.
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 22.08.21 21:58
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Но чисто теоретически, я бы решал эту проблему следующим образом. Я бы вынес все взаимодействие с Qt в отдельную динамическую библиотеку, собрал бы две версии этой библиотеки, под разные Qt, и нужную из них динамически грузил.


Проблема вопроса топика в том, что в нём заложен ответ.

1) Во-первых, не нужны несколько версий Qt, нужна только одна, или Qt 4.8.7 как последняя 4-ая версия, или последующие, если это 5, то можно взять одну из LTS. Вот здесь можно посмотреть историю версий:
https://en.wikipedia.org/wiki/Qt_version_history
Лично я по некоторым причинам для опытов пока использую 5.9 LTS (5.9.9), но есть и более поздние LTS. По сравнению с 4.8.7 использование 5 версии позволяет мне ещё создавать приложения для Android простой перекомпиляцией в связке с Android Studio.

2) Во-вторых, да никто так не делает, не занимаются люди подгрузкой непонятно чего. Я на GNU/Linux где-то с 2008 года или что-то около того, может даже раньше, там сторонние приложения просто тащат за собой все библиотеки. Говорят проблемы могут возникнуть лишь при переходе с одного ядра Linux на другое и только, если ядро ну очень устарело. А так всё как в винде скопировал и работает, разве что разработчики указывают где лежат поставляемые с программой библиотеки. Думаю нужно только разобраться как это лучше делать, а вариантов там несколько.

3) И я напоминаю, что Qt это мощный кроссплатформенный фреймворк, это не какая-то мелка либа взаимодействие с которой можно скрывать за интерфейсами. Конечно, ничто не истина, всё дозволено, но это даже не подмена на другой фреймворк, а просто попытка работать с разными версиями Qt. Зачем? Для чего? А потому что вопрос вот так звучал, вот зачем.

На самом деле автором топика не было предоставлено никаких данных о том, сколько должна занимать программа, сколько памяти на устройстве и так далее, так что никакой экономии и не будет. А речь напомню в среднем о нескольких мегабайтах на модуль Qt. В наше время страницы в браузере порой занимают больше.

Забудь об авторе топика. Неужели ты бы реально стал прятать за интерфейсы код взаимодействия c Qt? Я вообще сомневаюсь, что у нормального человека возникла бы идея пытаться поддерживать несколько версий Qt.
Re[3]: Кросс-QT (4/5) приложение.
От: Pzz Россия https://github.com/alexpevzner
Дата: 22.08.21 22:08
Оценка:
Здравствуйте, velkin, Вы писали:

V>2) Во-вторых, да никто так не делает, не занимаются люди подгрузкой непонятно чего. Я на GNU/Linux где-то с 2008 года или что-то около того, может даже раньше, там сторонние приложения просто тащат за собой все библиотеки.


И это раздражает, кстати. Гораздо приятнее, когда программа собрана под мою родную федору (или под чью-то родную убунту, тут каждому свое), и пользуется "удобствами", прилагаемыми к системе, а не тащет свои.

V>Говорят проблемы могут возникнуть лишь при переходе с одного ядра Linux на другое и только, если ядро ну очень устарело.


Очень редко.

V>На самом деле автором топика не было предоставлено никаких данных о том, сколько должна занимать программа, сколько памяти на устройстве и так далее, так что никакой экономии и не будет. А речь напомню в среднем о нескольких мегабайтах на модуль Qt. В наше время страницы в браузере порой занимают больше.


У народа странное отношение к памяти. Иногда ее экономят, когда не надо, а иногда не экономят, когда надо.

Но тут обоснование может быть не техническое, а психологическое. С ним сложнее всего, на чисто техническом уровне всегда можно найти какой-то разумный компромис.

V>Забудь об авторе топика. Неужели ты бы реально стал прятать за интерфейсы код взаимодействия c Qt? Я вообще сомневаюсь, что у нормального человека возникла бы идея пытаться поддерживать несколько версий Qt.


Нет, я бы вынес в отдельный модуль работу с гуйней (предполагаю, что Qt используется именно для этого, а не в качестве фреймворка общего назначения) и сделал бы у этого модуля высокоуровневый интерфейс, а внутренности Qt из него наружу бы не тащил.
Re[4]: Кросс-QT (4/5) приложение.
От: velkin Удмуртия http://blogs.rsdn.org/effective/
Дата: 22.08.21 22:29
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>И это раздражает, кстати. Гораздо приятнее, когда программа собрана под мою родную федору (или под чью-то родную убунту, тут каждому свое), и пользуется "удобствами", прилагаемыми к системе, а не тащет свои.


Так не проблема, но тогда разработчику программы придётся собирать пакет под каждую операционку с её версией. Но лично я вполне доволен программами находящимися у меня в папке opt, которые притащили за собой все библиотеки. На винде я на это не жалуюсь, а там ведь происходит тоже самое.

Pzz>У народа странное отношение к памяти. Иногда ее экономят, когда не надо, а иногда не экономят, когда надо.


Если это древний десктоп, то память в данном случае экономить не нужно. Если это старый смартфон, какой-нибудь Android 4, тоже самое. Raspberry Pi, да даже первая версия в данном сценарии зверь, а не машина. Вот вот, сначала люди грузят виртуальные машины, потом хоба, им помешала библиотека C++. Как тут любят ставить смайлик рука лицо.

Там основные модули, ядро, графика, виджеты и база данных не дотягивают даже до 20 мегабайт, ещё добавить сеть и как раз будет столько. А другие модули вообще копеечные. Ну ладно, там ещё всякие вспомогательные либы C++, ещё добавим докучи модулей, которые весят по 1-2 мегабайта. Что, 30-40 мегабайт в оперативной памяти? Так что это всё фантазии про экономию. Более того, прироста производительности от иных действий ожидать не приходится.

Pzz>Нет, я бы вынес в отдельный модуль работу с гуйней (предполагаю, что Qt используется именно для этого, а не в качестве фреймворка общего назначения) и сделал бы у этого модуля высокоуровневый интерфейс, а внутренности Qt из него наружу бы не тащил.


Для меня по крайне мере сам Qt не подлежит закрытию интерфейсами, так как по сути это и есть само приложение. То, что к нему подключается можно обёртывать, интерфейсами Qt проходящими через MOC, теми же плагинами опять же живущими за счёт того же MOC, но не сам Qt. Как бы меня не коробили имена функций Qt, никакого делегирования я бы уж точно не делал.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.