Как я собираю/бэкпорчу deb пакеты

В связи с упомянутой в комментариях к этой статье задачей “Как правильно собрать/сбэкпортить пакет” решил описать свое решение.

Disclamer

Если Вам показалась интересной эта статья и, в особенности, если что-то показалось неясным, обратите внимание на соответствующую страницу в DebianWiki.

Шаг 0. Сурцовый пакет

Во-первых, предположим, что у нас уже есть сурцовый пакет. Получается он обычно из репозитория deb-src командой

$ apt-get source <имя пакета>

Если у вас несколько репозиториев, то вытащена будет самая свежая версия пакета, если требуется какая-то конкретная, то можно указать ее после имени через знак =

Кстати, чтобы узнать список версий в доступных репозиториях, можно использовать команду

$ apt-cache policy <имя пакета>

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

Если вы тащите пакеты откуда-то вне репозитория, или не хотите подключать ради этого сурцовый репозиторий, то достаточно скачать файлы

  • <имя пакета>_<версия>.orig.tar.gz
  • <имя пакета>_<версия>.diff.gz
  • <имя пакета>_<версия>.dsc

После этого надо распаковать этот сурцовый пакет командой

$dpkg-source -x <имя пакета&>_<версия>.dsc

Получится каталог <имя пакета>-<версия_upstream>

Есливы скачали пакет из репозитория командой apt-get, а он не распаковался сам, значит вам надо поставить пакет dpkg-dev в котором содержится утилита dpkg-source.

Шаг 1. Исправление версии

Этот шаг не обязателен, но если вы соберете пакет с такой-же версией, что и в официальном репозитории, то во-первых, по версии пакета будет сложно определить бэкпорт это или нет, а во-вторых, при дальнейшем апгрейде у вас может остаться сбэкпорченный пакет, потому что его версия будет совпадать с версией в репозитории. Да и вообще, нехорошо это, когда 2 разных сборки пакета имеют одну и ту же версию.

При бэкпорте обычно добавляют в конец версии что-то вроде ~backport1, так как по правилам сравнения версий в системе apt “<версия>~<строка>” всегда меньшн чем просто “<версия>”.

Переходим в каталог <имя пакета>-<версия_upstream> и говорим в нем

dch -i

Откроется редактор файла changelog, в котором необходимо указать правильную версию (то есть версия такая же, как в предыдущей записе + волшебное ~backport1). Ну и описать изменения вроде “* Backport to Sarge”.

Если команды dch у вас нет (она из пакета devscripts), то можно отредактировать файл debian/changelog руками (читай редактором), добавив секцию для новой версии.

Шаг 2a. Сборка

Осталось малое – собрать пакет.

В простом случае, когда мы собираем для себя, можно просто поставить в рабочую систему все сборочные зависимости (или руками, посмотрев Build-depends в debian/control, или командой apt-get build-dep) . Достаточно часто бывает ситуация, что в build-depends указаны версии пакетов, старше тех, чтол имеются в текущей системе. Иногда (особенно в случае, когда требуется более старшая версия debhelper), достаточно просто понизить требования в файле debian/control, а иногда придется вначале сбэкпортить (или скачать и поставить уже сбэкпорченный пакет) необходимую для сборки библиотеку.

Кстати, для сборки необходимы помимо пакетов, указанных в build-depend еще и все пакеты, которые устанавливаются с пакетом build-essentialmake, fakeroot, gcc, g++ и прочие. Так что лучше не забыть поставить этот пакет.

Теперь, находясь во все том же каталоге <имя пакета>-<версия upstream>, говорим

dpkg-buildpackage -rfakeroot

И вуаля, через некоторое время, каталогом выше лежит заветный файлик <имя пакета>-<версия>_i386.deb

Если конечно, у вас удовлетворены все зависимости, стоят пакеты dpkg-deb, fakeroot, g++ и не произошло еще каких ошибок.

Шаг 2б. Правильная сборка

На самом деле, для того, чтобы собрать пакет правильно, его надо собирать в минимальной системе, где стоят только build-essential и зависимости этого пакета. Тогда, во-первых, не будет никаких накладок из-за того, что у вас в системе стоят некоторые пакеты вообще неизвестно откуда и непонятно каких версий (и в итоге в зависимостях у бинарного пакета могут оказаться пакеты версий, отсутствующих в том дистрибутиве, под который вы хотите собрать пакет), а во-вторых, вы избежите накладок (крайне редких, но все же), когда установленный лишний пакет как-то (читай негативно и не всегда очевидно) влияет на сборку.

В качестве решения подойдет chroot с чистым окружением… Испугались? Все уже украдено до нас.

Ставим пакет pbuilder и используем его возможности. Подробное описание поищите в гугле. Можно пойти еще дальше и использовать cowbuilder из пакета cowdancer – это аналог pbuilder, только образ сборочной системы он хранит не в tar.gz а в развернутом виде, а при сборке копирует этот образ с использованием техники copy-on-write, что ускоряет сборку.

Шаг 2б.1. Настройка cowbuilder

cowbuilder является надстройкой над pbuilder, поэтому надо вначале поколдовать над /etc/pbuilderrc.

BUILDPLACE=/var/cache/pbuilder/build/
USEPROC=yes
USEDEVPTS=yes
USEDEVFS=no
BUILDRESULT=/var/cache/pbuilder/result/
#у меня кэширующий apt-cacher, пожтому я отключил кэширование пакетов внутри pbuilder
#APTCACHE="/var/cache/pbuilder/aptcache/"
APTCACHE=""
REMOVEPACKAGES=""
HOOKDIR=""
export DEBIAN_FRONTEND="noninteractive"
DEBEMAIL="Alexander GQ Gerasiov < gq@cs.msu.su >"
BUILDSOURCEROOTCMD="fakeroot"
PBUILDERROOTCMD="sudo"
DEBBUILDOPTS=""
APTCONFDIR=""
BUILDUSERID=1000
BUILDUSERNAME=gq
export LOGNAME=gq
BINDMOUNTS=""
unset DEBOOTSTRAPOPTS
export PATH="/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin"
export SHELL=/bin/bash
DEBOOTSTRAP="cdebootstrap"
PKGNAME_LOGFILE_EXTENTION="_$(dpkg --print-architecture).build"

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

Шаг 2б.2. Создание чистых образов систем

Далее я содал образы для sarge и etch, командой вроде

debootstrap sarge /var/cache/pbuilder/base.sarge/

Зашел в созданное окружение командой

cowbuilder --login --save-after-login --basepath /var/cache/pbuilder/base.sarge

Задал нужные мне репозитории в /etc/apt/sourses.list, удалил ненужные пакеты, поставил build-essential и cowdancer (версию для Sarge можно взять в моем репозитории для Sarge).

С Ubuntu дело оказалось несколько сложнее, cdebootstap не умеет собирать образы для нее, а debootstap умеет только собирать образы для breezy, так что мне пришлось для создания образов edgy и dapper ставить при помощи debootstrap образ breezy, заходить в него “cowbuilder –login” и делать внутри “aptitude dist-upgrade” до нужного мне дистрибутива. Но в целом задача решаема.

Итак у меня есть несколько образов в /var/cache/pbuilder/:

  • base.dapper
  • base.edgy
  • base.etch
  • base.experimental
  • base.sarge

Шаг 2б.3 Сборка пакета в чистом окружении

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

Вначале из нашего каталога <имя пакета>-<версия апстрим> с измененной версией и поправленными build-depends собираем сурцовый пакет новой версии:

dpkg-buildpackade -rfakeroot -S

Переходим каталогом выше, где собрался файлик <имя пакета>_<версия>.dsc (где версия, это уже наша версия с “~backport”) и говорим

pbuild --dist sarge <имя пакета>_<версия>.dsc

Если произошла ошибка (например из-за проблем с зависимостями), то возвращаемся к шагу 1 и исправляем ошибки. Если все прошло нормально, то собранные пакеты окажутся в каталоге /var/cache/pbuilder/results. Вот собственно и все.

Для обновления образов (особенно актуально для testing) я использую команду

pbuild --dist etch --update

Ну и собственно сам мой скриптик.

Автоматизируй это

Так как в последнее время все чаще мне приходится делать однообразную задачу бэкпорта пакетов под 4 дистрибутива (оригинальный пакет для Debian Unstable надо сбэкпортить для Lenny, Etch и трёх Ubuntu), написал небольшой скриптик, который не требует от меня вообще никаких ручных действий при бэкпорте:
backport.

10 Replies to “Как я собираю/бэкпорчу deb пакеты”

  1. А mini-dinstall пинать не нужно, он сам заводится когда работает в качестве демона. Это его самое главное достоинство.

    1. Знаю я. Меня даже звали его мейнтейнить… Там проблема в том, что он не совсем стабильный и раз в неделю, да падает куда-то (по крайней мере оказывается не запущенным).
      Да и смысл его держать запущенным, когда проще пнуть скриптом, когда надо.

  2. Вот когда аплоадят по 20 раз в час, а репозиторий переиндексируется 10 минут вот тогда и надо держать его в демоне, потому что при старте он переиндексирует все репозитории.

  3. спасибо за статью 🙂

    сможете помочь – как собрать пакет с нуля, т.е. когда нет исходников с INSTALL b configure, а есть два-три текстовых файликов программного кода?

    1. Ну там наверное есть Makefile. Или, если используется другая система сборки, аналог. Ну или хотя бы представление, как оно собирается.
      Значит надо создать пакет с нуля при помощи dh_make. И указать в целях сборки в debian/rules то что надо.
      См. http://www.us.debian.org/doc/maint-guide/

  4. Спасибо за статью! Весьма доступно) Я всё делал неправильно. Теперь исправлюсь, да.

Leave a Reply

Your email address will not be published. Required fields are marked *