Сборка deb-пакетов

Статья с http://tigro.info/blog/ о сборке deb пакетов.

Для сборки пакета нам понадобятся debhelper, dh-make, devscripts, fakeroot, а также необходимые компиляторы и интерпретаторы. Кроме того нам нужна программа, которую будем компилировать. Сам тарбол нам как бы и не нужен, нам нужно только дерево исходников, которое необходимо распаковать. Главный каталог должен называться следующим образом: имяпакета-версияпакета, в противном случае возникнут проблемы.

В итоге у нас должны получиться бинарные файлы, исходник *orig*tar.gz, *diff*gz* и файлы .dsc и .changes. Возможно обойтись без файлов *orig*tar.gz и *diff*gz* заменив их одним тарболом, в котором находятся все служебные файлы, однако начиная с версии Debian 4.0 подобные ухищрения не приветствуются.

Итак, я для удобства рекомендую создать в вашем домашнем каталоге папку, допустим, BUILD, в ней для каждого пакета создавать каталог по его имени, и уже внутри последнего каталога размещать дерево исходников. Для чего так сложно? Потому, что собранные пакеты будут помещаться на уровень выше дерева и у вас скоро весь каталог BUILD забьётся кучей файлов.

Если вы хотите использовать Цифровую подпись, то необходимо добавить в ваш файл .bashrc следующие строки:

export EMAIL=your@gpg.email
export DEBFULLNAME="YOUR GPG NAME"                                  
export DEBEMAIL=your@gpg.email

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

Итак, для начала необходимо создать служебные файлы. Для этого нужно зайти в каталог исходников и отдать команду dh_make --createorig. Вам необходимо выбрать нужный тип пакета. Если у вас будет только один бинарный пакет, то нажимаем s, если несколько — то l. Для модулей ядра нужно выбрать k. О cdbs (b) мы поговорим как-нибудь потом.

Можете также вызывать команду

dh_make

вместе с ключом

-c

чтобы указать лицензию пакета.

Мы сперва рассмотрим пакет, содержащий несколько бинарников (то, что обычно ни в каких документациях не рассматривается). А потом скажем несколько слов относительно single binary.

После запуска dh_make создастся каталог debian, в котором будет лежать довольно большое количество файлов. Все файлы *.ex и *.EX можно в принципе удалить сразу и создавать только по мере надобности.

В файле control указываются все необходимые параметры. Он делится на секции Source и Package. Секций Package может быть несколько в зависимости от того сколько бинарных пакетов получится при сборке. Ниже приведён пример файла control для пакета liferea:

Source: liferea
Section: gnome
Priority: optional
Maintainer: Franz Pletz <fpletz@franz-pletz.org>
Uploaders: Luis Rodrigo Gallardo Cruz <rodrigo@nul-unu.com>
Build-Depends: autotools-dev, debhelper (>> 4.0.0), libgtkhtml2-dev
Standards-Version: 3.7.2.0
Package: liferea
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}, liferea-xulrunner (=${Source-Version}), dbus-1-utils
Description: feed aggregator for GNOME
 Liferea is a simple FeedReader clone for GNOME. It is a reader for
 RSS/RDF feeds which also supports CDF channels, Atom/Echo/PIE feeds and
 OCS directories.
 .
 Liferea is an abbreviation for Linux Feed Reader.
 .
 Homepage: http://liferea.sourceforge.net/
Package: liferea-xulrunner
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: liferea-mozilla, liferea-gtkhtml
Conflicts: liferea-mozilla (<< 1.0.17-1), liferea-gtkhtml (<< 1.0.27-2)
Replaces: liferea-mozilla (<< 1.0.17-1)
Description: xulrunner-based rendering library for Liferea
 Liferea is a simple FeedReader clone for GNOME2. It is a reader for
 RSS/RDF feeds which also supports CDF channels, Atom/Echo/PIE feeds and
 OCS directories.
 .
 Liferea is an abbreviation for Linux Feed Reader.
 .
 Homepage: http://liferea.sourceforge.net/
Package: liferea-mozilla
Architecture: all
Depends: liferea-xulrunner
Description: transitional dummy package
 Previous versions of liferea had several rendering engines to choose from.
 This is a dummy package to ease transition from those versions.
 .
 It can be safely removed from your system after updating.

Package: liferea-gtkhtml
Architecture: all
Depends: liferea-xulrunner
Description: transitional dummy package
 Previous versions of liferea had several rendering engines to choose from.
 This is a dummy package to ease transition from those versions.
 .
 It can be safely removed from your system after updating.

Разберём его поподробней. Итак, в секции Source указывается имя исходника, секция (Section), к которой пакет будет отнесён в репозитории, Priority — приоритет, подробнее смотреть здесь. Maintainer и Uploaders — думаю без вопросов, Build-Depends — пакеты необходимые при сборке пакета, Standards-Version — версия документа Debian-Policy (не нужно трогать).

Далее идёт описание для бинарного пакета, Packages — его имя, Architecture: архитектура пакета, может быть any (сама превратится в нужную платформозависимую архитектуру) и all (платформонезависимую), Depends — зависимости которые обязательно требуются для установки пакета (благодаря двум переменным в этом поле зависимости появятся автоматически, однако иногда следует добавлять их вручную), Description — описание пакета, причём в первой строке используется краткое описание, а в остальных строках, начиная с пробела, длинное. Новые абзацы отделены строкой с точкой.

По поводу зависимостей. Существуют ещё два типа зависимостей Suggests и Recommeds. Первый тип зависимостей нацелен на расширение возможностей нашего пакета, второй настоятельно рекомендует установить данные пакеты. Aptitude ставит зависимости Recommeds по умолчанию, apt-get не обрабатывает ни те, ни другие. Существуют также Pre-Depends, но их использовать не рекомендуется.

В зависимостях могут применяться указания версий, как видно из примера. Допустимыми символами сравнения являются: <<, <=, =, >=, и >> для строго раньше чем, раньше или равно, в точности равно, равно или позже и строго позже чем соответственно.

Также в control файле могут применяться следующие теги: Provides — дополнительное имя для нашего пакета (эдакое виртуальное), Replaces — список пакетов, которые будут удалены после установки нашего пакета, Conflicts — пакеты с которыми наш пакет заведомо конфликтует.

Вторым по важности файлом является файл rules. Именно в нем находится все необходимое для компиляции пакета и упаковки его в бинарные пакеты. Этот файл есть ничто иное, как скрипт make, с использованием команд dh_*.

В нем действительно много секций, и много строк, но нам нужно будет изменять секции config.status, build и install. В этих секциях, соответственно, необходимо прописать команды для конфигурации пакета (если они нужны), для его сборки и для установки. Если мысленно выкинуть всевозможные dh-команды, то скрипт становится не таким уж страшным. Правда dh-команды разумеется нужны. Ниже приведен файл rules:

#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
CFLAGS = -g -O2
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
    INSTALL_PROGRAM += -s
endif
config.status: configure
        dh_testdir
        cp -f /usr/share/misc/config.sub config.sub
        cp -f /usr/share/misc/config.guess config.guess
        CFLAGS="$(CFLAGS)" ./configure --prefix=/usr \
                                 --mandir=\$${prefix}/share/man \
                                 --sysconfdir=/etc --disable-gecko \
                                 --disable-gtkhtml2 --enable-sm
        ln -s $(CURDIR)/liferea.1 $(CURDIR)/debian/liferea-bin.1
        ln -s $(CURDIR)/liferea.1 $(CURDIR)/debian/liferea-add-feed.1

build: build-stamp
build-stamp:  config.status
        dh_testdir
        $(MAKE)
        touch build-stamp

clean:
        dh_testdir
        dh_testroot
        rm -f build-stamp config.log debian/liferea-bin.1 \
            debian/liferea-add-feed.1
        -$(MAKE) distclean
        dh_clean 

install: build
        dh_testdir
        dh_testroot
        dh_clean -k 
        dh_installdirs
        GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1 $(MAKE) install \
        DESTDIR=$(CURDIR)/debian/liferea
        # add the debian menu icon
        cp debian/liferea.xpm debian/liferea/usr/share/liferea/pixmaps/
        # Link documentation
        mkdir -p debian/liferea/usr/share/doc/liferea
        ln -s ../../liferea/doc/html debian/liferea/usr/share/doc/liferea/html
        dh_movefiles --sourcedir=debian/liferea
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.

# Build architecture-dependent files here.
binary-arch: build install
        dh_testdir
        dh_testroot
        dh_installchangelogs ChangeLog
        dh_installdocs
        dh_installman debian/liferea-bin.1 debian/liferea-add-feed.1
        dh_installmenu
        dh_gconf
        dh_link
        dh_strip
        dh_compress
        dh_fixperms
        dh_installdeb
        dh_shlibdeps
        dh_gencontrol
        dh_md5sums
        dh_builddeb

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

Вообще при сборке deb-пакета следует привыкать к тому, что одно и тоже можно делать разными способами, что разумеется не упрощает задачу. Рассмотрим основные строки из файла rules.

В секции config.status идет обычный запрос на конфигурацию пакета. Обратите внимание, что вам необходимо правильно задавать каталоги, так как по умолчанию configure выбирает /usr/local. Секция build вызывает секцию build-stamp, в которой происходит обычный make ($(MAKE) = make).

Затем выполняется install. Там идет обычный make install и дополнительные команды для правильной установки данного пакета. Заметьте, что инсталляция происходит в каталог $(CURDIR)/debian/liferea, где $(CURDIR) каталог дерева исходников. Теперь одна из важных вещей. Нам необходимо разобрать файлы из общего каталога liferea по нашим бинарным пакетам. Именно для этих целей и служит команда dh_movefiles. В качестве параметра указывается каталог в который была произведена инсталляция. Если вы инсталлировали пакет в каталог $(CURDIR)/debian/tmp, то никаких параметров dh_movefiles передавать не нужно.

Все данные о том какие файлы в какие пакеты положить dh_movefiles берёт из файлов (в каталоге debian) название-бинарного-пакеты.install. Создайте их столько же, сколько будет бинарных пакетов и пропишите в них названия файлов с полным путём относительно каталога в который была установлена программа, но без первого слеша. Можно использовать маски.

После разбора файлов выполняется секция binary-arch, которая создаёт deb-пакет. В ней, например, видно, как устанавливаются man файлы.

В deb-пакете также могут присутствовать скрипты postinst, preinst, postrm и prerm, которые выполняются соответственно, после инсталляции, перед инсталляцией, после удаления и перед удалением. Для каждого из пакетов необходимо создать файл имя-бинарного-пакета.postinst и т. п. в них можно разместить любые команды.

Теперь рассмотрим changelog. Именно в нем мы будем указывать версию нашего пакета. Версией в Debian называется все, что идёт после имени пакета. В deb нет тегов release и epoch как в rpm, однако вы можете запросто задать что-то наподобие 3:1.0.4-15.feisty.0. До ":" идёт эпоха, после "-" идёт релиз. Файл changelog следует редактировать при помощи команды dch. Если её вызвать без параметра, то будет изменена последняя запись в changelog, а если dch -i, то будет добавлена новая:

liferea (1.0.27-2) unstable; urgency=low
  * Remove the GtkHTML rendering plugin. This plugin is basically unusable
  on 64bit architectures. liferea-gtkhtml is now just a dummy package for
  upgrades (Closes: #379900, #407152, #361376, #368866).
  * Remove upstream's NEWS file, it contains only version release dates.
 -- Luis Rodrigo Gallardo Cruz <rodrigo@nul-unu.com>  Sun, 11 Feb 2007 21:18:16 -0600

Также в changelog вы можете менять принадлежность пакета к дистрибутиву (сразу после версии). В данно примере идёт unstable, в Ubuntu там должно быть что-то типа feisty, edgy и т. п.

Что касается single binary то там все намного проще. После команды dh_make, вам нужно подправить control и changelog. Возможно немного rules. И далее пакет соберётся сам собой.

Для сборки пакета нам понадобится команда debuild которую следует отдавать всё в том же каталоге исходников. После того, как пакеты соберутся, вы должны будете подписать пакет (если настроили GPG), вернее не пакет, а два текстовых файла, которые появятся в процессе сборки. Это файлы .dsc и .changes. Первый из них несёт информацию об исходнике, второй нужен только для помещения пакета в репозиторий.

У debuild есть параметр clean, который позволяет очистить дерево исходников и папку debian от ненужных файлов.

В этой статье я попытался передать основные принципы сборки deb пакетов, однако прекрасно понимаю, что нюансов здесь очень много, но описать их все я конечно же не смогу. Вам возможно следует почитать Руководство начинающего разработчика Debian, в котором некоторые аспекты изложены поподробней, а также Руководство по политике Debian. В следующей статье мы поговорим о том, как создавать репозитории для rpm и deb пакетов.