Приложение на Qt5#
Пример собирает Qt5-приложение из исходников и доводит его до установленного и работающего Flatpak. Программа написана здесь же, поэтому пример повторяется целиком, без скачивания чего-либо со стороны.
Qt5-приложения работают на среде org.astra.Qt. Она несёт весь Qt5:
libqt5core5a, libqt5gui5, libqt5widgets5, libqt5network5,
libqt5svg5, мультимедиа и плагины платформ. Приложение не тащит Qt с собой,
поэтому сборка получается небольшой.
Подготовка#
Понадобятся среда выполнения и SDK одной версии:
sudo flatpak install astra-main org.astra.Qt//1.8.6
sudo flatpak install astra-extended org.astra.qtSdk//1.8.6
Дерево примера#
Всё лежит в одном каталоге:
qt5-hello/
|-- qt5-hello.yaml
`-- src/
|-- CMakeLists.txt
|-- main.cpp
|-- ru.example.Qt5Hello.desktop
|-- ru.example.Qt5Hello.metainfo.xml
`-- icons/
`-- 128x128/
`-- app.png
Имя файла иконки роли не играет: при сборке иконки переименовываются в
идентификатор приложения. Достаточно положить любой PNG размером 128 на 128 в
каталог icons/128x128.
Исходный код#
src/main.cpp:
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QLabel label("Qt5 внутри Flatpak");
label.setAlignment(Qt::AlignCenter);
label.resize(360, 120);
label.setWindowTitle("Qt5 Hello");
label.show();
return app.exec();
}
src/CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(qt5-hello LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
find_package(Qt5 REQUIRED COMPONENTS Widgets)
add_executable(qt5-hello main.cpp)
target_link_libraries(qt5-hello PRIVATE Qt5::Widgets)
install(TARGETS qt5-hello RUNTIME DESTINATION bin)
src/ru.example.Qt5Hello.desktop:
[Desktop Entry]
Type=Application
Name=Qt5 Hello
Name[ru]=Пример на Qt5
Comment=Минимальное приложение на Qt5
Exec=qt5-hello
Icon=qt5-hello
Terminal=false
Categories=Utility;
Значение Icon при сборке заменяется на идентификатор приложения, а
абсолютный путь в Exec сокращается до имени команды, поэтому подгонять их
вручную не нужно.
src/ru.example.Qt5Hello.metainfo.xml:
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>ru.example.Qt5Hello</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>MIT</project_license>
<name>Qt5 Hello</name>
<summary>Минимальное приложение на Qt5</summary>
<description>
<p>Пример приложения на Qt5 для проверки сборки во Flatpak.</p>
</description>
<launchable type="desktop-id">ru.example.Qt5Hello.desktop</launchable>
</component>
Манифест#
qt5-hello.yaml:
version: "1.0"
metadata:
id: ru.example.Qt5Hello
name: "Qt5 Hello"
version: "1.0"
arch: amd64
branch: stable
runtime:
id: org.astra.Qt
version: "1.8.6"
sdk: org.astra.qtSdk
source:
type: sourcedir
sourcedir:
path: ./src
buildDeps:
packages:
- qtbase5-dev
- cmake
buildCommands:
- cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/app -DCMAKE_BUILD_TYPE=Release
- cmake --build build -j
- cmake --install build
files:
command: qt5-hello
desktop: ./src/ru.example.Qt5Hello.desktop
metainfo: ./src/ru.example.Qt5Hello.metainfo.xml
icons-dir: ./src/icons
permissions:
sockets: [wayland, fallback-x11]
devices: [dri]
shares: [ipc]
persist: [.config]
export:
repository: ./repo
Команды сборки выполняются внутри песочницы SDK, в каталоге, куда примонтирован
source.sourcedir.path. Рабочим каталогом становится он же, поэтому пути в
командах относительные. Сборочные зависимости из buildDeps подкладываются
отдельным сысрутом, а пути к ним прописываются в CMAKE_PREFIX_PATH,
PKG_CONFIG_PATH, CPATH и LIBRARY_PATH автоматически.
Сборка и установка#
cd qt5-hello
aft-app validate qt5-hello.yaml
sudo aft-app build qt5-hello.yaml
Готовое лежит в ./repo. Установка на этой же машине:
sudo flatpak remote-add --if-not-exists --no-gpg-verify local-repo ./repo
sudo flatpak install -y local-repo ru.example.Qt5Hello
flatpak run ru.example.Qt5Hello
Ключ --no-gpg-verify уместен только для проверки у себя. Для раздачи
пользователям репозиторий подписывается, как описано в разделе
Репозиторий вендора.
Проверка:
aft-analyzer ru.example.Qt5Hello
Если поставка приходит пакетом#
Готовый deb от поставщика собирается тем же способом, меняется только секция источника. Зависимости разбираются по составу самого пакета, поэтому его не обязано быть в подключённых репозиториях:
source:
type: local
local:
path: ./vendor-qt-app_2.4.0_amd64.deb
additionalPaths:
- ./vendor-qt-libs_2.4.0_amd64.deb
dependencies:
additional: [libqt5sql5-sqlite]
Команду запуска в этом случае берут из desktop-файла внутри пакета, а поля
files.desktop, files.metainfo и files.icons-dir можно не указывать:
если они есть в пакете, aft-app найдёт их сам.
Для пакета из репозитория Astra секция ещё короче:
source:
type: repository
repository:
package: kcalc
Тонкости Qt5#
Плагин платформы Qt выбирает сам. Для Wayland нужны и сокет wayland, и
fallback-x11: часть программ не умеет Wayland и завершается без запасного
варианта.
Настройки Qt пишет в ~/.config, поэтому каталог перечисляется в
permissions.persist. Без этого настройки теряются между запусками.
Приложениям с базой SQLite нужен драйвер libqt5sql5-sqlite: в среду он не
входит и попадает в сборку, только если объявлен зависимостью пакета или
дописан в dependencies.additional.
Стиль оформления и тема берутся из среды, а не с хоста. Если приложение
выглядит непривычно, обычно не хватает пакета стиля, и он докладывается тем же
dependencies.additional.