- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF77:Autopackage
Материал из Linuxformat.
Содержание |
Autopackage Создаем пакет
Если вы сумеете постичь сложный процесс создания файлов Autopackage, линуксоиды всего мира будут вам благодарны. Грэм Моррисон покажет, как это делается.
Linux остро нуждается в более простом способе установки программ. Новички часто бывают обескуражены, когда вместо установки программы щелчком мыши по setup.exe им приходится брести по тернистой дистрибутиво-зависимой тропе установки пакетов, на ходу обучаясь работе с пакетными менеджерами, RPM и DEB-файлами и разбираясь с адской кухней зависимостей. Безусловно, это одна из главных причин, почему начинающие пользователи теряют мужество и возвращаются в Windows. Да и Linux-ветеранов раздражает, что очередную новинку нельзя по-быстрому установить и поглядеть без отслеживания дюжины зависимостей.
Текущая ситуация — это неустойчивое равновесие. В каждом дистрибутиве поддерживаются свои пакеты, которые исправляются и обновляются. Пользователи вынуждены переходить на новые версии дистрибутивов, если им нужны новые пакеты, либо искать альтернативы. Чаще всего такой альтернативой является самостоятельная сборка пакета из исходных текстов, но не у всех пользователей есть на это время.
Autopackage пытается внести порядок в этот хаос, посулив предоставить Linux альтернативу setup.exe, то есть пре-компилированные бинарные пакеты и автоматическое разрешение зависимостей. Autopackage ориентирован на совместимость с максимально большим числом дистрибутивов, причем установка везде проходит одинаково. Если вы предусмотрели Autopackage-файл для программы, вы можете быть уверены, что люди смогут установить ее легким движением руки независимо от используемого дистрибутива.
Работа для умелых рук…
Расплатой за легкость установки программы из Autopackage является довольно сложный процесс создания такого пакета. Пусть не вы писали программу, но, создав файл Autopackage, вы можете существенно облегчить жизнь ее пользователям и разработчику. Здесь не обойтись без хорошего знания Linux, включая версии установленных у вас библиотек и зависимостей выбранной вами программы. Да еще неплохо бы уметь программировать, поскольку исходный код программы скорее всего придется подправить для уменьшения числа зависимостей, замены опций компилятора или улучшения совместимости с различными версиями библиотек. Другого пути нет, в любом случае вы должны уверенно чувствовать себя в Linux. Фактически, Autopackage позволяет Linux-хакерам совершенствовать мастерство.
В процессе урока я шаг за шагом покажу вам на реальном примере, как создавать Autopackage-файл (далее Автопакет). Для этой цели я выбрал программу Kalbum, каталогизатор фотографий — слегка облегчив вам задачу, поскольку у Kalbum сравнительно мало зависимостей. Чем больше зависимостей, тем сложнее задача, и тем больше знаний требуется для ее решения.
Разобьем процесс создания автопакета на несколько шагов. Во-первых, нужно убедиться, что приложение в состоянии запускаться из любого каталога на жестком диске, иначе с ним не смогут работать те, у кого нет прав суперпользователя. Затем, с помощью опций сборки мы сократим зависимости, насколько возможно, после чего создадим spec-файл для завершения построения автопакета.
Перед тем, как начать, установите утилиты разработки Autopackage (http://autopackage.org/download-tools.html).
В данном уроке я использую версию Kalbum 1.0, ее можно взять с диска к LXF72 или с http://www.paldandy.com/kalbum.
ШАГ 1 — СДЕЛАТЬ ПРИЛОЖЕНИЕ ПЕРЕМЕЩАЕМЫМ
Для максимальной гибкости нужно сделать приложение перемещаемым. То есть программа обязана запускаться в любом случае, независимо от того, где она установлена. Тогда пользователи, не имеющие root-доступа к рабочей машине, смогут установить ее в свою домашнюю директорию. Но как узнать, насколько перемещаемо приложение?
Только путем чтения исходного кода. Как раз в нем разработчики указывают, требует ли программа прав суперпользователя (кстати, имейте это в виду, если затеете писать собственное приложение). Разработчики Autopackage специально создали утилиту BinReloc, чтобы хоть немного упростить мучительный процесс перемещения программы. Утилита статически компонуется с вашим приложением и зависит только от libc.
Преимущество KDE-приложений вроде Kalbum — наличие класса KStandardDirs, он выполняет ту же функцию, что и BinReloc: доступ к стандартным системным каталогам изнутри вашей программы. Так что править исходный код в данном случае нам не придется, и можно переходить к следующему шагу. (Отметим, что разработчики Autopackage надеются в будущем сделать сборку перемещаемых пакетов почти автоматической). Давайте посмотрим, как класс KStandardDirs используется в Kalbum (файл photodetails.cpp):
QString dir; KGlobal::dirs()->addResourceType("kalbum_data", KGlobal::dirs()->kde_default("data") + "kalbum/data/"); dir = KGlobal::dirs()->findResourceDir("kalbum_data", "slides/slides.png");
Этот кусок кода использует метод addResourceType класса KStandardDirs (типа ‘данные’, в отличие от, например, иконок), определяет директорию, а директория затем присваивается строке (dir), вместе с вложенной директорией и именем файла, который мы будем в ней искать. Строка укажет slides.png, расположена программа в домашней директории пользователя или в системном каталоге, тем самым выполняя функцию BinReloc. API Autopackage также включает собственные команды для определения местоположения программ в файловой системе и создания директорий, чтоб не пришлось разбираться, локальное имя файла или глобальное.
ШАГ 2 — СОКРАЩАЕМ ЗАВИСИМОСТИ
Благодаря удобному стандартному классу KDE нам не пришлось править код на предыдущем шаге. Надеюсь, это приободрит тех, кто еще не стал гуру программирования. Теперь нам предстоит сделать программу как можно более переносимой. По сути, это основная причина создания автопакета.
Главное препятствие к созданию повсеместно приемлемого пакета — огромное число зависимостей. Мы должны определить, какие из них действительно необходимы, а какие вполне можно отбросить. И это проблема с тройным дном. Любой разработчик прежде всего попытается найти и использовать стандартную библиотечную функцию, а не изобретать велосипед. Если программа использует всеобъемлющие API вроде GTK или KDE/Qt, то небольшой проект практически всегда обойдется функциями этих библиотек. Однако есть разработчики, предпочитающие выуживать библиотеки из самых потаенных омутов мира Open Source. Вот тут и начинаются проблемы с зависимостями.
Дело в том, что пользователю понадобятся не просто копии библиотек, а именно те версии, которые были у разработчика. Проблема усугубляется тем, что многие сборщики пакетов имеют привычку модифицировать библиотеки, накладывая на них патчи. В результате получается «ад зависимостей», сгубивший немало некогда добротных систем Linux.
Здесь нет простого решения. Если вы пишете программу и хотите, чтобы она была максимально переносимой, используйте поменьше сторонних библиотек, а те, что используете, подбирайте посвежее. Отсутствие старушки foobarlib 1997 года выпуска облегчит жизнь не только вам, но и создателю автопакета.
Внутреннее расследование
Хороший способ узнать, сколько библиотек тянется за программой - вызвать утилиту ldd. Сконфигурировав и построив пакет Kalbum, зайдите в каталог, где находится его исполняемый файл и введите команду: ldd kalbum. Вы увидите список из 38 библиотек, начинающийся так:
linux-gate.so.1 => (0xffffe000) libresolv.so.2 => /lib/libresolv.so.2 (0x4003c000) libkio.so.4 => /opt/kde3/lib/libkio.so.4 (0x4004f000) libkdeui.so.4 => /opt/kde3/lib/libkdeui.so.4 (0x4038c000) libkwalletclient.so.1 => /opt/kde3/lib/libkwalletclient.so.1 (0x4067a000)
Легко понять, почему для KDE-программы требуются библиотеки libkio и libkdeui, но что такое, например, linux-gate.so.1? Если бы мы строили RPM из этого пакета как такового, RPM затребовал бы данную библиотеку, а менеджер пакетов попытался бы ее установить, что вовлекло бы новые зависимости, и так далее. Но на самом деле linuxgate — экзотический случай: на нее ссылается вывод ldd, причем путь в ссылке не указан. И неудивительно: это не библиотека, а виртуальный динамический объект, используемый ядром для ускорения системных вызовов. Осталось убедиться, что libkwalletclient здесь лишняя, так как Kalbum не использует Wallet Manager, для связи с которым она и нужна.
Более подробную информацию по требуемым библиотекам можно добыть с помощью objdump. Команда objdump -u kalbum также выведет список библиотек, используемых программой. Библиотеки, расположенные в начале списка под заголовком Dynamic Section, помечены как ‘NEEDED’ (необходимые). Вас может огорчить тот факт, что список библиотек, выводимый objdump, не короче вывода ldd. Но ldd предусматривает еще один трюк: выводить названия библиотек, объявленных необходимыми, но никогда не использующихся:
ldd -u kalbum Unused direct dependencies: /lib/libresolv.so.2 /opt/kde3/lib/libkdesu.so.4 /opt/kde3/lib/libkwalletclient.so.1
Посмотрите на вывод — и увидите, что сюда попала и libkwalletclient. Итак, из 36 библиотек 31 не используется. Вопрос: как вычистить эти зависимости из программы? Разработчики Autopackage позаботились об этом и создали несколько Perl-скриптов для этой цели. Скрипты имеют общее имя apbuild и являются обертками для компилятора: они просто фильтруют ненужные зависимости перед тем, как пропустить необходимые.
Для компиляции Kalbum с использованием apbuild выполните make CC=apgcc CXX=apg++ из главной директории приложения. Компилятор переадресуется на скрипты, а они попытаются минимизировать зависимости. Эффект от apbuild проявляется немедленно: список стал гораздо короче. По завершении компиляции проверьте получившийся файл командой objdump -u kalbum. Список используемых библиотек сократился с 36 до 9 — для KDE это мизер, и шансы создать переносимое приложение заметно повысились. С оставшимися зависимостями мы рассчитаемся на следующем шаге.
ШАГ 3 — СОБИРАЕМ АВТОПАКЕТ
Радуйтесь: самое сложное позади. Все, что осталось сделать — создать небольшой текстовый файл, описывающий каждый компонент вашего пакета, с тем, чтобы Autopackage сумел собрать его в один инсталлируемый файл (к счастью, этот процесс в основном автоматизирован утилитой makeinstaller). Текстовый файл создается так, чтобы makeinstaller знал, что делать, и называется он spec-файлом. Если вы когда-либо собирали RPM-пакеты, вам известно, что они тоже используют файлы похожего формата. И фактически, и по названию это спецификация, включающая описание программы и перечень устанавливаемых файлов. Для автоматизации некоторых рутинных операций обычно используются скрипты, но кто-то, разбирающийся в приложении, должен отредактировать спецификацию вручную.
Метаданные
Первым делом изготовим спецификацию при помощи makeinstaller. Создайте в главном каталоге программы поддиректорию autopackage, именно в ней Autopackage будет искать spec-файл. Введите следующую команду для создания шаблона:
makeinstaller --mkspec >autopackage/default.apspec.in
Если вы откроете сгенерированый файл (autopackage/default.apspec.in), то обнаружите, что он состоит из разделов. Первый называется Meta и содержит описание программы, а также номер версии, чтобы Autopackage мог учесть его при обновлении. Назначение большинства параметров очевидно: легко догадаться, для чего нужны ‘DisplayName’, ‘Maintainer’ и ‘Description’. ‘ShortName’ — сокращенное имя версии строчными буквами. Единственный параметр, способный вызвать затруднение — ‘RootName’. Это уникальный идентификатор вашего автопакета, он начинается с @, затем следует домен, имя приложения и номер версии. Домен — не обязательно реальное имя, а просто символьный идентификатор: в нем требуется наличие хотя бы одного прямого слэша (но не в конце), а префиксы — ни www, ни протокол — не нужны. Номер версии — переменная, которую вставляет сам Autopackage ($SOFTWAREVERSION), так что ее можно оставить в покое. Для Kalbum этот параметр выглядит следующим образом:
@paldandy.com/kalbum:$SOFTWAREVERSION
Последний трудный параметр, AutoPackageTarget, указывает версию Autopackage, необходимую для установки этого пакета. Мы используем версию 1.0, так и запишем (1.0).
Закончив править этот раздел, можете смело пропускать два следующих, BuildPrepare и BuildUnprepare. Они уже были сконфигурированы автоматически при создании шаблона. Это касается и раздела import, описывающего дополнительные файлы, которые нужно включить в пакет. После сборки, по умолчанию Autopackage проверяет каждый файл; если обнаружатся лишние файлы, их можно просто удалить.
Подготовка к запуску
Следующий раздел спецификации — самый важный. Он называется Prepare (Подготовка), и именно в нем перечисляются все зависимости программы. Autopackage предоставляет механизм установки большинства распространенных зависимостей, таких как KDE, Gnome, SDL, Perl, используя скелет-файлы. Они находятся в установочной директории Autopackage (обычно /usr/share/autopackage/skeletons), и на них есть ссылка в спецификации, на базе описания имени домена, использованного как RootName автопакета.
При помощи списка зависимостей, составленного на предыдущем шаге, следует добавить запись о каждой библиотеке. Например, ваше приложение требует libpng, и в директории skeleton вы найдете скелет-файл, который (большинство из них этим и ограничивается) проверит наличие версии с требуемым номером. Если для нужной библиотеки скелет-файла найти не удалось, придется создать его самостоятельно, используя в качестве шаблона другие скелет-файлы.
Итак, после сборки Kalbum с помощью apbuild, у нас есть девять зависимостей: libkio, libkdeui, libkdecore, libkdefx, libqt-mt, libXext, libX1 libstdc++ и libc. К счастью, все они поддерживаются Autopackage.
- Библиотеки libk* устанавливаются вместе с KDE, так что в раздел Prepare нужно добавить такую строку: ‘requireAtLeastVersion @kde.org/kdelibs 3.0’. 3.0 — самая ранняя версия KDE; для перестраховки можно указать номер поновее.
- Libqt требуется для KDE всегда, так что можно о ней не беспокоиться.
- Остальные четыре библиотеки есть в любом дистрибутиве Linux, тут тоже волноваться не о чем.
Так легко мы отделались благодаря сокращению числа библиотек до минимума на предыдущем шаге. Теперь раздел Prepare должна выглядеть следующим образом:
[Prepare] # Dependency checking require @kde.org/kdelibs 3.0
Следующий раздел называется Install. Здесь находятся несколько скриптов-макросов, которые устанавливают различные части вашего пакета. Например, installExe устанавливает исполняемый файл, а installData — требуемые программе файлы данных. InstallDesktop создает иконку на рабочем столе, а InstallMan — обеспечивает документацию. Исполняемых файлов у Kalbum только один, зато множество файлов с данными; секция Install для него выглядит так:
prefix='kde-config --prefix' installExe bin/* installData share/apps/ installDesktop «Accessories» share/applications/kde/kalbum.desktop
Директории назначения самые обычные, как у других приложений. KDE-приложения требуют специального префикса для нормальной работы, который и добавляется в самом начале.
Итак, осталось только собрать сам автопакет. Поможет та же утилита makeinstaller, только теперь она используется немного по-другому:
makeinstaller autopackage/default.apspec.in Building installer for kalbum...
Вот и все! В результате мы получим shell-скрипт с расширением. autopackage. Для установки программы нужно запустить его. Это и есть файл, которым вы должны сопроводить свое приложение. Дайте нам знать, как вы справились с этим заданием, если начнете делать свои автопакеты.
Простая установка – это, конечно, хорошо, но как потом избавиться от автопакета? Есть два пути. Во-первых, существует маленькая утилита, весьма похожая на диалог установки/удаления программ в Windows: просто наберите команду autopackagemanager. Она предоставляет интерфейсы для Gtk и Qt. Во-вторых, существует командная утилита package, предлагающая несколько опций для управления автопакетами. Например, для удаления Kalbum введите команду package remove Kalbum, а чтобы убедиться в правильности установки, замените remove на verify. Узнать больше о команде package вы можете в man- и info-документации.