Описание процесса сборки пакета deb

Обновлено Обновлено: Опубликовано Опубликовано:

Данная инструкция является шпаргалкой по сборке пакетов для deb-систем (Debian, Ubuntu, Mint и так далее). Мы рассмотрим пример работы с исходниками nginx, а также разберем подробнее опции, которые можно задействовать при сборке. Важно отметить, что уже собранный nginx можно получить на сайте разработчика или в репозитории системы, но мы хотим понять процесс сборки, а это удобнее делать на хорошо знакомом пакете.

Сама сборка будет выполняться с помощью debhelper — набора программ, который помогает автоматизировать ряд задач по подготовке и упаковке пакета.

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

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

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

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

apt update

apt install dpkg-dev devscripts equivs wget

* где: 

  • dpkg-dev — содержит набор инструментов для работы с исходными файлами для пакетов deb.
  • devscripts — набор скриптов для сборки пакетов.
  • equivs — необходим для запуска утилиты mk-build-deps для установки зависимых пакетов.
  • 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

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

Source:                 nginx
Section:                misc
Priority:               optional
Maintainer:             Dmitriy Moks <master@dmosk.ru>
Build-Depends:          libpcre3-dev,
                        zlib1g-dev
Standards-Version:      1.20.1
Homepage:               https://nginx.org

Package:                nginx
Architecture:           amd64
Provides:               nginx
Description: NGINX packages.
 The description can be written in several lines.
 Each line have to be 73 chars maximum.

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

2. Файл changelog.

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

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

vi debian/changelog

nginx (1.20.1) stable; urgency=medium
  * Initial release
 -- Dmitriy Mosk <master@dmosk.ru>  Tue, 03 Aug 2021 17:34:42 +0300

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

3. Файл rules.

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

vi debian/rules

#!/usr/bin/make -f
export DH_VERBOSE = 1

url='http://nginx.org/download/nginx-1.20.1.tar.gz'
build_dir='nginx'

override_dh_auto_clean:
	if [ ! -f $(build_dir) ]; then rm -rf $(build_dir); fi
	mkdir $(build_dir)
	dh_auto_clean

override_dh_auto_configure:
	wget $(url) -O $(build_dir).tar.gz
	tar -xzf $(build_dir).tar.gz -C $(build_dir)/ --strip-components=1
	rm -f $(build_dir).tar.gz
	cd $(build_dir) && ./configure

override_dh_usrlocal:

%:
	dh $@ --sourcedirectory=$(build_dir)/

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

4. Файл compat.

Указываем на уровень совместимости с debhelper. Другими словами, какой версии debhelper соответствует процесс сборки. На это влияет, какие хелперы будут запускаться и как будет проходить сборка.

Создаем файл:

vi debian/compat

12

* нам необходимо использовать номер в соответствии с версией debhelper, для который мы писали правила сборки. Если мы укажем, скажем, 13, а тестировали сборку и правила на версии 9, то можем получить ряд ошибок.

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

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

1. Файл postinst.

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

vi debian/postinst

#!/bin/sh
# postinst script for dmosk
#
# see: dh_installdeb(1)

set -e

useradd dmosk

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

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

...

case "$1" in
    configure)
        systemctl is-enabled --quiet nginx && systemctl disable nginx        
    ;;

    abort-upgrade|abort-remove|abort-deconfigure)
    ;;

    upgrade)
        systemctl is-active --quiet nginx
    ;;

    *)
        echo "postinst called with unknown argument \`$1'" >&2
        exit 1
    ;;
esac

exit 0

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

2. Файл postrm.

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

vi debian/postrm

#!/bin/sh -e
# postrm script for dmosk
#
# see: dh_installdeb(1)

case "$1" in
    purge|remove|abort-install|disappear)
        rm -rf /var/log/app
        rm -rf /opt/app/test
    ;;

    upgrade|failed-upgrade|abort-upgrade)
    ;;

    *)
        echo "postrm called with unknown argument \`$1'" >&2
        exit 1
    ;;
esac

exit 0

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

3. Файл preinst.

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

4. Файл prerm.

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

vi debian/prerm

#!/bin/sh -e
# prerm script for dmosk
#
# see: dh_installdeb(1)

case "$1" in
    purge|remove|abort-install|disappear)
        systemctl is-active --quiet nginx && systemctl stop nginx &>/dev/null || :
    ;;

    upgrade|failed-upgrade|abort-upgrade)
    ;;

    *)
        echo "prerm called with unknown argument \`$1'" >&2
        exit 1
    ;;
esac

exit 0

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

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

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

mk-build-deps --install

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

Для запуска утилиты в тихом режиме (без запросов на подтверждения) команду можно ввести так:

echo yes | mk-build-deps -ri

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

debuild -us -uc -b

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

W: nginx: missing-depends-line
E: nginx: dir-in-usr-local usr/local/nginx/logs/
E: nginx: dir-in-usr-local usr/local/nginx/sbin/
E: nginx: file-in-usr-local usr/local/nginx/sbin/nginx
W: nginx: file-in-unusual-dir usr/local/nginx/sbin/nginx
Finished running lintian.

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

ls ../

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

nginx-1.20.1               nginx_1.20.1_amd64.build      nginx_1.20.1_amd64.changes
nginx-dbgsym_1.20.1_amd64.deb  nginx_1.20.1_amd64.buildinfo  nginx_1.20.1_amd64.deb

Пример сборки из исходных файлов

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

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

Откроем файл:

vi debian/rules

И приведем его к виду:

#!/usr/bin/make -f
#export DH_VERBOSE = 1

build_dir=debian/PKG_NAME
PKG_PREFIX=/opt/PKG_NAME

override_dh_install:
	mkdir -p $(build_dir)/$(PKG_PREFIX) || :
	mkdir -p $(build_dir)/usr/share/doc/PKG_NAME || :
	cp /PKG_SOURCE/install/* $(build_dir)/$(PKG_PREFIX)/
	cp /PKG_SOURCE/DOC/* $(build_dir)/usr/share/doc/PKG_NAME/
	cp /PKG_SOURCE/scripts/*.sh $(build_dir)/$(PKG_PREFIX)/

override_dh_fixperms:
	dh_fixperms
	find $(build_dir)/ -type f -exec chmod 644 {} \;
	find $(build_dir)/ -type d -exec chmod 755 {} \;
	chmod +x $(build_dir)/$(PKG_PREFIX)/*.sh
	chown root:root -R $(build_dir)

%:
	dh $@

Остальные файлы и запуск сборки были нами рассмотрены выше. Мы же разберем подробнее, что происходит в текущем примере.

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

  • Все файлы из папки /PKG_SOURCE/install.
  • Все скрипты из папки /PKG_SOURCE/scripts.

Документацию из каталога /PKG_SOURCE/DOC мы должны поместить в /usr/share/doc/PKG_NAME (где PKG_NAME — название для нашего пакета).

Теперь по сценарию сборки. Мы переопределили поведение dh_install — создали каталоги для размещения файлов и документации. Обратите внимание, что сборка идет относительно базового каталога debian/<название пакета>.

Также мы немного поменяли выполнение dh_fixperms, а именно, всем файлам назвачили права 644, а всем каталогам 755. Скриптам мы добавили возможность запуска (+x).

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

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

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

Control

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

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

Опция Описание Пример
Source Определяет имя пакета источника. nginx
Maintainer Имя и адрес электронной почты сборщика пакета. Dmitriy Moks <master@dmosk.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, php — в данном примере мы трубем, чтобы были установлены php и одни из веб-серверов (apache2 или httpd).
3. Указание версии: libpcre3-dev (= 13), zlib1g-dev (> 14),
                                  apache2 (>= 15), 
                                  httpd (< 16),
                                  nginx (<= 17)
(обратите внимание, данный перечень можно записать через запятую в одну строчку или по одной/несколько пакетов на каждой строчке также через запятую).
Standards-Version Указывает на версию пакета.
Homepage Домашняя страница для собираемого пакета.
Provides Имя пакета, под которым будет зарегистрировано приложение после установки. Как правило, указывается таким же, как и имя собираемого пакета. Но в редких случаях, может понадобиться поменять на свое.
Depends Список пакетов, которые требуются для установки собираемого пакета на конечной системе. Также как и в Build-Depends, возможен разный формат написания.
Conflicts Пакеты, которые будут удалены при установке нашего пакета.
Description Произвольное описание для пакета. Необходимо проследить, чтобы размер одной строки не превышал 73 символа. Каждая последующая строка описания должна начинаться, как минимум, с одного пробела.

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

Rules

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

%:
	dh $@

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

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

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

  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

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

dh_auto_build

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

override_dh_auto_build:
	dh_auto_build -- PG_CONFIG=/opt/pgpro/std-11/bin/pg_config

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

dh_auto_test

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

override_dh_auto_test:

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

dh_auto_install

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

override_dh_auto_install:
	dh_auto_install -- PG_CONFIG=/opt/pgpro/std-11/bin/pg_config

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

dh_fixperms

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

override_dh_fixperms:
	dh_fixperms
	chown nginx:nginx -R nginx

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

override_dh_gencontrol

Позволяет создать или переопределить некоторые опции в файле control, например:

override_dh_gencontrol:
	dh_gencontrol -- -DSource="$(PKG_NAME)" -DDepends:"$(DEPENDS)"

* в данном примере мы меняем значения некоторым полям:

  • Package — на значение переменной PKG_NAME.
  • Depends — на значение переменной DEPENDS.

Сами переменные мы можем передать при запуске сборки. Подробнее процедура описана ниже.

Также данную команду можно выполнять из командной строки операционной системы. Это может оказаться полезным, если нужно создать контрол-файл при сборке. Например:

dh_gencontrol -- -DBuild-Depends="postgresql-server-dev-16" -Otmp_control

echo yes | mk-build-deps -ri tmp_control

* в данном примере мы взяли за основу файл по умолчанию (debian/control) и на его основе создали новый tmp_control, в котором переопределили поле Build-Depends. После мы использовали новый контрол-файл для запуска утилиты mk-build-deps, которая устанавливает пакеты, необходимые для сборки (перечислены в поле Build-Depends).

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).
  • вторая строка является примером для описания изменения. Таких строк, начинающихся со звездочки, может быть несколько.
  • третья строка — имя и адрес автора правок и дата редактирования.

Описание дополнительных файлов

Ранее мы уже говорили о таких файлах, как:

  • postinst — скрипт для запуска после установки пакета на целевой системе.
  • postrm — выполнится после удаления пакета.
  • preinst — скрипт выполнения перед установкой пакета.
  • prerm — скрипт выполнения перед удалением пакета

Это дополнительные файлы, которые помогут нам сделать пакет более функциональным и удобным.

Рассмотрим еще несколько дополнительных файлов.

Copyright

Содержит информацию об авторских правах и лицензии исходников. К данному файлу предъявляются требования по содержимому и оформлению. Подробнее можно почитать на странице Machine-readable debian/copyright file.

Файл copyright необходимо размещать в каталоге debian. Мы можем это сделать заранее или во время сборки (командой в файле rules).

Conffiles

Позволяет отметить файлы как конфигурационные. Такие файлы не будут удалены при деинсталляции пакета или заменены при обновлении. Важно знать, что программа dh_installdeb, которая помечает файлы как конфигурационные автоматически делает отметку для содержимого каталога /etc. Поэтому, нам не нужно создавать conffiles, если наши конфиги находятся в каталоге /etc.

Пример содержимого файла:

/opt/package_name/conf/package.conf
/opt/package_name/.config

$mypackage.links

Название файла состоит из названия пакета + .links. Позволяет создать символьные ссылки при установке пакета. Например:

vi debian/package_name.links

/opt/package_name/mybin /usr/bin/mybin

* в нашем примере будет создаваться симлинк /usr/bin/mybin из файла /opt/package_name/mybin.

Несколько пакетов за одну сборку

Debhelper позволяет использование нескольких блоков Package в контрол-файле для создания множества пакетов за одну сборку.

Например:

...
Package: package1
Architecture: amd64
Depends: wget
Description: This is package1.

Package: package2
Architecture: amd64
Depends: curl
Description: This is package2.

Package: package3
Architecture: amd64
Depends: nettools
Description: This is package3.

В данном примере мы перечислили 3 пакета с условными названиями package1, package2 и package3.

Чтобы пакеты были собраны корректно, установка должна быть выполнена в 3 каталога:

  1. debian/package1.
  2. debian/package2.
  3. debian/package3.

В rules мы можем добиться этого с помощью хелпера dh_auto_install и опции destdir, например:

override_dh_auto_install:
	dh_auto_install --sourcedirectory=spackage1 --destdir debian/package1
	dh_auto_install --sourcedirectory=spackage2 --destdir debian/package2
	dh_auto_install --sourcedirectory=spackage3 --destdir debian/package3

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

Применение патчей во время создания пакета

Предположим, мы обнаружили недочет в исходнике, который хотим исправить в процессе сборки пакета. Лучше всего изменения в исходный код вносить с помощью патчей. Инструмент debhelper позволяет применять исправления без необходимости описывать процесс в правилах rules. Для этого используется хелпер dh_quilt_patch.

Настройка применения патча будет состоять из следующих шагов:

  1. Создание diff-файла, который и будет патчем.
  2. Установка служебного пакета.
  3. Создание дополнительных файлов в каталоге debian.
  4. Редактирование rules для указания точки применения патча.

Рассмотрим процесс по шагам.

Создание патча

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

  • Makefile
  • Makefile.patched

Где Makefile — исходный, а Makefile.patched с исправлениями. Теперь выполним команду:

diff -Naur Makefile Makefile.patched > malefile.patch

Полученный файл malefile.patch будет, примерно, такого вида:

--- Makefile    2024-05-07 18:43:09.671504221 +0300
+++ Makefile.patched   2024-05-08 16:00:24.757681404 +0300
@@ -13,6 +13,6 @@
 PG_CPPFLAGS+= -DDO_DEBUG -g
 endif

-PGXS := $(shell pg_config --pgxs)
+PGXS := $(shell $(PG_CONFIG) --pgxs)
 include $(PGXS)

* если применить данный патч, то он попробует обнаружить в текущей директории файл Makefile, в нем найти строку PGXS := $(shell pg_config --pgxs) и заменить ее на PGXS := $(shell $(PG_CONFIG) --pgxs).

Патч готов.

Установка quilt

Как было сказано выше, для применения патча используется хелпер dh_quilt_patch. Для его работы необходим пакет quilt.

Выполняем установку командой:

apt update

apt install quilt

Более того, хорошей идеей будет добавить в control файл зависимость от данного пакета.

vi debian/control

Build-Depends: ..., quilt

Настройка хелпера

В каталоге debian нужно создать папку patches. В ней хранятся все патчи, которые могут использоваться для сборки:

mkdir debian/patches

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

mv malefile.patch debian/patches/

Рядом создаем файл series:

vi debian/patches/series

malefile.patch

* в нем мы перечисляем в порядке применения все патчи, которые должен использовать хелпер dh_quilt_patch. В нашем примере должен использоваться только один патч.

Важно отметить, что мы создавали патч, когда оригинал и исправленный файл были в одном каталоге. Поэтому путь до файла в патче такой:

--- Makefile

Это означает, что dh_quilt_patch должен применить исправления в файле, который находится в каталоге выполнения сборки. На практике, это будет не так и нам как администраторам сценария сборки необходимо разобраться, какой указать путь. 

Например, в моем случае исходник размещался в каталоге src. Поэтому к пути я добавил:

--- src/Makefile

Это не помогло, так как сборка выполняется в каталоге debian, то есть, нам нужно из нее выйти:

--- ../src/Makefile

Вот такое исправление пути в патче решило проблему с путем в моем случае.

Редактируем rules

Хелпер dh_quilt_patch не вызывается самостоятельно и должен применяться вручную. В rules мы можем вызвать его на нужном этапе или запустить dh с опцией --with quilt.

Предположим, что нам нужно применить патч до выполнения make. Тогда в добавляем, примерно, следующее:

vi debian/rules

override_dh_auto_build:
	dh_quilt_patch
	dh_auto_build

* в данном примере мы переопределям хелпер dh_auto_build — сначала указываем, что должен отработать dh_quilt_patch, а после уже сам dh_auto_build.

Или:

%:
	dh $@ --with quilt

Готово. Теперь во время сборки будет вызван хелпер dh_auto_build, который найдет файл debian/patches/series, в нем список патчей и применит их по очереди.

Дополнительно

В данном разделе опишем некоторые полезные возможности.

1. Передача переменной.

При запуске сборки может понадобиться передать переменную, значение которой будет использоваться в нашем скрипте rules. Это делается с помощью опции -e:

debuild -e<var_name>=<var_value> -us -uc -b

Например:

debuild -eRELEASE=Ubuntu -eVERSION=22.04 -us -uc -b

* в нашем примере мы передали 2 переменные release и version.

В файле rules можно использовать данные переменные, например:

echo $(RELEASE)
echo $(VERSION)

* применение не самое практичное, но для нашего примера достаточно.

2. Команда для редактирования Changelog.

Как было сказано выше, файл Changelog нужен для описания верий и изменений пакета. Для упрощения автоматизации работы со сборками, есть команда dch, которая сама вносит изменения в данный файл.

Например:

dch -m -v "1.5.5" -D "stable" "Fix errors"

... добавит строку с версией 1.5.5 и описанием Fix errors.

А если у нас нет файла debian/changelog, то его также можно создать с помощью команды dch:

dch --create --package pkg_name -m -v "1.5.5" -D "stable" "Fix errors"

3. Не создавать файлы dbgsym.

По умолчанию в результате работы debuild создается не только пакет установки, но и пакет с символами отладки (dbgsym или Debug symbol packages). Данный пакет не рекомендуется устанавливать в продуктивной среде, но он полезен для тестовой среды.

Чтобы не выполнять сборку данных пакетов, необходимо задать системную переменную DEB_BUILD_OPTIONS со значением noautodbgsym.

Например, команда сборки может быть запущена так:

DEB_BUILD_OPTIONS=noautodbgsym debuild -us -uc -b

Возможные ошибки

Рассмотрим некоторые проблемы, с которыми мы можем столкнуться в процессе сборки пакетов deb.

1. dpkg-shlibdeps: error: cannot find library

Причина: после сборки и установки пакетов сборщик проверяет наличие библиотек, которые нужны устанавливаемым файлам. На основе этого строятся зависимости при установке нашего собираемого пакета. Однако, хелпер shlibdeps ищет только в известных ему местах, а необходимые библиотеки могут располагаться в альтернативных каталогах, например /opt.

Решение: мы можем переопределить запуск хелпера shlibdeps, указав ему пути, где нужно искать библиотеки:

override_dh_shlibdeps:
    dh_shlibdeps -l /usr/local/lib -l /usr/local/lib64 -l $(shell pwd)/debian/lib

* в нашем примере мы указали три каталога, где нужно выполнить поиск — /usr/local/lib/usr/local/lib64 и lib, которая находится в рабочем каталоге debian.

2. Ошибка dh_dwz

На стадии сборки dh_dwz вылетает ошибка returned exit code 1.

Причина: модуль dh_dwz отвечает за оптимизацю отладочных файлов debug_info, чтобы сделать файлы dbgsym меньше. Но если отладочной информации нет, некоторые версии debhelper завершают свою работу с ошибкой.

Решение: мы можем либо обновить debhelper, либо переопределить выполнение dh_dwz. Для этого в файл rules добавим строку:

override_dh_dwz:

3. dir-or-file-in-opt

Скорее, это не ошибка, а предупреждение, когда наш пакет будет устанавливаться в каталог /opt.

Причина: по спецификации DEB не рекомендуется использовать каталог /opt в качестве пути для установки приложения из пакета.

Решение: если мы точно понимаем, что наше приложение должно устанавливаться в каталог /opt, то просто подавляем вывод предупреждения с помощью файла debian/<package>.lintian-overrides.

 Например, в нашем случае, для пакета nginx создаем файл:

vi debian/nginx.lintian-overrides

nginx: dir-or-file-in-opt

Теперь при сборке пакета nginx предупреждение dir-or-file-in-opt не будет отображаться в консоли.

Читайте также

1. Пример сборки RPM и Deb пакетов в Gradle

2. Создание RPM-пакетов с нуля на примерах.

3. Сборка своего RPM-пакета на примере NGINX.

# DevOps # Linux
Дмитрий Моск — частный мастер
Была ли полезна вам эта инструкция?

Да            Нет