[Перевод] Создание пакета Debian с нуля

Создание пакета Debian с нуля является своего рода волшебным процессом. Вы могли бы начать гуглить с запросом «Создание пакета Debian с нуля» и получить множество результатов, ни один из которых не стал бы тем, который Вам необходим. Несомненно, Вы найдете большой обзор команд, которые используются в Debian и, если Вы роете достаточно глубоко, Вы сможете все же найти пару команд, которые помогут создать базовый пакет Debian, но не смогут объяснить, что происходит. Более подробную информацию о том, что все же «происходит» Вы можете получить, в данном посте мы попробуем это частично затронуть.

b2d0688b4e684758b39f07a327d3ba64.png

Во-первых, необходимо начать с установки некоторых зависимостей. Все это руководство было сделано на основе Ubuntu 14.04, но подходит для большинства операционных систем на основе Debian. Выполните следующую команду, чтобы приступить к работе.

sudo apt-get install build-essential dh-make


Далее нам нужно будет создать пакет, в котором мы будем размещать все компоненты. В данном случае пакет будет называться «mylittledeb». Для установки пакета используются следующие команды:

mkdir mylittledeb
touch mylittledeb/Makefile
touch mylittledeb/hello.c


Содержание hello.c должно содержать классический «Hello, World».

#include 

int main() {
    printf("Hello, World\n”);
    return 0;
}


Make-файл должен иметь следующее содержание. Информация для того, кто не знаком с Make-файлами — нужно применять »_», а не пробел или позже при выполнении некоторых команд Вы рискуете получить ошибки. Кроме того, обратите внимание, что очистка целевого элемента установлена ||true после удаления бинарного файла. Указанное рассогласование и другие элементы Debian мы будем использовать в дальнейшем запуская make clean перед созданием.

all:
    gcc hello.c -o hello

clean:
    rm hello || true


В этой точке у Вас есть созданный пакет Debian, который позволит пользователям печатать «Hello, World». Это не самая интересная часть, но дальше будет больше. На этом этапе убедитесь, что запуск make производит бинарный вызов hello и запускает двоичные выводы «Hello, World». Если такого не произошло — значит, что-то пошло не так и это надо исправить, для того, чтобы двигаться дальше.

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

dh_make -p mylittledeb_0.0.1

Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch?
[s/i/m/l/k/n] s

Maintainer name  : root
Email-Address    : root@unknown
Date             : Sun, 10 Apr 2016 14:38:32 -0400
Package Name     : mylittledeb
Version          : 0.0.1
License          : blank
Type of Package  : Single
Hit  to confirm:

Could not find mylittledeb_0.0.1.orig.tar.xz
Either specify an alternate file to use with -f,
or add --createorig to create one.


Мы получили сообщение об ошибке. Теперь рассмотрим несколько вещей, которые касаются этой ошибки. Во-первых, что такое orig.tar.xz файл. Во-вторых, почему использовался флаг -p? Давайте начнем с простого вопроса. Флаг-p используется, потому что dh_make смотрит на имя директории, в которой Вы находитесь в настоящее время, чтобы выяснить имя пакета и версию. Многие могут согласится, что глупо вызывать каталог таким путем, поэтому флаг -p при первом выполнении dh_make передает данные в виде _ .

Теперь давайте выясним, что за файл orig.tar.xz. Официальная документация говорит, что это — просто tarball исходного кода, который в нашем случае является просто текущим состоянием каталога. Однако, возможно, что-то особенное в этом orig.tar.xz файле есть. Поэтому давайте посмотрим, как он создается. Выполнение следующей команды позволит Вам снести исходный код для dh-make. Вы можете сделать это в tmp, так как потребуется очистить все файлы, если вы делаете это в вашем пакете mylittledeb.

apt-get source dh_make


Теперь, когда есть исходный код, давайте посмотрим, что происходит. Открывая сценарий dh_make, можно найти внутри файл Perl. При поиске orig.tar.xz с Vim приходим к следующей строке.

system(‘tar’, ‘cfJ’, "../$package_name\_$version.orig.tar.xz”, ".”);


Это просто старый архивный файл tar. Однако у Вас должно быть некоторое понимание того, что все эти волшебные Debian сценарии делаются на случай, если все пойдет не так. Теперь давайте вернемся в нашу папку mylittledeb и запустим следующее:

dh_make -p mylittledeb_0.0.1 --createorig


Теперь вы должны увидеть папку DEBiAN в вашей папке mylittledeb со следующим содержимым:

changelog 
compat 
control 
copyright 
docs 
init.d.ex 
manpage.1.ex 
manpage.sgml.ex 
manpage.xml.ex 
menu.ex 
mylittledeb.cron.d.ex 
mylittledeb.default.ex 
mylittledeb.doc-base.EX 
postinst.ex 
postrm.ex 
preinst.ex 
prerm.ex 
README.Debian 
README.source 
rules 
source 
watch.ex


Файлы .ex и .EX являются примерами файлов. В большинстве из них нет никакой необходимости.

changelog — этот файл управляет Вашей версией пакета, а также кратко приводит объяснение о том, что изменилось, начиная с последнего обновления. Вот то, на что должен быть похож основной файл.

mylittledeb (0.0.1–1) unstable; urgency=low

* Initial release (Closes: #nnnn) 

 — root  Sun, 10 Apr 2016 15:00:11 -0400


'mylittledeb' будет содержать в названии '0.0.1' это версия пакета и '1' в конце это — версия Debian. Нестабильный дистрибутив, для которого пакет Debian является целевым и переноса на различные дистрибутивы, сделан за пределами этого процесса. В данном случае мы просто будем использовать trusty, так как все это строится на Ubuntu 14.04. После того, как Вы все сделали это выглядит примерно так:

mylittledeb (0.0.1–1) trusty; urgency=low

* Intial package release

 — root  Sun, 10 Apr 2016 15:00:11 -0400


Последняя строка должна содержать имя, связанное с ключом GPG, если вы хотите подписать свои пакеты. Но мы еще дойдем до подписи пакета. На данный момент Вы можете проигнорировать этот пункт.

compat — это волшебный файл, и Вы должны всегда использовать цифру 9. Это — примерно единственная информация, которую Вы можете найти на нем. Почему именно 9? Ну, она используется всеми инструментами в пакете debhelper, это будет гарантировать, что ваш файл Debian совместим.

control — файл управления содержит версию, независимую информацию о Вашем пакете, которую увидят люди при выполнении 'apt-cache show mylittledeb'. Это все довольно хорошо объяснено в вики Debian. Ваш пакет должен выглядеть следующим образом.

Source: mylittledeb
Section: devel
Priority: optional
Maintainer: root 
Build-Depends: debhelper (>= 8.0.0)
Standards-Version: 3.9.4
#Vcs-Git: git://git.debian.org/collab-maint/mylittledeb.git
#Vcs-Browser: http://git.debian.org/?p=collab-maint/mylittledeb.git;a=summary

Package: mylittledeb
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: An example debian package that says "Hello, World”


Нужно понимать, что сборка зависимостей должна быть построена правильно, так как включает в себя все зависимости для вашего пакета. Они не должны быть добавлены к Depends, который включает только зависимости, которые запускают Вашу программу. Здесь важно отметить, что {shlibs: Depends} и {misc: Depends} — это две волшебные строки, вызываемые командой dh_shlibdeps. Эта команда полезна для определения зависимостей, Ваших двоичных потребностей, которые не сразу очевидны.

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

docs — этот файл может перечислить имена всех файлов, которые вы хотели бы видеть включенными в комплект.

rules — файл правил Debian, содержит всю информацию о создании вашего пакет и является специальной версией Makefile. В файле указываются дополнительные цели, которые используются в создании файлов Debian. По умолчанию, это очень простой файл, который просто запускает основные команды. Тем не менее, если вам нужно что-то переопределить, например, как ваш каталог будет очищаться до сборки, Вам стоит сделать что-то вроде этого.

#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

override_dh_auto_clean:
    rm /tmp/random.file

%:
    dh $@


Все доступные переопределения перечислены в этой вики статье, а также более детальное описания файла правил. По умолчанию все инструменты debhelper используют этот файл таким образом, например, если мы хотим очистить директорию, это должно быть сделано перед созданием нового пакета, то выполняется следующая команда 'dh clean'. Эта команда в свою очередь вызывает dh_testdir, dh_auto_clean и dh_clean, что в свою очередь вызывает некоторые perl скрипты.

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

source/format — этот файл кажется довольно простым. На данный момент Вы можете оставить его как есть. Просто знайте, что это формат компилирования, специфический способ применения патчей к восходящему тарболу который мы создали ранее.

*.install- этот файл не создается автоматически, так что вам нужно будет сделать файл с именем mylittledeb.install. Любой файл, который был добавлен с установкой, будет использоваться, чтобы установить двоичный файл. Файл или директория, расположенные в системе, используется при установке пакета. Так как у нас есть «hello world» двоичный файл, мы должны будем поместить это в пользовательскую систему. Следующий файл поместит наш «hello world» двоичный файл в пользовательскую директорию /usr/bin.

hello /usr/bin


Остальная часть файлов, заканчивающихся на .ex и.EX, содержит описания того, что делают различные файлы. Их лучше же конечно сохранить, но и от удаления ничего страшного не произойдет.

Теперь простая часть. Выполните следующую команду.

dpkg-buildpackage


Если раскомментировать export DH_VERBOSE=1 вы можете увидеть все команды, которые выполняются в данный момент. Все эти команды Вы можете переопределить, по этому в случае возникновения проблемы с своим собственным пакетом Вы сможете определить ее причину.

Вот вывод приведенной выше команды:

dpkg-buildpackage: source package mylittledeb
dpkg-buildpackage: source version 0.0.1-1
dpkg-buildpackage: source distribution trusty
dpkg-buildpackage: source changed by root 
dpkg-buildpackage: host architecture amd64
 dpkg-source --before-build mylittledeb
 debian/rules clean
dh clean 
   dh_testdir
   dh_auto_clean
        make -j1 clean
make[1]: Entering directory `/root/mylittledeb'
rm hello || true
rm: cannot remove ‘hello’: No such file or directory
make[1]: Leaving directory `/root/mylittledeb'
   dh_clean
        rm -f debian/mylittledeb.substvars
        rm -f debian/mylittledeb.*.debhelper
        rm -rf debian/mylittledeb/
        rm -f debian/*.debhelper.log
        rm -f debian/files
        find .  \( \( -type f -a \
                \( -name '#*#' -o -name '.*~' -o -name '*~' -o -name DEADJOE \
                 -o -name '*.orig' -o -name '*.rej' -o -name '*.bak' \
                 -o -name '.*.orig' -o -name .*.rej -o -name '.SUMS' \
                 -o -name TAGS -o \( -path '*/.deps/*' -a -name '*.P' \) \
                \) -exec rm -f {} + \) -o \
                \( -type d -a -name autom4te.cache -prune -exec rm -rf {} + \) \)
        rm -f *-stamp
 dpkg-source -b mylittledeb
dpkg-source: info: using source format `3.0 (quilt)'
dpkg-source: info: building mylittledeb using existing ./mylittledeb_0.0.1.orig.tar.xz
dpkg-source: info: building mylittledeb in mylittledeb_0.0.1-1.debian.tar.gz
dpkg-source: info: building mylittledeb in mylittledeb_0.0.1-1.dsc
 debian/rules build
dh build 
   dh_testdir
   dh_auto_configure
   dh_auto_build
        make -j1
make[1]: Entering directory `/root/mylittledeb'
gcc hello.c -o hello
make[1]: Leaving directory `/root/mylittledeb'
   dh_auto_test
 debian/rules binary
dh binary 
   dh_testroot
   dh_prep
        rm -f debian/mylittledeb.substvars
        rm -f debian/mylittledeb.*.debhelper
        rm -rf debian/mylittledeb/
   dh_auto_install
        install -d debian/mylittledeb
   dh_install
        install -d debian/mylittledeb//usr/bin
        cp -a ./hello debian/mylittledeb//usr/bin/
   dh_installdocs
        install -g 0 -o 0 -d debian/mylittledeb/usr/share/doc/mylittledeb
        chown -R 0:0 debian/mylittledeb/usr/share/doc
        chmod -R go=rX debian/mylittledeb/usr/share/doc
        chmod -R u\+rw debian/mylittledeb/usr/share/doc
        install -g 0 -o 0 -m 644 -p debian/README.Debian debian/mylittledeb/usr/share/doc/mylittledeb/README.Debian
        install -g 0 -o 0 -m 644 -p debian/copyright debian/mylittledeb/usr/share/doc/mylittledeb/copyright
   dh_installchangelogs
        install -o 0 -g 0 -p -m644 debian/changelog debian/mylittledeb/usr/share/doc/mylittledeb/changelog.Debian
   dh_perl
   dh_link
   dh_compress
        cd debian/mylittledeb
        chmod a-x usr/share/doc/mylittledeb/changelog.Debian
        gzip -9nf usr/share/doc/mylittledeb/changelog.Debian
        cd '/root/mylittledeb'
   dh_fixperms
        find debian/mylittledeb  -print0 2>/dev/null | xargs -0r chown --no-dereference 0:0
        find debian/mylittledeb ! -type l  -print0 2>/dev/null | xargs -0r chmod go=rX,u+rw,a-s
        find debian/mylittledeb/usr/share/doc -type f  ! -regex 'debian/mylittledeb/usr/share/doc/[^/]*/examples/.*' -print0 2>/dev/null | xargs -0r chmod 644
        find debian/mylittledeb/usr/share/doc -type d  -print0 2>/dev/null | xargs -0r chmod 755
        find debian/mylittledeb/usr/share/man debian/mylittledeb/usr/man/ debian/mylittledeb/usr/X11*/man/ -type f  -print0 2>/dev/null | xargs -0r chmod 644
        find debian/mylittledeb -perm -5 -type f \( -name '*.so.*' -or -name '*.so' -or -name '*.la' -or -name '*.a' \)  -print0 2>/dev/null | xargs -0r chmod 644
        find debian/mylittledeb/usr/include -type f  -print0 2>/dev/null | xargs -0r chmod 644
        find debian/mylittledeb/usr/share/applications -type f  -print0 2>/dev/null | xargs -0r chmod 644
        find debian/mylittledeb -perm -5 -type f \( -name '*.cmxs' \)  -print0 2>/dev/null | xargs -0r chmod 644
        find debian/mylittledeb/usr/lib/perl5 debian/mylittledeb/usr/share/perl5 -type f -perm -5 -name '*.pm'  -print0 2>/dev/null | xargs -0r chmod a-X
        find debian/mylittledeb/usr/bin -type f  -print0 2>/dev/null | xargs -0r chmod a+x
        find debian/mylittledeb/usr/lib -type f -name '*.ali'  -print0 2>/dev/null | xargs -0r chmod uga-w
   dh_strip
        strip --remove-section=.comment --remove-section=.note debian/mylittledeb/usr/bin/hello
   dh_makeshlibs
        rm -f debian/mylittledeb/DEBIAN/shlibs
   dh_shlibdeps
        install -o 0 -g 0 -d debian/mylittledeb/DEBIAN
        dpkg-shlibdeps -Tdebian/mylittledeb.substvars debian/mylittledeb/usr/bin/hello
   dh_installdeb
   dh_gencontrol
        echo misc:Depends= >> debian/mylittledeb.substvars
        dpkg-gencontrol -ldebian/changelog -Tdebian/mylittledeb.substvars -Pdebian/mylittledeb
        chmod 644 debian/mylittledeb/DEBIAN/control
        chown 0:0 debian/mylittledeb/DEBIAN/control
   dh_md5sums
        (cd debian/mylittledeb >/dev/null ; find . -type f  ! -regex './DEBIAN/.*' -printf '%P\0' | LC_ALL=C sort -z | xargs -r0 md5sum > DEBIAN/md5sums) >/dev/null
        chmod 644 debian/mylittledeb/DEBIAN/md5sums
        chown 0:0 debian/mylittledeb/DEBIAN/md5sums
   dh_builddeb
        dpkg-deb --build debian/mylittledeb ..
dpkg-deb: building package `mylittledeb' in `../mylittledeb_0.0.1-1_amd64.deb'.
 signfile mylittledeb_0.0.1-1.dsc
gpg: skipped "root ": secret key not available
gpg: [stdin]: clearsign failed: secret key not available

 dpkg-genchanges  >../mylittledeb_0.0.1-1_amd64.changes
dpkg-genchanges: including full source code in upload
 dpkg-source --after-build mylittledeb
dpkg-buildpackage: full upload (original source is included)
dpkg-buildpackage: warning: failed to sign .dsc and .changes file

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

Теперь Вы должны увидеть набор новых файлов в том же каталоге, где размещена Ваша папка mylittledeb. Нас интересует файл с названием «mylittledeb_0.0.1–1_amd64.deb», который может быть установлен с помощью команды:

sudo dpkg -i mylittledeb_0.0.1–1_amd64.deb


Теперь вы должны иметь возможность запускать «Hello» из любого места на вашем компьютере, и получить текст «Hello, World».

© Habrahabr.ru