Pull to refresh
0

Кроссплатформенное приложение на Qt: Распространение

Reading time6 min
Views34K
Сборка дистрибутива — завершающий этап подготовки программы к выходу в свет. К сожалению, ни о какой стандартизации в этой области речи не идет, более того, на некоторых ОС (не будем показывать пальцем), так вообще целый зоопарк форматов.

Итак, в идеале нам нужны дистрибутивы:
  • Windows
  • OS X (.dmg)
  • OS X (.pkg — App Store)
  • Linux (.deb)
  • Linux (.rpm)
  • Linux (.tar.gz — universal)

Qt Installer Framework


Справедливости ради стоит отметить, что Qt имеет свой, разумеется кроссплатформенный, фреймворк для создания установщиков. Он позволяет создавать как обычные, так и online инсталлеры, способные докачивать дополнительные компоненты из репозитория. Также есть возможность вставлять свои виджеты, добавлять новые действия (страницы). Вы наверняка устанавливали Qt Creator, а значит видели эту систему в работе. Однако при создании установщика приходится писать xml конфиг, работать с ключами в командной строке, в общем настройка имеет довольно высокий порог вхождения, особенно по сравнению с другими решениями. При этом я так и не нашел в документации упоминания о том, как пропустить страницу выбора компонентов. В общем получился весьма специфичный продукт, минус которого еще и в том, что такой способ установки считается родным только на Windows платформе.

Windows


Соответственно и вариантов создания установщиков для этой ОС масса, но я остановился на довольно удобном open source продукте — Inno setup. Создание инсталлера в нем не сложнее, чем собственно установка «далее-далее-готово».


После прохождения мастера создания, на выходе получаем скрипт, который можно легко поменять под следующие версии своей программы.

Linux


Исторически сложилось, что софт под Linux распространяется через репозитории, причем дистрибутив каждой программы представляет собой пакет специального вида, содержащий собственно файлы программы, информацию о зависимостях, и некоторые другие метаданные. Несмотря на все попытки стандартизации, кроме мейнстримовых .deb и .rpm существует множество других форматов, специфичных для отдельных дистрибутивов Linux. Canonical экспериментирует с форматом .click, напоминающим бандлы приложений в OS X, но на сегодня рассматривать этот вариант в числе основных пока преждевременно. Раз уж Ubuntu де-факто стандарт Линукса на десктопе, я буду описывать создание пакетов именно на этой платформе. Также следует отметить, что чаще всего дистрибутив стороннего ПО несет с собой все необходимое для функционирования, потому продвинутые возможности пакетной системы остаются незадействованными.

.tar.gz

Что общего между дистрибутивами? Конечно командная оболочка! Значит будем делать скриптовый установщик, который запустится на любой системе, вне зависимости от предполагаемого формата пакетов. Для того, чтобы система «увидела», что установлена новая программа, каждый файл должен занять положенное место. Минимальный набор состоит из: иконки, исполняемого файла, и специального конфига с расширением .desktop

Иконка: Согласно спецификации, Linux не требует преобразовывать исходники иконки в какие-либо сборки, нужно просто скопировать (при установке) файлы в поддиректории вида:
/usr/share/icons/hicolor/RxR/apps, где R — разрешение иконки
или
/usr/share/icons/hicolor/scalable/apps — если вы хотите установить векторное изображение в формате .svg
Однако это еще не все, каждая тема иконок имеет свой кэш, и если его не обновить — увидеть новую иконку не получится. Кэш автоматически обновляется при штатной установке пакетов, либо можно сделать это вручную, выполнив команду:
gtk-update-icon-cache /usr/share/icons/hicolor
Исполняемый файл
/usr/bin
Конфигурационный файл .desktop
/usr/share/applications
содержит всю информацию о программе — название и описание приложения, его категория, название иконки и т.д.

Для примера:
[Desktop Entry]
Name=iStodo
Comment=iStodo is an organizer for students with scheduling and planning features.
GenericName=Organizer for students
Exec=istodo
Icon=istodo
Categories=Office;Qt;
Terminal=false
Type=Application
Version=1.2
Name[ru]=Органайзер iStodo
Comment[ru]=Составление расписания и планирование учебы
GenericName[ru]=Органайзер для студентов

Узнать больше можно прочитав стандарт.

Правилом хорошего тона при установке сторонних программ с нестандартным способом установки будет хранение всех своих файлов в подкаталоге /opt/myapp, куда в том числе следует положить и деинсталлер.

Итак, в итоге у меня получился следующий скрипт, который полагает, что рядом с ним лежит бинарник, файл .desktop, скрипт на удаление, папка с иконками(в ней подкаталоги по размерам):
install.sh
#!/bin/bash

iconsPath="/usr/share/icons/hicolor"
desktopPath="/usr/share/applications" 
installPath="/opt/myapp"
linkPath="/usr/bin/myapp"

#Check user
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root"
    exit 1
fi

#Remove old version
if [ -d $installPath ]; then
    $installPath'/uninstall.sh' > /dev/null   
fi
    
echo "myapp install..."
mkdir -v $installPath
cp -v myapp $installPath
cp -v uninstall.sh $installPath
cp -v myapp.desktop $desktopPath
ln -sv $installPath'/myapp' $linkPath
chmod a+x $linkPath
echo "---"
cp -v icons/32x32/myapp.png $iconsPath'/32x32/apps'
cp -v icons/48x48/myapp.png $iconsPath'/48x48/apps'
cp -v icons/64x64/myapp.png $iconsPath'/64x64/apps'
cp -v icons/128x128/myapp.png $iconsPath'/128x128/apps'
cp -v icons/256x256/myapp.png $iconsPath'/256x256/apps'
gtk-update-icon-cache /usr/share/icons/hicolor
update-desktop-database

echo "...finished!"

Логично, что потребуется и скрипт для удаления программы:
uninstall.sh
#!/bin/bash

iconsPath="/usr/share/icons/hicolor"
desktopPath="/usr/share/applications" 
installPath="/opt/myapp"
linkPath="/usr/bin/myapp"
echo "myapp uninstall"

#Check user
if [[ $EUID -ne 0 ]]; then
    echo "This script must be run as root"
    exit 1
fi

rm -v $iconsPath'/32x32/apps/myapp.png'
rm -v $iconsPath'/48x48/apps/myapp.png'
rm -v $iconsPath'/64x64/apps/myapp.png'
rm -v $iconsPath'/128x128/apps/myapp.png'
rm -v $iconsPath'/256x256/apps/myapp.png'
rm -v $desktopPath'/myapp.desktop'

#Remove app folder
echo "---"
rm -rfv $installPath
rm -v  $linkPath

echo "Uninstall finished!"

.deb

Несмотря на пугающе-монструозные спецификации формата, для создания простейшего пакета требуется всего один конфигурационный файл — control. Но для начала нам нужно провести некоторые приготовления:
a) Создать папку проекта, с указанием версии программы и пакета, например myapp-1.1-1
b) В нее добавить папку DEBIAN (регистр важен!), в которой будут находиться все служебные файлы, в частности control
Пример для control
Package: istodo
Version: 1.2-1
Section: misc
Architecture: amd64
Installed-Size: 16500
Maintainer: Yakov Eremin <support@istodo.ru>
Description: Organizer for students
 iStodo is an organizer for students with scheduling and planning features.
Тут все очевидно, нужно только заметить, что полное описание начинается с пробела
c) Создать структуру каталогов, повторяющую положение файлов установленной программы в файловой системе, нечто вроде

myapp-1.1-1
├── DEBIAN
│   └── control
└── usr
    ├── bin
    │   └── myapp
    └── share
        ├── applications
        │   └── myapp.desktop
        └── icons
            └── hicolor
                ├── 128x128
                │   └── apps
                │       └── myapp.png
                ├── 256x256
                │   └── apps
                │       └── myapp.png
                ├── 32x32
                │   └── apps
                │       └── myapp.png
                ├── 48x48
                │   └── apps
                │       └── myapp.png
                └── 64x64
                    └── apps
                        └── myapp.png

Для того, чтобы создавать пакеты не поднимая привилегии до суперпользователя, стоит воспользоваться утилитой fakeroot, эмулирующей соответствующее окружение.

Ну и собираем пакет командой:
fakeroot dpkg-deb --build myapp-1.1-1/

Если вам требуются дополнительные возможности, тут можно почитать подробный обзор.

.rpm

Как говорится, есть два способа — простой и правильный.
Простой: если .deb пакет не содержит зависимостей и скриптов, то можно просто сконвертировать его, в результате наверняка получится корректно работающий пакет формата .rpm. Для этого предназначена утилита alien, которую можно установить из репозитория.
fakeroot alien -kr myapp-1.0-1.deb

Минусом такого подхода является неработоспособность пакетов на Fedora 18 и более поздних. Насколько я понимаю, проблема вызвана разницей в правах доступа на системные каталоги, из-за чего происходит конфликт. Остается два варианта: либо исправить пакеты руками так (требуется установленная Fedora), либо собирать .rpm пакеты как положено.
Правильный: К сожалению, тут уже конфигом на три с половиной строки не отделаться, потому «Сборка rpm для чайников» — тема отдельной статьи. При этом полное руководство доступно на русском языке.

Подробнее о сборке пакетов можно почитать тут.

OS X


Как было указано выше, есть два основных метода распространения — образ диска с программой, или загрузка из каталога. Оба метода уже неплохо разобраны, стоит отметить лишь несколько принципиальных моментов.


Для того, чтобы программа могла запускаться не только на системах с установленным Qt SDK, нужно использовать специализированную утилиту — macdeployqt, которая скопирует все необходимые плагины и фреймворки в бандл приложения. При добавлении ключа "-d" будет сгенерирован .dmg образ, который можно использовать как базовый для кастомизации.

  • Открываем его через дисковую утилиту, конвертируем в read/write
  • Открываем получившийся образ в Finder
  • В меню «Вид» скрываем лишние элементы (строку статуса и т.д.)
  • Добавляем ссылку на /Applicatons
  • Создаем скрытую папку, копируем в нее фоновое изображение
  • В «параметрах вида» (ПКМ) подстраиваем размер иконок, сетку, фон
  • Конвертируем образ обратно

Оглавление цикла статей
Tags:
Hubs:
+32
Comments39

Articles

Information

Website
istodo.ru
Registered
Founded
Employees
2–10 employees
Location
Россия