сборка пакета deb

Thank you for reading this post, don't forget to subscribe!

Мы рас­смот­рим при­мер рабо­ты с исход­ни­ка­ми nginx, а так­же раз­бе­рем подроб­нее опции, кото­рые мож­но задей­ство­вать при сбор­ке. На прак­ти­ке, дан­ное дей­ствие не име­ет смыс­ла, так как уже собран­ный nginx мож­но полу­чить на сай­те раз­ра­бот­чи­ка или в репо­зи­то­рии системы

Подготовка системы

Про­цесс сбор­ки тре­бу­ет уста­нов­ки допол­ни­тель­ных ком­по­нен­тов, что при­во­дит к скоп­ле­нию мусо­ра из ненуж­ных паке­тов. Реко­мен­ду­ет­ся делать сбор­ку на отдель­ном ком­пью­те­ре или в кон­тей­не­ре Docker.

Неза­ви­си­мо от сре­ды, в кото­рой мы будем соби­рать паке­ты, необ­хо­ди­мо выпол­нить пред­ва­ри­тель­ные настройки.

1. Уста­нов­ка пакетов:

apt-get update

apt-get install dpkg-dev devscripts wget

* где:

  • dpkg-dev — содер­жит набор инстру­мен­тов для рабо­ты с исход­ны­ми фай­ла­ми для паке­тов deb.
  • devscripts — набор скрип­тов для сбор­ки пакетов.
  • wget — ути­ли­та для загруз­ки фай­лов по http. Нуж­на для загруз­ки архи­вов с исходниками.

2. Созда­ние пользователя.

Делать гото­вые уста­но­воч­ные сбор­ки паке­тов очень опас­но от поль­зо­ва­те­ля root. Если мы допу­стим ошиб­ку с путя­ми, фай­лы могут пере­те­реть или уда­лить важ­ные для рабо­ты дирек­то­рии. Сто­ит создать отдель­но­го поль­зо­ва­те­ля и рабо­тать под ним. Одна­ко, если мы рабо­та­ем в спе­ци­аль­ной вир­ту­аль­ной сре­де или кон­тей­не­ре Docker, нам это не страш­но. Тогда дан­ный пункт мож­но про­пу­стить и рабо­тать из-под root.

Выпол­ня­ем команду:

useradd builder -m

* в дан­ном при­ме­ре мы созда­дим поль­зо­ва­те­ля builder. Опция -m сра­зу создаст домаш­ний ката­лог для пользователя.

Теперь захо­дим под дан­ным поль­зо­ва­те­лем — после­ду­ю­щие коман­ды мы будем выпол­нять от него:

su - builder

3. Созда­дим ката­лог, в кото­ром будет про­ис­хо­дит сборка:

mkdir -p debbuild

Перей­дем в debbuild:

cd debbuild

Мы гото­вы к сборке.

Сборка из исходников

В нашем при­ме­ре мы возь­мем исход­ни­ки для сбор­ки nginx (для выпол­не­ния configure, make, make install …) и собе­рем из них свой пакет для уста­нов­ки NGINX. Про­цесс будет раз­бит на несколь­ко этапов:

  1. Пред­ва­ри­тель­ная настройка.
  2. Созда­ние фай­лов с инструк­ци­я­ми для сбор­ки пакета.
  3. Выпол­не­ние сбор­ки и проверки.

Рас­смот­рим каж­дый из эта­пов подробнее.

Подготовка

Созда­дим ката­лог с назва­ни­ем соби­ра­е­мо­го при­ло­же­ния (с уче­том версии):

mkdir -p nginx-1.20.1/debian

* в нем обя­за­тель­но ката­лог debian.

Перей­дем в создан­ный каталог:

cd nginx-1.20.1

Теперь созда­дим несколь­ко важ­ных файлов.

Создание файлов сборки (основные)

Для выпол­не­ния сбор­ки нуж­но создать, мини­мум, 4 файла.

1. Control-файл.

Это основ­ной файл с опи­са­ни­ем про­цес­са сбор­ки. Вводим:

vi debian/control

При­мер для наше­го случая:

* зна­че­ния для опции Build-Depends зада­ют­ся экс­пе­ри­мен­таль­но — луч­ше все­го попро­бо­вать сна­ча­ла собрать тре­бу­е­мый пакет вруч­ную, что­бы понять, какие потре­бу­ет­ся доуста­но­вить паке­ты. Реко­мен­ду­ет­ся это делать на чистой систе­ме, что­бы не полу­чить иска­жен­ный резуль­тат (на исполь­зу­е­мой систе­ме уже могут быть паке­ты, кото­рых не будет на дру­гом ком­пью­те­ре, где будет про­ис­хо­дить сборка).
* более подроб­ное опи­са­ние фай­ла control пред­став­ле­но ниже.

2. Файл changelog.

В дан­ном фай­ле опи­сы­ва­ет­ся исто­рия изме­не­ний паке­та. Так­же сбор­щик берет из это­го фай­ла номер вер­сии и релиза.

Созда­ем файл командой:

vi debian/changelog

* в фай­ле ука­за­но, что пер­вые изме­не­ния внес test testovich  03 авгу­ста. Для нача­ла сбор­ки это­го будет доста­точ­но. Опи­са­ние ниже.

3. Файл rules.

Опи­сы­ва­ем пра­ви­ла ком­пи­ля­ции паке­та во вре­мя его сбор­ки. Созда­ем файл:

vi debian/rules

* важ­но обра­тить вни­ма­ние на факт, что содер­жи­мое фай­ла может силь­но отли­чать­ся в зави­си­мо­сти от того, что мы соби­ра­ем и какой вер­сии соби­ра­е­мое про­грамм­ное обес­пе­че­ние. В дан­ном при­ме­ре мы созда­ли файл для неза­ви­си­мой рабо­ты — сбор­щик сам ска­ча­ет исход­ник и рас­па­ку­ет его в рабо­чий ката­лог (в дан­ном при­ме­ре, nginx). Так­же мне при­шлось пере­опре­де­лить этап dh_usrlocal, так как на нем воз­ни­ка­ла ошиб­ка, свя­зан­ная с невоз­мож­но­стью уда­лить ката­лог коман­дой rmdir.
* в нашей систе­ме дол­жен быть уста­нов­лен wget, как и все осталь­ные ути­ли­ты, кото­ры­ми мы захо­тим воспользоваться.
* более подроб­ное опи­са­ние фай­ла rules ниже.

4. Файл compat.

Ука­зы­ва­ем на уро­вень сов­ме­сти­мо­сти с debhelper (вспо­мо­га­тель­ный инстру­мент для сбор­ки паке­тов). Созда­ем файл:

vi debian/compat

9

* на момент обнов­ле­ния инструк­ции реко­мен­до­ва­но исполь­зо­вать вер­сию не ниже 9. Сама по себе сбор­ка без дан­но­го фай­ла (или при ука­за­нии вер­сии ниже 9) запу­стит­ся, но быст­ро оста­но­вит­ся с ошиб­кой dh_auto_clean: Compatibility levels before 9 are deprecated (level X in use), где Х — теку­щий уро­вень совместимости.

Дополнительные файлы сборки

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

1. Файл postinst.

Явля­ет­ся скрип­том, кото­рый будет запу­щен после уста­нов­ки паке­та на целе­вой систе­ме. Любые постин­стал­ля­ци­он­ные настрой­ки мож­но выпол­нить с его помо­щью, например:

vi debian/postinst

* в дан­ном при­ме­ре мы про­сто созда­дим учет­ную запись test. Опция set -e гово­рит о том, что при воз­ник­но­ве­нии ошиб­ки, необ­хо­ди­мо сра­зу пре­рвать рабо­ту скрипта.

Может быть исполь­зо­ван более слож­ный сце­на­рий с обра­бот­кой аргу­мен­тов, например:

* таким обра­зом, при уста­нов­ке при­ло­же­ния посред­ством, напри­мер, коман­ды apt-get upgrade, после инстал­ля­ции будет выпол­не­на толь­ко коман­да sytemctls is-active --quiet nginx.

2. Файл postrm.

Это скрипт, кото­рый выпол­нит­ся после уда­ле­ния пакета:

vi debian/postrm

* в дан­ном при­ме­ре мы пред­по­ло­жи­ли, что после уда­ле­ния нуж­но уда­лить 2 ката­ло­га /var/log/app и /opt/app/test.

3. Файл preinst.

Скрипт выпол­не­ния перед уста­нов­кой пакета.

4. Файл prerm.

Скрипт выпол­не­ния перед уда­ле­ни­ем пакета.

Сборка пакета

У нас созда­ны все необ­хо­ди­мые фай­лы, выпол­не­ны пред­ва­ри­тель­ные дей­ствия, и мы гото­вы к сборке.

Про­ве­ря­ем, что у нас уста­нов­ле­ны необ­хо­ди­мые паке­ты и, при необ­хо­ди­мо­сти, уста­но­вим их:

mk-build-deps --install

* коман­да явля­ет­ся частью паке­та devscripts, кото­рый мы уста­но­ви­ли в нача­ле инструк­ции. Она чита­ет опцию Build-Depends фай­ла control и уста­нав­ли­ва­ет необ­хо­ди­мые пакеты.

Выпол­ним сбор­ку командой:

debuild -us -uc -b

Если мы все сде­ла­ли пра­виль­но, в кон­це мы уви­дим что-то на подобие:

Пакет сфор­ми­ро­ван и дол­жен нахо­дит­ся в дирек­то­рии на уро­вень ниже:

ls ../

Сре­ди спис­ка фай­лов мы долж­ны уви­деть пакет с нашим названием:

Описание служебных файлов

Попро­бу­ем разо­брать­ся в син­так­си­се обя­за­тель­ных фай­лов, кото­рые мы созда­ли для выпол­не­ния сборки.

Control

Дан­ный файл содер­жит основ­ную инфор­ма­цию о соби­ра­е­мом паке­те. Рас­смот­рим по отдель­но­сти обя­за­тель­ные опции и дополнительные.

Основ­ные (без кото­рых сбор­щик вер­нет ошибку):

Опция Опи­са­ние При­мер
Source Опре­де­ля­ет имя паке­та источника. nginx
Maintainer Имя и адрес элек­трон­ной почты сбор­щи­ка пакета. test testovich  <master@test.ru>
Package Имя соби­ра­е­мо­го пакета. nginx
Architecture Архи­тек­ту­ра соби­ра­е­мо­го пакета. amd64

Допол­ни­тель­ные опции фай­ла control:

Опция Опи­са­ние
Section Клас­си­фи­ка­ция зада­чи, для кото­рой может быть исполь­зо­ва­но приложение.
Чаще все­го при­ме­ня­ют­ся: misc, utils, net, mail, text, x11.
Воз­мож­ные зна­че­ния: admin, base, comm, contrib, devel, doc, editors, electronics, embedded, games, gnome, graphics, hamradio, interpreters, kde, libs, libdevel, mail, math, misc, net, news, non-free, oldlibs, otherosfs, perl, python, science, shells, sound, tex, text, utils, web, x11.
Priority Опре­де­ля­ет важ­ность паке­та для системы.
Воз­мож­ные вари­ан­ты: required, standard, optional, extra, important.
Вли­я­ет на пове­де­ние при уда­ле­нии — напри­мер, пакет, отме­чен­ный как required, не может быть удален.
Build-Depends Пере­чис­ля­ет спи­сок паке­тов, кото­рые тре­бу­ют­ся для сборки.
Если в систе­ме не будет пере­чис­лен­ных паке­тов, сбор­щик вер­нет ошибку.
Есть раз­ные фор­ма­ты запи­си, например:
1. Пере­чис­ля­ем зави­си­мо­сти: libpcre3-dev, zlib1g-dev
2. Исполь­зу­ем логи­че­ское или: apache2 | httpd | nginx, php-fpm
3. Ука­за­ние вер­сии: libpcre3-dev (= 13), zlib1g-dev (> 14),
apache2 (>= 15),
httpd (< 16),
nginx (<= 17)
(обра­ти­те вни­ма­ние, дан­ный пере­чень мож­но запи­сать через запя­тую в одну строч­ку или по одной/несколько паке­тов на каж­дой строч­ке так­же через запятую).
Standards-Version Ука­зы­ва­ет на вер­сию пакета.
Homepage Домаш­няя стра­ни­ца для соби­ра­е­мо­го пакета.
Provides Имя паке­та, под кото­рым будет заре­ги­стри­ро­ва­но при­ло­же­ние после уста­нов­ки. Как пра­ви­ло, ука­зы­ва­ет­ся таким же, как и имя соби­ра­е­мо­го паке­та. Но в ред­ких слу­ча­ях, может пона­до­бить­ся поме­нять на свое.
Depends Спи­сок паке­тов, кото­рые тре­бу­ют­ся для уста­нов­ки соби­ра­е­мо­го паке­та на конеч­ной систе­ме. Так­же как и в Build-Depends, воз­мо­жен раз­ный фор­мат написания.
Description Про­из­воль­ное опи­са­ние для паке­та. Необ­хо­ди­мо про­сле­дить, что­бы раз­мер одной стро­ки не пре­вы­шал 73 сим­во­ла. Каж­дая после­ду­ю­щая стро­ка опи­са­ния долж­на начи­нать­ся, как мини­мум, с одно­го пробела.

Пол­ный пере­чень опций мож­но най­ти в офи­ци­аль­ном руко­вод­стве.

Rules

В дан­ном фай­ле мы зада­ем пове­де­ние при ком­пи­ля­ции паке­та. Как пра­ви­ло, его содер­жи­мое сво­дит­ся к:

* отсту­пы долж­ны быть табу­ля­ци­я­ми, ина­че систе­ма вер­нет ошибку.

… что озна­ча­ет, что все дей­ствия по уста­нов­ке паке­та из исход­ни­ка долж­ны быть шаблонные.

При ком­пи­ля­ции будет запу­ще­но три груп­пы команд:

  1. debian/rules clean. Выпол­ня­ет чист­ку ката­ло­га сбор­ки и его подготовку.
  2. debian/rules build. Под­го­тов­ка к сбор­ке и сборка.
  3. debian/rules binary. Уста­нов­ка и созда­ние бинар­но­го пакета.

У каж­дой выше озву­чен­ной груп­пы есть свои эта­пы, через кото­рые про­хо­дит про­цесс сбор­ки. Подроб­нее про дан­ные эта­пы мож­но почи­тать на сай­те debian.org.

Одна­ко, для каж­до­го из эта­пов мы можем пере­опре­де­лять пове­де­ние и зада­вать настрой­ки (с помо­щью при­став­ки override_ в фай­ле). Рас­смот­рим при­ме­ры неко­то­рых эта­пов и настроек.

Ката­лог источника

Зада­ет­ся с помо­щью пара­мет­ра --sourcedirectory, напри­мер:
dh $@ --sourcedirectory=src/

* в дан­ном при­ме­ре мы ука­жем сбор­щи­ку, что брать исход­ные фай­лы нуж­но в ката­ло­ге src (отно­си­тель­но рабо­че­го ката­ло­га). При таком опре­де­ле­нии источ­ни­ка, не забы­ва­ем зара­нее создать ката­лог (в дан­ном при­ме­ре, mkdir src).

override_dh_auto_configure

Выпол­ня­ет кон­фи­гу­ри­ро­ва­ние. Нам может потре­бо­вать­ся изме­нить опции на свои, например:
override_dh_auto_configure:
cd src/ && ./configure --prefix=/usr

* обра­ти­те вни­ма­ние, что если у нас исход­ник нахо­дит­ся в отдель­ном ката­ло­ге, мы долж­ны перей­ти в него и сра­зу (&&) запу­стить коман­ду для кон­фи­гу­ри­ро­ва­ния. Если эти коман­ды вве­сти в раз­ных стро­ках, то мы полу­чим ошиб­ку — перед выпол­не­ни­ем каж­дой коман­ды сбор­щик воз­вра­ща­ет­ся в исход­ную директорию.

dh_auto_build

На дан­ном эта­пе выпол­ня­ет­ся сбор­ка (make). Мож­но перед этим про­цес­сом зака­чи­вать исход­ник и рас­па­ко­вы­вать его в ката­лог src:

* в конеч­ном ито­ге, мы запус­ка­ем тот же dh_auto_build, но с пере­да­чей допол­ни­тель­ной опции.

dh_auto_test

Выпол­ня­ем цель test фай­ла Makefile. Ино­гда, в про­цес­се сбор­ки паке­та на дан­ном эта­пе воз­вра­ща­ет­ся ошиб­ка, хотя сама по себе ком­пи­ля­ция и сбор­ка про­шли кор­рект­но. В таком слу­чае, этап мож­но пропустить:

* для про­пус­ка любо­го из эта­пов про­сто встав­ля­ем соот­вет­ству­ю­щую стро­ку с пустым переч­нем действий.

dh_auto_install

На дан­ном эта­пе выпол­ня­ет­ся уста­нов­ка паке­та (make install). Рас­смот­рим такой пример:

* такая настрой­ка выпол­нит уста­нов­ку, пере­дав коман­де make install допол­ни­тель­ный пара­метр PG_CONFIG=/opt/pgpro/std-11/bin/pg_config. На прак­ти­ке, эта опция зада­ет путь рас­по­ло­же­ния кон­фи­га postgresql pro.

dh_fixperms

Зада­ет стан­дарт­ные пра­ва на фай­лы. Мы же можем захо­теть назна­чить свои или отдель­но­го вла­дель­ца, например:

* в дан­ном при­ме­ре всем фай­лам внут­ри ката­ло­га будет задан вла­де­лец поль­зо­ва­тель nginx. Обра­ти­те вни­ма­ние, что мы сна­ча­ла поз­во­ля­ем систе­ме выста­вить пра­ва по сво­е­му алго­рит­му (dh_fixperms), после чего выпол­ня­ем свою команду.

Changelog

Файл исполь­зу­ет­ся систе­мой сбор­ки для полу­че­ния номе­ра вер­сии паке­та, его реви­зии, сроч­но­сти и раз­де­ла. Так­же в него мож­но зано­сить спи­сок изменений.

Типич­ный при­мер для файла:

gentoo (0.9.12-1) unstable; urgency=medium

* Initial release. (Closes: #nnnn)  <nnnn is the bug number of your ITP>

-- Josip Rodin <joy-mg@debian.org>  Mon, 22 Mar 2010 00:37:31 +0100

* где:

  • пер­вая строч­ка ука­зы­ва­ет на: 
    • имя паке­та (gentoo).
    • вер­сию (0.9.12-1).
    • релиз (unstable).
    • важ­ность паке­та (urgency=medium).
  • вто­рая стро­ка явля­ет­ся при­ме­ром для опи­са­ния изме­не­ния. Таких строк, начи­на­ю­щих­ся со звез­доч­ки, может быть несколько.
  • тре­тья стро­ка — имя и адрес авто­ра пра­вок и дата редактирования.