Еще раз о deb пакетах
Чтобы начать создавать deb пакеты, нужно установить несколько пакетов:
$ sudo apt-get install dh_make
Подготовка папки с исходниками
Для того, чтобы dh_make и другие утилиты могли работать с папкой с исходниками, нужно привести ее в специфичный вид.
Папка должна называться имяпакета-версия. Т.е. если у меня есть папка Plugins с программой версии 0.1, то я создаю папку с именем plugins-0.1.
$ ls VKSPlugins $ mv VKSPlugins/ libvksplugins-0.1 $ ls libvksplugins-0.1
Теперь нужно создать архив с этой папкой. Архив должен содержать в имени *.orig.tar.gz, т.е.:
$ tar -zcf libvksplugins_0.1.orig.tar.gz libvksplugins-0.1 $ ls libvksplugins-0.1 libvksplugins_0.1.orig.tar.gz
Последний подготовительный шаг, это создание в папке с исходниками папки debian со множеством служебных файлов. Чтобы это сделать, нужно выполнить команду:
$ cd libvksplugins-0.1/ $ dh_make Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch? [s/i/m/l/k/n] l Maintainer name : User Name Email-Address : user@name.ru Date : Wed, 19 Aug 2015 14:55:53 +0300 Package Name : libvksplugins Version : 0.1 License : blank Type of Package : Single Hit to confirm: Skipping creating ../libvksplugins_0.1.orig.tar.gz because it already exists Done. Please edit the files in the debian/ subdirectory now. plugins uses a configure script, so you probably don’t have to edit the Makefiles.
В процессе выполнения этой команды будет задан вопрос о том, какой тип архива мы создаем, самый простой это single.
О типе пакета
На самом деле документация говорит, выбирать вариант только single. Т.к. я не смог понять всех требований к пакету типа library но меня вполне устраивает результат, то описание и дальше пойдет про пакет типа library.
Настройка пакета
Вся настройка пакета происходит путем редактирования файлов в каталоге debian. Рассмотрим те файлы, которые будем использовать:
- changelog — история пакета.
- control — главный конфиг пакета;
- rules — аналог Makefile для пакета;
changelog
Данный файл содержит историю изменения пакета и текущую версию пакета. Посмотрим на его содержимое:
$ cat changelog libvksplugins (0.1-1) unstable; urgency=low * Initial release (Closes: #nnnn) -- User Name Wed, 19 Aug 2015 15:03:51 +0300
В начале идет название пакета — libvksplugins, затем его версия. Версия делиться на две части символом «-». Первая часть показывает версию программы в пакете, вторая «ревизию» пакета. Ревизия это версия пакета, т.е. если раньше такого пакета не было, то ревизия равна 1. Если же пакет с такой версией программы уже был, но в нем произошли изменения, то ревизия увеличивается.
Слово unstable показывает, что пакет является не стабильным, т.е. он не был протестирован должным образом на машинах пользователей.
Надпись urgency=low показывает срочность изменения. Т.к. срочности нет, то значение равно low. Если бы, мы делали пакет для исправления серьезной уязвимости или ошибки, то значение можно было бы установить в high.
После первой строки идет пустая строка, а за ней первая запись:
* Initial release (Closes: #nnnn)
В Debian, changelog используется для автоматического закрытия ошибок в системах отслеживания ошибок в программных продуктах. Т.к. в данном случае, я не использую такую систему, то эта строка принимает вид:
Замечание
При проверке пакета программой lintian, отсутствие Closes: #XXXX считается ошибкой.
Последняя строка является подписью человека, сделавшего запись. В ней содержится имя и адрес, а также дата изменения.
После установки deb пакета, файл changelog устанавливается в
control
Файл debian/control является главным конфигом, при создании deb пакета. Вот пример такого файла:
$ cat control Source: libvksplugins Priority: optional Maintainer: User Name Build-Depends: debhelper (>= 9), cmake Standards-Version: 3.9.5 Section: libs Homepage: #Vcs-Git: git://anonscm.debian.org/collab-maint/plugins.git #Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/plugins.git;a=summary Package: libvksplugins-dev Section: libdevel Architecture: any Depends: libvkspluginsBROKEN (= $), $ Description: Package: libvkspluginsBROKEN Architecture: any Depends: $, $ Description:
Видно, что файл разбит на секции при помощи пустых строк. Каждая секция описывает один пакет, создаваемый из папки с исходниками. Рассмотрим их по порядку:
Source Данная секция говорит о том, что нужно создать пакет исходных кодов. Параметром указано libvksplugins, это значит, что пакет исходных кодов будет называться libvksplugins.
Priority Эта секция устанавливает приоритет пакета. Т.к. система может прекрасно обойтись без нового пакета, то значение секции установлено в optional. Т.е. этот пакет не обязателен для установки. Подробнее о приоритетах написано здесь.
Maintainer Эта секция описывает контакты человека, создающего пакет. Ее формат довольно прост и дополнительного описание не требует.
Build-Depends Одна из самых важных секций, устанавливающая зависимости пакета. Зависимости, указанные в данной секции должны быть выполнены, чтобы можно было собрать пакет. Т.е. список зависимостей для сборки и установки могут отличаться.
Видно, что в зависимостях стоят debhelper (>= 9), cmake. Зависимость debhelper (>= 9) ставиться для всех пакетов по умолчанию. Она нужна для корректной работы программ вида dh_*.
Второй элемент cmake был добавлен потому, что папка с исходниками содержала файл CMakeLists.txt, т.е. для сборки используется система сборки CMake. Для того, чтобы узнать, какие зависимости есть у программы, можно почитать ее документацию. Кроме этого, можно воспользоваться командой dpkg-depcheck. Данная команда должна запускаться так:
$ dpkg-depcheck -d ./configure
Но, т.к. при использовании CMake нет скрипта конфигурирования, то я использую ее так:
$ mkdir build && cd build $ dpkg-depcheck -d cmake ../ . Packages needed: libxml2:amd64 cmake libkrb5support0:amd64 language-pack-ru-base libnettle4:amd64 . libedit2:amd64 libtasn1-6:amd64 qt4-qmake libgssapi-krb5-2:amd64 libhcrypto4-heimdal:amd64 . libroken18-heimdal:amd64 libsqlite3-0:amd64 libqt4-dev libssl1.0.0:amd64 .
Из примечательных тут можно отметить:
cmake
qt4-qmake
libqt4-dev
Остальные являются зависимостями данных. Причем, cmake уже есть в списке зависимостей сборки. В принципе, можно его оставить как есть или указать используемую версию:
$ apt-cache show cmake | grep Version: Version: 2.8.12.2-0ubuntu6
При этом в CMakeLists.txt указана версия cmake, которую нужно использовать:
$ cat CMakeLists.txt | grep cmake_minimum cmake_minimum_required(VERSION 2.8.4)
Я думаю, что разработчику виднее, и поэтому указываю версию из CMakeLists.txt. Для Qt 4 все понятно с номерами версий, но для очистки совести проверим и их версии:
$ apt-cache show qt4-qmake | grep Version: Version: 4:4.8.6+git49-gbc62005+dfsg-1ubuntu1.1 Version: 4:4.8.6+git49-gbc62005+dfsg-1ubuntu1 $ apt-cache show libqt4-dev | grep Version: Version: 4:4.8.6+git49-gbc62005+dfsg-1ubuntu1.1 Version: 4:4.8.6+git49-gbc62005+dfsg-1ubuntu1
Т.е. для Qt 4 указываем версию 4.8.6:
Build-Depends: debhelper (>= 9), cmake (>= 2.8.4), qt4-qmake (>= 4.8.6), libqt4-dev (>= 4.8.6)
Standards-Version Версия стандарта, в соответствии с которым создан файл. Это значение не нужно менять.
Section. Секция для пакета, т.е. группа пакетов, выполняющая одну задачу. В Политике Debian разделе 2.4 этот вопрос описан более подробно.
Homepage Домашняя страница проекта. Т.к. данный код писал я и у него нет страницы, просто удаляю эту строку.
Vcs-* Ссылки на репозитории проекта. Их у меня тоже нет, поэтому удаляю эти строки.
Другие пакеты После секции файла, где описывается пакет с исходниками, идут секции, которые описывают другие пакеты, создаваемые из пакета с исходниками. Схема создания пакетов:

Из схемы видно, что из исходников программы, я хочу получить 4 пакета:
- пакет с исходными кодами;
- пакет с бинарником (самой библиотекой);
- пакет для разработки (заголовочные файлы);
- пакет с документацией.
Мой персональный ответ на данный вопрос, заключается в том, что такое разбиение помогает структурировать программу по тому, как я хочу с ней работать. Для разработки я поставлю dev пакет, а для использования нет.
Кроме описанных выше пакетов, можно создать dbg пакет с отладочной сборкой программы. Это может пригодиться, если программа падает и у Вас есть под рукой отладчик. Однако, я так и не смог понять как это делать. Документация не дает ответа на этот вопрос. Если делать так как описано в ней, то я либо получаю пустой пакет либо получаю кучу ошибок при сборке.
Схема на рисунке выше показывает, что пакет с исходниками называется libvksplugins_source, однако, в файле control указано, что пакет с исходниками будет называться libvksplugins. На самом деле, он действительно будет называться libvksplugins, а пакет с бинарниками, будет называться libvksplugins… deb. Суть этой путаницы в том, что пакет с исходниками представляет собой tar архив и служебные файлы, тогда как пакет бинарников это архив с расширение deb.
Настройка пакета библиотеки Посмотрим внимательно на описание пакета библиотеки:
Package: libvksplugins
Architecture: any
Depends: $, $
Description: Library for creating plugins with VKS 2
This library provides a mechanism for creating plugins
to use in project VKS 2.
Параметр Architecture устанавливает архитектуру собираемого пакета. Значение any означает, что после сборки бинарников нужная архитектура будет подставлена системой сборки. Т.е. на 64х битной машине, получится пакет . _amd64. а на 32х битной пакет . _i386. .
Для пакетов, содержащих скрипты или тексты, нужно указывать значение как all.
Третья строка, описывает зависимости создаваемого пакета. Вот как она описана в 4й главе Руководства начинающего разработчика Debian:
Утилита dh_shlibdeps вычисляет зависимости двоичного пакета от общих библиотек. Она генерирует список исполняемых файлов ELF и общих библиотек, которые находит для каждого двоичного пакета. Этот список подставляется вместо $ .
Утилита dh_perl вычисляет зависимости Perl. Она генерирует список зависимостей от perl или perlapi для каждого двоичного пакета. Этот список подставляется вместо $ .
Некоторые команды пакета debhelper могут добавлять зависимости к вашему генерируемому пакету. Каждая команда генерирует список необходимых пакетов для каждого двоичного пакета. Этот список подставляется вместо
$ .
Утилита dh_gencontrol генерирует файл DEBIAN/control для каждого двоичного пакета, заменяя $ , $ , $ и т.д на полученные значения.
Т.е. эта строка говорит о том, что сборщик пакета сам определит зависимости.
Последний раздел данной секции это описание пакета. Первая строка содержит кратное описание, последующие строки содержат более подробное описание. Подробное описание, должно иметь определенный формат:
- строка должна начинаться с пробела;
- строка не должна быть длиннее 80 символов;
- пустая строка должна начинаться с пробела и состоять из символа точки.
Package: libvksplugins-dev
Section: libdevel
Architecture: any
Depends: libvksplugins (= $), $
Description: Development package for libvksplugins
This package provides development files for
library libvksplugins.
.
Also, it contains pkg-config file, to use.
В данном примере, интересна строка Depends. В ней указано, что данный пакет будет зависеть от пакета библиотеки libvksplugins, причем (= $ ) говорит о том, что необходимо строгое совпадение версий бинарного пакета и пакета разработчика. Это важный момент потому, что заголовочные файлы должны строго соответствовать бинарникам.
Настройка пакета документации Вместе с библиотекой поставляется документация, чтобы она была в отдельном пакете, добавляем его описание:
Package: libvksplugins-doc
Architecture: all
Depends: $, $
Description: Documentation for libvksplugins
Package contains html documentation files for libvksplugins
Тут должно быть все понятно.
rules
Данный файл является аналогом Makefile для сборки пакетов. По умолчанию, он создается в таком виде:
$ cat rules #!/usr/bin/make -f # See debhelper(7) (uncomment to enable) # output every command that modifies files on the build system. #DH_VERBOSE = 1 # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk # see FEATURE AREAS in dpkg-buildflags(1) #export DEB_BUILD_MAINT_OPTIONS = hardening=+all # see ENVIRONMENT in dpkg-buildflags(1) # package maintainers to append CFLAGS #export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic # package maintainers to append LDFLAGS #export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed # main packaging script based on dh7 syntax %: dh $@ # debmake generated override targets # This is example for Cmake (See http://bugs.debian.org/641051 ) #override_dh_auto_configure: # dh_auto_configure -- \ # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH)
Видно, что это bash скрипт с синтаксисом Makefile. Единственная интересная конструкция здесь это
Это шаблон, который для всех целей вызывает dh команду с передачей аргументов ей. Для сборки пакета важно, чтобы текст dh $@ начитался с символа табуляции. Т.е. отступ это не пробелы, а табуляция.
Т.к. исходники используют систему сборки CMake, то нужно изменить эту запись следующим образом:
%: dh $@ --buildsystem=cmake
Содержимое пакетов
После того, как мы указали в debian/control какие пакеты мы хотим получить, нужно указать какие файлы в какой пакет помещать. Для этого, для каждого названия пакета из файла control, нужно создать в папке debian два файла. Первый должен называться пакет.dirs, а второй пакет.install. Суть файлов в том, что первый указывает, какие папки нужно создать для пакета, а второй, какие файлы включить в пакет.
Посмотрим на их содержимое:
$ cat libvksplugins-dev.dirs usr/lib usr/include $ cat libvksplugins-dev.install usr/include/* usr/lib/lib*.a usr/lib/lib*.so usr/lib/pkgconfig/* usr/share/pkgconfig/*
Важный момент, отсутствие начальной дроби в путях и отсутствие дроби в конце пути к папке. Проверив, куда CMake устанавливает файлы библиотеки, можно сформировать такие файлы:
$ for item in $(ls libvksplugins*); do echo "$item:"; cat $item; done libvksplugins-dev.dirs: usr/include/dep572 usr/lib/pkgconfig libvksplugins-dev.install: usr/include/dep572/plugins/* usr/lib/dep572/lib*.so usr/lib/pkgconfig/* libvksplugins.dirs: usr/lib/dep572 libvksplugins-doc.dirs: usr/share/doc/libplugins-0.1 libvksplugins-doc.install: usr/share/doc/libplugins-0.1/*.tgz libvksplugins.install: usr/lib/dep572/lib*.so.*
Завершение настройки
Т.к. исходники мои, то никаких дополнительных описаний и ограничений copyright у меня нет, поэтому я удаляю все лишние файлы из каталога debian.
Сборка пакетов
После настройки, сборка пакетов происходит довольно просто, нужно в папке проекта (которая включает подпапку debian) выполнить команду:
$ dpkg-buildpackage -rfakeroot -us -uc
Параметры -us -uc говорят о том, что не нужно подписывать gpg ключом созданные пакеты. Их можно не использовать, если настроен ключ подписи gpg по умолчанию. Как указать ключ подписи по умолчанию, я тоже не понял. Если все прошло хорошо, то у нас поваляется набор пакетов в папке выше:
$ ls -l ../ итого 748 drwxrwxr-x 10 user user 4096 авг. 20 10:46 libvksplugins-0.1 -rw-rw-r-- 1 user user 2210 авг. 20 10:47 libvksplugins_0.1-1_amd64.changes -rw-r--r-- 1 user user 6418 авг. 20 10:47 libvksplugins_0.1-1_amd64.deb -rw-rw-r-- 1 user user 1504 авг. 20 10:46 libvksplugins_0.1-1.debian.tar.xz -rw-rw-r-- 1 user user 1008 авг. 20 10:46 libvksplugins_0.1-1.dsc -rw-rw-r-- 1 user user 36713 авг. 19 14:52 libvksplugins_0.1.orig.tar.gz -rw-r--r-- 1 user user 3262 авг. 20 10:47 libvksplugins-dev_0.1-1_amd64.deb -rw-r--r-- 1 user user 699564 авг. 20 10:47 libvksplugins-doc_0.1-1_all.deb
Заключение
Если вы дочитали до сюда — значит вы любите читать.
Этот текст является результатом моего опыта внедрения deb пакетов на работе. Опыт показал, что наличие сетевого репозитория (reprepro) и внимательное отслеживание версий, позволяют без проблем обновлять и тестировать различные версии ПО на парке из 30 машин с системами Astra Linux 1.3, 1.4 и Эльбрус ОС.
Описание процесса сборки пакета deb

Обновлено: 26.05.2023 Опубликовано: 11.08.2021
Данная инструкция является шпаргалкой по сборке пакетов для deb-систем (Debian, Ubuntu, Mint и так далее). Мы рассмотрим пример работы с исходниками nginx, а также разберем подробнее опции, которые можно задействовать при сборке. На практике, данное действие не имеет смысла, так как уже собранный nginx можно получить на сайте разработчика или в репозитории системы, но для нас важно понять процесс сборки, после чего можно будет применить данные знания для своих проектов.
Подготовка системы
Процесс сборки требует установки дополнительных компонентов, что приводит к скоплению мусора из ненужных пакетов. Рекомендуется делать сборку на отдельном компьютере или в контейнере 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 сразу создаст домашний каталог для пользователя.
Теперь заходим под данным пользователем — последующие команды мы будем выполнять от него:
3. Создадим каталог, в котором будет происходит сборка:
mkdir -p debbuild
Перейдем в debbuild:
Мы готовы к сборке.
Сборка из исходников
В нашем примере мы возьмем исходники для сборки nginx (для выполнения configure, make, make install . ) и соберем из них свой пакет для установки NGINX. Процесс будет разбит на несколько этапов:
- Предварительная настройка.
- Создание файлов с инструкциями для сборки пакета.
- Выполнение сборки и проверки.
Рассмотрим каждый из этапов подробнее.
Подготовка
Создадим каталог с названием собираемого приложения (с учетом версии):
mkdir -p nginx-1.20.1/debian
* в нем обязательно каталог debian.
Перейдем в созданный каталог:
Теперь создадим несколько важных файлов.
Создание файлов сборки (основные)
Для выполнения сборки нужно создать, минимум, 4 файла.
1. Control-файл.
Это основной файл с описанием процесса сборки. Вводим:
Пример для нашего случая:
Source: nginx
Section: misc
Priority: optional
Maintainer: Dmitriy Moks
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.
В данном файле описывается история изменений пакета. Также сборщик берет из этого файла номер версии и релиза.
Создаем файл командой:
nginx (1.20.1) stable; urgency=medium
* Initial release
— Dmitriy Mosk Tue, 03 Aug 2021 17:34:42 +0300
* в файле указано, что первые изменения внес Dmitriy Mosk 03 августа. Для начала сборки этого будет достаточно. Описание ниже.
3. Файл 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 (вспомогательный инструмент для сборки пакетов). Создаем файл:
* нам необходимо использовать версию в соответствии с версией Debian, на основе которой организован дистрибутив Linux, в котором идет сборка — в нашем примере 9. Сама по себе сборка без данного файла (или при указании версии ниже текущей, на дистрибутиве которого собирается пакет) запустится, но быстро остановится с ошибкой dh_auto_clean: Compatibility levels before 9 are deprecated (level X in use), где Х — текущий уровень совместимости.
Дополнительные файлы сборки
Данные файлы не являются обязательными. Они могут увеличить возможности собираемого пакета, а также нужны для нашего удобства.
1. Файл postinst.
Является скриптом, который будет запущен после установки пакета на целевой системе. Любые постинсталляционные настройки можно выполнить с его помощью, например:
#!/bin/sh
# postinst script for dmosk
#
# see: dh_installdeb(1)
* в данном примере мы просто создадим учетную запись dmosk. Опция set -e говорит о том, что при возникновении ошибки, необходимо сразу прервать работу скрипта.
Может быть использован более сложный сценарий с обработкой аргументов, например:
case «$1» in
configure)
systemctl is-enabled —quiet nginx && systemctl disable nginx
;;
upgrade)
systemctl is-active —quiet nginx
;;
*)
echo «postinst called with unknown argument \`$1′» >&2
exit 1
;;
esac
* таким образом, при установке приложения посредством, например, команды apt upgrade, после инсталляции будет выполнена только команда sytemctls is-active —quiet nginx.
2. Файл 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
;;
*)
echo «postrm called with unknown argument \`$1′» >&2
exit 1
;;
esac
* в данном примере мы предположили, что после удаления нужно удалить 2 каталога /var/log/app и /opt/app/test.
3. Файл preinst.
Скрипт выполнения перед установкой пакета.
4. Файл 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 || :
;;
*)
echo «prerm called with unknown argument \`$1′» >&2
exit 1
;;
esac
Сборка пакета
У нас созданы все необходимые файлы, выполнены предварительные действия, и мы готовы к сборке.
Проверяем, что у нас установлены необходимые пакеты и, при необходимости, установим их:
* команда является частью пакета 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.
Пакет сформирован и должен находится в директории на уровень ниже:
Среди списка файлов мы должны увидеть пакет с нашим названием:
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.
И приведем его к виду:
#!/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 |
| 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 ( (обратите внимание, данный перечень можно записать через запятую в одну строчку или по одной/несколько пакетов на каждой строчке также через запятую). |
| Standards-Version | Указывает на версию пакета. |
| Homepage | Домашняя страница для собираемого пакета. |
| Provides | Имя пакета, под которым будет зарегистрировано приложение после установки. Как правило, указывается таким же, как и имя собираемого пакета. Но в редких случаях, может понадобиться поменять на свое. |
| Depends | Список пакетов, которые требуются для установки собираемого пакета на конечной системе. Также как и в Build-Depends, возможен разный формат написания. |
| Description | Произвольное описание для пакета. Необходимо проследить, чтобы размер одной строки не превышал 73 символа. Каждая последующая строка описания должна начинаться, как минимум, с одного пробела. |
Полный перечень опций можно найти в официальном руководстве.
Rules
В данном файле мы задаем поведение при компиляции пакета. Как правило, его содержимое сводится к:
* отступы должны быть табуляциями, иначе система вернет ошибку.
. что означает, что все действия по установке пакета из исходника должны быть шаблонные.
При компиляции будет запущено три группы команд:
- debian/rules clean. Выполняет чистку каталога сборки и его подготовку.
- debian/rules build. Подготовка к сборке и сборка.
- 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:
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)"
* в данном примере мы меняем значения некоторым полям:
Сами переменные мы можем передать при запуске сборки. Подробнее процедура описана ниже.
Changelog
Файл используется системой сборки для получения номера версии пакета, его ревизии, срочности и раздела. Также в него можно заносить список изменений.
Типичный пример для файла:
gentoo (0.9.12-1) unstable; urgency=medium
* Initial release. (Closes: #nnnn)
— Josip Rodin Mon, 22 Mar 2010 00:37:31 +0100
- первая строчка указывает на:
- имя пакета (gentoo).
- версию (0.9.12-1).
- релиз (unstable).
- важность пакета (urgency=medium).
Описание дополнительных файлов
Ранее мы уже говорили о таких файлах, как:
- postinst — скрипт для запуска после установки пакета на целевой системе.
- postrm — выполнится после удаления пакета.
- preinst — скрипт выполнения перед установкой пакета.
- prerm — скрипт выполнения перед удалением пакета
Это дополнительные файлы, которые помогут нам сделать пакет более функциональным и удобным.
Рассмотрим некоторые дополнительные файлы.
Conffiles
Позволяет отметить файлы как конфигурационные. Такие файлы не будут удалены при деинсталляции пакета или заменены при обновлении. Важно знать, что программа dh_installdeb, которая помечает файлы как конфигурационные автоматически делает отметку для содержимого каталога /etc. Поэтому, нам не нужно создавать conffiles, если наши конфиги находятся в каталоге /etc.
Пример содержимого файла:
$mypackage.links
Название файла состоит из названия пакета + .links. Позволяет создать символьные ссылки при установке пакета. Например:
* в нашем примере будет создаваться симлинк /usr/bin/mybin из файла /opt/package_name/mybin.
Дополнительно
В данном разделе опишем некоторые полезные возможности.
1. Передача переменной.
При запуске сборки может понадобиться передать переменную, значение которой будет использоваться в нашем скрипте rules. Это делается с помощью опции -e:
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»
Возможные ошибки
Рассмотрим некоторые проблемы, с которыми мы можем столкнуться в процессе сборки пакетов 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.
Как собрать deb пакет из tar gz
Зачастую некоторый пакет имеется в ветках unstable и experimental, однако его нет в ветках stable/testing. Программу поставить очень хочется, а обновлять полсистемы страшновато или нежелательно.
Для таких случаев есть замечательный ресурс backports.org, однако его использование во многом похоже на прямое использование веток unstable и иногда доставляет бОльшие проблемы из-за периодически возникающих конфликтов между backports и unstable.
В большинстве случаев установить пакет из unstable и experimental можно, используя пересборку пакета в своем окружении. Делается это довольно несложно, и данное руководство предназначено для того, чтобы помочь начинающему пользователю в этом вопросе. Для примера мы разберем вариант с установкой пакета fluxbox из experimental-ветки.
Установим инструменты для сборки:
#aptitude install devscripts
Сгенерируем gpg-ключ и выполним экспорт некоторых переменных окружения, связанных с ним:
export EMAIL=name@domen.com export DEBFULLNAME="yourfullname" export DEBEMAIL=name@domen.com
Настройка apt-get
Прежде всего, нам необходимо настроить apt-get на работу с src-репозитариями Debian. Для этого добавьте в Ваш файл /etc/apt/sources.list следующие строки:
deb-src http://ftp.debian.org/debian testing main contrib non-free deb-src http://ftp.debian.org/debian sid main contrib non-free deb-src http://ftp.debian.org/debian experimental main contrib non-free
Зеркало пакетов, разумеется, можете выбрать любое — то, которым наиболее часто пользуетесь. После изменения файла /etc/apt/sources.list сделайте традиционный
#apt-get update
и будем считать систему настроенной для наших дальнейших действий.
Немного теории
Что представляет собой src-пакет в системе Debian?
Src-пакет для debian — это исходные тексты программы, которые любезно предоставлены автором под той или иной лицензией, дополненные несколькими скриптами (которые предоставлены сопровождающим пакета), обеспечивающими сборку пакета.
Все скрипты, файлы и т.п., относящиеся к сборке пакета в системе Debian, традиционно располагаются в подкаталоге debian/ вместе с исходными текстами.
- package-version.dsc — текстовый файл, включающий в себя перечень остальных необходимых файлов;
- package-version.orig.tar.gz — архив с исходными текстами программы;
- package-version.diff.gz — патч на архив с исходными текстами программы, добавляющий в них вышеупомянутый каталог debian/, а так же, возможно, содержащий исправления внесенные в исходные тексты сопровождающим.
Примечание: Некоторые включают каталог debian/ прямо в архив с исходными кодами. Это в основном касается программ разработанных специально для Debian. В таком случае вместо файлов .orig.tar.gz и .diff.gz будет один файл package-version.tar.gz.
Получение и распаковка пакета с исходными текстами
В системе, настроенной как было рекомендовано выше, данная процедура выливается в одну команду:
$ apt-get source package
для нашего случая с fluxbox это будет выглядеть так:
$ apt-get source fluxbox Чтение списков пакетов. Готово Построение дерева зависимостей. Готово Нужно загрузить 1033kB архивов с исходными текстами. Получено:1 http://ftp.debian.org experimental/main fluxbox 0.9.15.1+1.0rc2-1 (dsc) [904B] Получено:2 http://ftp.debian.org experimental/main fluxbox 0.9.15.1+1.0rc2-1 (tar) [1016kB] Получено:3 http://ftp.debian.org experimental/main fluxbox 0.9.15.1+1.0rc2-1 (diff) [16,1kB] Получено 1033kB за 1m38s (10,5kB/c) gpg: Signature made Втр 04 Июл 2006 17:05:39 MSD using DSA key ID E160649A gpg: Can't check signature: public key not found dpkg-source: extracting fluxbox in fluxbox-0.9.15.1+1.0rc2 dpkg-source: unpacking fluxbox_0.9.15.1+1.0rc2.orig.tar.gz dpkg-source: applying ./fluxbox_0.9.15.1+1.0rc2-1.diff.gz
Чтобы узнать список версий в доступных репозиториях, можно использовать команду
$ apt-cache policy
В результате этого действия, как видно из приведенного выше лога, были скачаны нужные файлы с зеркала (которое мы прописали в /etc/apt/sources.list) и произведена распаковка исходников и наложение патча в .diff.gz.
Данную операцию необязательно было проделывать с помощью apt-get, можно было пойти на страничку пакета, скачать файлы по ссылке Downloads (внизу страницы) и распаковать командой
$ dpkg-source -x fluxbox_0.9.15.1+1.0rc2-1.dsc
Также можно использовать утилиту dget, которая скачает весь пакет и сразу распакует исходники:
dget www.path.to/fluxbox_0.9.15.1+1.0rc2-1.dsc
Немного об устройстве каталога debian/
Все действия по сборке пакетов выполняются из каталога с исходными текстами, который получился при распаковке src-архива. В этом каталоге расположен и каталог debian/.
- debian/rules — этот скрипт осуществляет собственно сборку пакета (и представляет собой обычный Makefile);
- debian/control — этот текстовый файл снабдит нас некоторой информацией, которая нам понадобится ниже;
- Build-Depends: libx11-dev, libxext-dev, libxft-dev, libxinerama-dev, libxpm-dev, libxrandr-dev, x-dev, libxt-dev, debhelper (>=4.1.0), libxft-dev, libx11-dev, libxext-dev, libxft-dev, libxinerama-dev, libxpm-dev, libxrandr-dev, x-dev, libimlib2-dev, libgtk2.0-dev, cdbs
как видим это просто список пакетов которые необходимы нам при сборке.
Зависимости для сборки
Это может оказаться как самый простой вопрос, так и самый сложный. Ситуация состоит в следующем. Сопровождающий пакета, как правило, является человеком, хорошо разбирающимся во внутреннем устройстве Debian, поэтому сопровождающие зачастую раньше других переходят на использование testing/unstable веток. Кроме того, аплоад пакетов в Debian происходит прежде всего в unstable, а потому сопровождающий часто оттестировал сборку своего пакета только под testing/unstable. Довольно редко авторы программ указывают версионные зависимости для своих детищ, поэтому не всегда удаётся проставить правильные версии, и они могут быть как завышены, так и занижены. Выяснять, с какой версией той или иной библиотеки перестанет собираться программа занимает много времени и сил, а зачастую и не очень нужно.
Установка зависимостей для сборки
Простой случай: все получилось с первого раза
Если у Вас apt-get настроен так, как было указано выше, то в большинстве случаев установка зависимостей может быть сделана одной командой:
# apt-get build-dep fluxbox
Для рассматриваемого нами пакета fluxbox все необходимое будет установлено без проблем, и можно переходить к разделу (ниже) Сборка пакета.
Требуемые зависимости отсутствуют в моем дистрибутиве
- Вариант, дающий 100%-й результат, но, возможно, требующий проделать больше работы: просматриваем строку Build-Depends, о которой речь шла выше, и смотрим, какие библиотеки или утилиты отсутствуют в нашем дистрибутиве. Как правило, их перечень не такой большой чтобы испугать настойчивого человека (одна-две). Собираем эти библиотеки или утилиты по этому хауту (рекурсивно ;)).
- В случае если в строке Build-Depends указана какая-то отсутствующая в нашем дистрибутиве версия пакета, то можно попробовать понизить требования сопровождающего, отредактировав файл debian/control. Попробуйте уменьшить номер версии требуемой библиотеки или утилиты, указанный сопровождающим, на тот что у Вас имеется. Перед тем как двигаться по этой пути, проглядите каталог с исходными текстами на наличие файлов INSTALL или README. В этих файлах авторы программы иногда описывают зависимости своего детища и если уж автор программы указал версионную зависимость, то скорее всего попытка ее понизить ни к чему не приведет.
Для того чтобы узнать, что еще не установлено для сборки пакета, запустите утилиту dpkg-checkbuilddeps в каталоге с исходными текстами. Эта утилита выведет список того что требуется для сборки, но еще не установлено в Вашей системе. Для перехода к следующему шагу Вам необходимо добиться того чтобы утилита dpkg-checkbuilddeps не выдавала сообщений о неудовлетворенных зависимостях. Можете попробовать собрать неудовлетворенную зависимость или понизить требования к номеру версии или покомбинировать эти два варианта.
Сборка пакета
Простая сборка
Итак, все что необходимо нам для сборки, установлено. Осталось, собственно, собрать пакет. Для этого нам понадобится утилитка fakeroot, установите ее, если она у Вас еще не установлена.
- $ dch -i
Это приведет к тому что будет вызван редактор changelog-файла пакета. Куда вы должны вписать что-то о ваших действиях. Если, например, Вы понизили версионную зависимость, то напишите об этом. Этот шаг можно, конечно, пропустить, однако лучше все же указать, кем собран пакет и зачем. Это может пригодиться в случае, если Вы, например, захотите с кем-то поделиться результатами своего труда, а так же, если вдруг решите сообщить о каком-то баге: измененный номер версии пакета будет фигурировать в письме, написанном при помощи reportbug.
- Это не должна быть версия, встречающаяся в официальном репозитории (чтобы не создавать путаницы)
- Если вы делаете просто бэкпорт, то версия должна быть младше той версии, на основе которой собран пакет (чтобы не возникло проблем, когда этот пакет попадет в testing, затем в stable и вы попробуете сделать dist-upgrade). Добавьте строку ~backports1 к номеру версии в таком случае. Позже, если в репозитариях окажется пакет с таким же номером версии, то ваша система произведет его обновление. Цифра 1 в данном случае может означать номер Вашей сборки, а слово backports может быть заменено на любое другое, которое будет более информативным.
Исходя из этого, правильным будет добавить к версии -какаятострока1, если вы что-то существенно дорабатывали, или ~какаятострока1, если делали бэкпорт.
$ fakeroot ./debian/rules binary или $ dpkg-buildpackage -rfakeroot или #debuild
В результате будет в родительском каталоге собран двоичный пакет, ради которого затевалась вся катавасия.
- Вы что-то не (так) сделали на предыдущих шагах (например, понизили зависимость, а реально этого делать было нельзя);
- Вы наткнулись на ошибку в src-пакете. Такое тоже иногда случается. Бывает, что пакеты не собираются, например, из за «неверно» установленного umask. Вообще, сборка пакетов от umask зависеть не должна, но этот баг почему-то довольно часто встречается в Debian.
Вернитесь на несколько шагов назад и повторите попытку.
Если есть только архив с исходниками
Итак, у нас есть только fluxbox-0.9.15.tar.bz2. Обычно выполняюncz следующие действия: Предварительно подготавливаю рабочую директорию:
mkdir ~/src/fluxbox mkdir ~/src/fluxbox/0.9.15 cd ~/src/fluxbox/0.9.15 wget "http://" (можно конечно и просто через браузер скачать но обычно так быстрее)
Получаем файл fluxbox-0.9.15.tar.bz2. Немного забегая вперёд, обработаем файл программой gzip.
bunzip2 fluxbox-0.9.15.tar.bz2 gzip fluxbox-0.9.15.tar
Получим fluxbox-0.9.15.tar.gz, переименуем:
mv fluxbox-0.9.15.tar.gz fluxbox_0.9.15.orig.tar.gz
(т.е. разделили имя и версию подчёркиванием и после версии добавили слово orig: fluxbox_0.9.15.orig.tar.gz) Теперь распаковываем его (но ни в коем случае не удаляем!):
tar zxvf ./fluxbox_0.9.15.orig.tar.gz cd fluxbox-0.9.15
Для корректной сборки нужно, чтобы корневая директория содержала не только название, но и версию! Ниже будем считать директорию ~/src/fluxbox/0.9.15/fluxbox-0.9.15 корневой директорией исходников. Далее выполняем «черновую» сборку. Т.е. делаем, как обычно
./configure --prefix=/usr && make
(но не устанавливаем!) Если конфигурируется со всеми нужными опциями и собирается в бинарный файл, значит осталось только дебианизировать.
Если есть только deb-пакет
Распаковываем пакет в папку /tmp/program/
$ dpkg -x program*.deb /tmp/program
Чтобы распаковать информацию о пакете, нужно выполнить:
mkdir /tmp/program/DEBIAN $ dpkg -e program*.deb /tmp/program/DEBIAN
Теперь можно делать изменения. Чтобы снова собрать пакет, делаем следующее:
$ dpkg - b /tmp/program program-new*.deb
Дебианизация
Cмысл всей этой процедуры — создать директорию debian в корне исходников, с нужными файлами конфигурации и скриптом(ами). Для этого, в корне исходных текстов (~/src/fluxbox/0.9.15/fluxbox-0.9.15), выполним:
dh_make Type of package: single binary, multiple binary, library, kernel module or cdbs? [s/m/l/k/b] s Maintainer name : Frank Email-Address : youmail@domen.com Date : Wen, 20 Mai 2011 12:40:33 +0200 Package Name : fluxbox Version : 0.9.15 License : GPLv3 Type of Package : Single Hit to confirm:
Здесь мы указываем сформировать пакет для одиночного бинарного файла. Если бы мы не переименовали архив, то получили бы следующее сообщение:
Could not find fluxbox_0.9.15.orig.tar.gz Either specify an alternate file to use with -f, or add --createorig to create one.
В таком случае советую прервать dh_make (Ctrl+C) и переименовать архив, как описано выше. Но мы с вами молодцы и всё у нас прошло без ошибок — появился каталог debian в корне исходников, посмотрев его содержимое, Вы увидите кучу файлов (расширение .ex) с примерами на все случаи жизни. Будем считать, что программа у нас простая, обычно ни один из этих файлов не нужен. Первым делом нужно добавить описание программы в файле debian/control:
Description:
- dh_install
без этого мы получим пустой пакет. Обычно этих настроек достаточно для сборки пакета с одной программой, которая не содержит разделяемых библиотек, т.е. только бинарник в /usr/bin и данные в /usr/share. Теперь, соберём пакет:
dpkg-buildpackage -rfakeroot
в директории выше, т.е. в ~/src/fluxbox/0.9.15, мы получим файлы:
cd .. ls -1 fluxbox_0.9.15-1.diff.gz fluxbox_0.9.15-1_i386.changes fluxbox_0.9.15-1_i386.deb fluxbox_0.9.15.orig.tar.gz
Установка пакета
После того, как пакет собран, его осталось установить командой:
dpkg -i имя_пакета.deb
Или включить его в состав собственного репозитария. Это уже базовые вещи в системе Debian, поэтому их описание наведено в других статьях вики.
Сборка с созданием чистых образов систем
На самом деле, для того, чтобы собрать пакет правильно, его надо собирать в минимальной системе, где стоят только build-essential и зависимости этого пакета. Тогда, во-первых, не будет никаких накладок из-за того, что у вас в системе стоят некоторые пакеты вообще неизвестно откуда и непонятно каких версий (и в итоге в зависимостях у бинарного пакета могут оказаться пакеты версий, отсутствующих в том дистрибутиве, под который вы хотите собрать пакет), а во-вторых, вы избежите накладок (крайне редких, но все же), когда установленный лишний пакет как-то (читай негативно и не всегда очевидно) влияет на сборку.
В качестве решения подойдет chroot с чистым окружением… Испугались? Все уже украдено до нас.
Сборка пакета в системе pbuilder
Довольно неплохо упрощает данный процесс интерактивная программа pbuilder. Установите пакет pbuilder, затем откройте на редактирование /etc/pbuilderrc и пропишите адрес Вашего любимого репозитория.
# pbuilder update # pbuilder create --distribution '''sarge'''
система готова к употреблению.
Вместо имени sarge подставьте название Вашего дистрибутива.
теперь чтобы собрать пакет для выбранного дистрибутива дайте команду:
# pbuilder build package-version.dsc
Будут автоматически проделаны все описанные выше шаги, при этом все пакеты требуемые для сборки скачиваются и устанавливаются во временный каталог, поэтому система не «замусоривается» лишними пакетами. Правда, проблему с зависимостями для сборки всё равно придется решать, однако последовательно пройти по всем зависимостям с данным инструментом не представляет особого труда. Почитайте документацию на этот замечательный пакет и узнайте об остальных его возможностях.
Сборка пакета в системе cowbuilder
сowbuilder является из пакета cowdancer – это аналог pbuilder, только образ сборочной системы он хранит не в tar.gz а в развернутом виде, а при сборке копирует этот образ с использованием техники copy-on-write, что ускоряет сборку.
Пример конфига /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"
Создать образ системы можно и без использования конфига:
# cowbuilder --create --distribution sid --architecture i386
Теперь логинимся в чистую систему:
# cowbuilder --login --save
Дальше ставим утилиты для сборки и действуем как в стандартной системе (смотреть след. раздел и начало страницы):
# aptitude install devscripts
Виход из окружения стандартен, собраные пакеты искать в /var/cache/pbuilder.
exit или Сtrl+D
Сборка пакета в чистом окружении
Как теперь собрать пакет в нужном окружении. Вначале из нашего каталога — с измененной версией и поправленными build-depends собираем сурцовый пакет новой версии:
dpkg-buildpackade -rfakeroot -S
Переходим каталогом выше, где собрался файлик _.dsc (где версия, это уже наша версия с “~backport”) и говорим
pbuild --dist sarge _.dsc
Если произошла ошибка (например из-за проблем с зависимостями), то возвращаемся к шагу 1 и исправляем ошибки. Если все прошло нормально, то собранные пакеты окажутся в каталоге /var/cache/pbuilder/results. Вот собственно и все.
Для обновления образов (особенно актуально для testing) я использую команду
pbuild --dist etch --update
Пример скрипта автоматизации: ||||
Пример скрипта автоматизации для нескольких релизов: ||||
Удаление зависимостей для сборки
Для этого можно использовать deborphan:
$ deborphan или $ deborphan —guess-dev или сразу удалить: # deborphan —guess-dev | xargs apt-get remove —purge -y
или же скриптом(проверено PavloRudyj):
# aptitude markauto $(apt-cache showsrc PACKAGE_NAME | grep Build-Depends | perl -p -e 's/(?:[\[(].+?[\])]|Build-Depends:|,|\|)//g')
Debian пакет с собственными скриптами: «Сделай сам»
В продолжение темы пользователя dreadatour, написавшего набор скриптов для заливки скриншотов на сервис clip2net, я решил показать, как можно собрать DEB пакет с собственными скриптами. Сам уже давно использую эту практику, удобно, если надо поделиться с кем-то или же взять с собой «к соседу» набор собственных утилит и не мучаться с зависимостями, вспоминая, что же ты там используешь, чтобы оно заработало.
Я не очень люблю dpkg-buildpackage, так как придется возиться с MakeFile’ами, а в данном случае оно все просто не нужно, скрипты не компилируются, а просто должны оказаться на своих местах. Поэтому собирать будем «совсем руками». Заодно покажу что же такое DEB пакет вообще и расскажу о некоторых «костылях», которые с ним можно иногда сотворить.
Итак, приступим! Нам понадобятся:
date, tar, gunzip, vi (nano, ee, kate, gedit), arСоздаем каталоги!
Создаем каталог, в котором будут происходить все наши манипуляции:
$ mkdir -p ~/build/clip2net
$ cd ~/build/clip2netключ -p позволяет создать «полный» путь, даже если промежуточных каталогов еще не существует, он создаст и их. Это удобно, когда Вы хотите создать дерево каталогов, зная его структуру.
Создаем структуру каталогов наших скриптов (рекомендую использовать для этого каталог /usr/local/bin, чтобы не перекликаться с системными). Структуру создаем в нашей рабочей папке! Пишу полные пути, чтобы не запутались:
$ mkdir -p ~/build/clip2net/usr/local/bin
$ mkdir -p ~/build/clip2net/usr/local/share/doc/clip2netв каталог ~/build/clip2net/usr/local/bin мы поместим исполняемые скрипты, а в ~/build/clip2net/usr/share/doc/clip2net документ о лицензировании и авторе, чтобы с ним можно было связаться в случае чего (пожелания, сообщить об ошибке и т.д.).
Готовим документацию
Поскольку в нашем примере нет компиляции, этот этап получается совсем простым. Нам необходимо создать служебные файлы
control
md5sumsа так же файлы сопровождения приложения
changelog.Debian
copyrightвсе 4 представляют собой обычные текстовые файлы, по правилам надо указать кто собрал пакет, кто создал скрипты, а так же актуальную дату в формате RFC 2822. С этим нам поможет команда:
$ date -R
Sat, 12 Dec 2009 01:29:00 +0300К сожалению я не поинтересовался именем Dreadatour, да и сам не являюсь мейнтейнером Debian, поэтому ограничился никнеймами вместо реальных имен. Так же взял на себя смелость лицензировать скрипты под GPLv2, если Dreadatour пожелает — может изменить ее на что-то более либеральное, или же наоборот.
This package was debianized by BaBL on
Sat, 12 Dec 2009 01:29:00 +0300.The current maintainer is BaBL .
It was downloaded from:
Copyright © 2009-2010 Dreadatour
The program is in the Public Domain.
The packaging is licensed under the GNU GPL License:
Copyright 2009, Dreadatour.
For the text of the GPL License in a Debian system, please see
`/usr/share/common-licenses/GPL-2′.changelog.Debian:
в этом файле описываются все выходящие версии пакета и изменения в нихclip2net (2009.12.12-1) unstable; urgency=low
changelog.Debian должен быть упакован архиватором gunzip, сделать это можно следующей командой:
$ gunzip -c changelog.Debian > changelog.Debian.gz
control:
этот файл содержит информацию о нашем приложении:Package: clip2net
Version: 2009.12.12-1
Architecture: all
Maintainer: BaBL
Installed-Size: 100
Depends: zenity, scrot, xclip
Section: web
Priority: extra
Homepage: habrahabr.ru/blogs/linux/78006
Description: upload screnshots to clip2net web service.
clip2net is a small command-line program to upload and share
your screenshots with clip2net web service.в общем-то здесь и так все понятно. Depends — это список пакетов, которые нужны для работы наших скриптов. Можно так же указать их версии, если у Вас есть жесткая привязанность к каким-то функциям, которые могут исчезнуть в будущих версиях пакетов. Все это делается в формате packagename (>= 1.1), в нашем случае функционал базовый, версии указывать не имеет смысла.
файл md5sums создадим позже, а теперь переходим непосредственно к сборке!
DEB пакет изнутри
Пакет представляет собой архив ar, в который запакованы 2 архива и текстовый файл с версией пакета (ныне 2.0) control.tar.gz data.tar.gz debian-binary. Давайте создадим их все.
С самими скриптами, думаю, все понятно. Берем их из соседней темы: habrahabr.ru/blogs/linux/78006 и кладем в наш usr/local/bin/:
$ chmod +x ~/build/clip2net/usr/local/bin/*
$ ls ~/build/clip2net/usr/local/bin/ -l
итого 8
-rwxr-xr-x 1 babl babl 2256 Дек 12 01:18 clip2net
-rwxr-xr-x 1 babl babl 1738 Дек 12 01:21 clip2net-uploaderто же самое делаем с файлами сопровождения:
$ ls ~/build/clip2net/usr/local/share/doc/clip2net/ -l
итого 8
-rw-r—r— 1 babl babl 152 Дек 12 01:27 changelog.Debian.gz
-rw-r—r— 1 babl babl 516 Дек 12 01:30 copyrightтеперь создадим файл чексумм:
у команды md5sum нет рекурсивного режима, если файлов мало — можно вызвать ее несколько раз и собрать все данные в файл, но если много — лучше воспользоваться md5deep.~/build/clip2net/$ md5deep -r usr > md5sums
$ cat md5sums
ce3819f05bdba9f9ca25e72b4af16c13 usr/local/share/doc/clip2net/changelog.Debian.gz
3b4bb44167a1b04ce855d4925a5166d8 usr/local/share/doc/clip2net/copyright
855704c1c7cc003737a4d3028af50a35 usr/local/bin/clip2net
c4a1385cdc01c4ff34b987533d590d19 usr/local/bin/clip2net-uploaderтак же не стоит забывать, что пользователя babl на компьютерах других людей нет, поэтому все файлы отдадим root’у:
$ sudo chown -R root:root ~/build/clip2net/usr
Все, у нас все готово.
Собираем пакет
итак, нам надо получить 3 файла: control.tar.gz data.tar.gz debian-binary. Все выполняем из папки ~/build/clip2net
debian-binary
$ echo ‘2.0’ > ./debian-binary
$ tar czvf control.tar.gz control md5sums
$ tar czvf data.tar.gz usr
а теперь соберем deb пакет:
ar -r clip2net_2009.12.12-1_all.deb debian-binary control.tar.gz data.tar.gz
Проверяем на вшивость
попробуем установить наш новенький пакет:
babl@localhost:~$ sudo dpkg -i clip2net_2009.12.12-1_all.deb
[sudo] password for babl:
Выбор ранее не выбранного пакета clip2net.
(Чтение базы данных . на данный момент установлено 298876 файлов и каталогов.)
Распаковывается пакет clip2net (из файла clip2net_2009.12.12-1_all.deb).
dpkg: зависимости пакетов не позволяют настроить пакет clip2net:
clip2net зависит от scrot, однако:
Пакет scrot не установлен.
clip2net зависит от xclip, однако:
Пакет xclip не установлен.
dpkg: не удалось обработать параметр clip2net (—install):
проблемы зависимостей — оставляем не настроенным
При обработке следующих пакетов произошли ошибки:
clip2net
babl@localhost:~$упс… ошибка… в системе не установлены зависимости, придется поставить:
babl@localhost:~$ sudo apt-get install xclip scrot giblib1
Чтение списков пакетов. Готово
Построение дерева зависимостей
Чтение информации о состоянии. Готово
НОВЫЕ пакеты, которые будут установлены:
giblib1 scrot xclip
обновлено 0, установлено 3 новых пакетов, для удаления отмечено 0 пакетов, и 478 пакетов не обновлено.
не установлено до конца или удалено 1 пакетов.
Необходимо скачать 57,2kБ архивов.
После данной операции, объём занятого дискового пространства возрастёт на 233kB.
Получено:1 mirror.yandex.ru unstable/main giblib1 1.2.4-5 [20,1kB]
Получено:2 mirror.yandex.ru unstable/main scrot 0.8-11 [17,7kB]
Получено:3 mirror.yandex.ru unstable/main xclip 0.12-1 [19,3kB]
Получено 57,2kБ за 0с (636kБ/c)
Выбор ранее не выбранного пакета giblib1.
(Чтение базы данных . на данный момент установлено 298881 файлов и каталогов.)
Распаковывается пакет giblib1 (из файла . /giblib1_1.2.4-5_i386.deb).
Выбор ранее не выбранного пакета scrot.
Распаковывается пакет scrot (из файла . /archives/scrot_0.8-11_i386.deb).
Выбор ранее не выбранного пакета xclip.
Распаковывается пакет xclip (из файла . /archives/xclip_0.12-1_i386.deb).
Обрабатываются триггеры для man-db .
Настраивается пакет giblib1 (1.2.4-5) .
Настраивается пакет scrot (0.8-11) .
Настраивается пакет xclip (0.12-1) .
Настраивается пакет clip2net (2009.12.12-1) .
babl@localhost:~$все, все пакеты установились корректно и clip2net занял свое достойное место в нашей системе. Пусть первая попытка установки вас не пугает, если залить этот пакет на какой-нибудь репозиторий, или же создать свой, apt сам найдет и установит зависимости.
Как применить полученные знания?
Иногда при установке левого пакета, бывает, что какие-то зависимости конфликтуют с установленной системой, а режим установки —force лучше не использовать вообще, он может сильно нагадить в последствие. Но что, если «конфликтующий» функционал нами не будет востребован, а решаемые задачи могут быть полностью удовлетворены? Чтобы не пересобирать пакет полностью, можно попробовать просто поправить его зависимости.
Дабы не быть голословным, у меня сейчас 2 таких пакета: wl-assistant (ну нравится он мне, но «официально» не ставится уже давно) и katapult (да, знаю, есть klauncher, но мне не нравится. К счастью Linux дает свободу выбора). Как правило dpkg или apt говорит что приложение не может быть установлено, так как в системе одна версия пакета, а нужна другая, но ее установить нельзя. Очень часто это всего-лишь «предосторожности», когда мейнтейнер не может 100% гарантировать совместимость, либо из-за нехватки времени для тестирования, либо еще по каким причинам, так что в большинстве случаев данное действие будет абсолютно безопасно. Тем не менее отдавайте себе отчет в том, что за перепакованный пакет вся ответственность лежит полностью на вас. С другой стороны, удалить его в любой момент никто нам не помешает.
распаковываем deb пакеты этих приложений:
$ ar x ~/Downloads/katapult_0.3.2.2-2_i386.deb
и видим старые знакомые файлы:
$ ls
control.tar.gz data.tar.gz debian-binaryнас интересует все тот же control, распакуем архив control.tar.gz, отредактируем зависимости (список Depends:), запакуем все что из него вылезло обратно и упакуем deb пакет. Все эти манипуляции я уже расписал, после них приложение установится как ни в чем не бывало.