Сборка RPM и DEB пакетов (Федора и Дебиан (на русском языке))

Готовые решения для многих вопросов, которые очень часто задаются снова и снова.

Модератор: Модераторы разделов


Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 12:56

Сборка пакетов. Глава 1. RPM. Часть 1. Какие RPM-пакеты бывают, и где их искать.

Не так давно у меня возникла мысль, что нужно написать пару статей о сборке пакетов в Linux, так как метод make && make install может пагубно отразиться на состоянии вашей системы. Об этом я и обмолвился в комментариях в блоге “Записки дебианщика”. Недавно мне об этом напомнили. В процессе написания, я понял что положить на бумагу свой опыт довольно сложно, поэтому у этой статьи будет две главы (сборка RPM и DEB пакетов) и несколько частей. Собирая RPM, я буду базироваться на дистрибутиве Fedora и подобным ей дистрибутивам. Относительно DEB нет смысла заострять внимание на конкретном дистрибутиве, так как разницы в пакетах (и их сборке) для Debian и Ubuntu никакой нет. Перед выходом этой статьи я специально написал обзор репозиториев для Fedora Core.

Итак, вы нашли некую очень интересную программу, которой к сожалению нет в репозиториях или она не той версии. Для правильной установки (и уж тем более правильного и безболезненного удаления) нам нужно создать пакет. Почему же не следует использовать make install?

1. Это не правильно, можно сделать большую свалку из работающей системы,
2. Вам будет трудно его удалить, а если поставите в /usr, то и вообще практически не реально,
3. Вам будет также сложно его перенести на другую машину,
4. При обновлении системы он может перестать работать, так как зависимости не будут соблюдаться.

Этот список можно дополнять и дополнять.

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

1. Вы не первый кто этот пакет пытался собрать.
2. Если его нет в Fedora, то с вероятностью 95% он есть или под Mandriva, или под openSUSE, или под PLD, или под ALT Linux.

Во втором пункте перечислены все основные крупные репозитории пакетов, с которыми вам возможно придётся столкнуться. Чем же отличаются rpm-пакеты этих дистрибутивов? Да и как их отличить?

Mandriva
. В своём названии пакеты обычно имеют суффикс mdv (раньше mdk) и год (так у них теперь идёт нумерация дистрибутива). Внутренний файл спецификации резко отличается от Fedora. Там используется своя конструкция для инсталляции, а именно %makeinstall_std, и конфигурации пакетов, которые используют autotools — %configure2_5x. Также используются различные макроопределения. Преобразование такого spec-файла к Федоровскому не особо простая задача. Однако некоторые пакеты преобразовываются очень просто.

openSUSE. Spec-файлы rpm-пакетов этого дистрибутива очень легко преобразовать к Федоровским. Отличительной чертой является упоминание об авторах пакета в поле %description. Есть свои макросы, а также стремление устанавливать многие пакеты в директорию /opt. Также обычно секция Release содержит большое число. Это мало о чем говорит, но если оно довольно большое, то вероятность принадлежности пакета к SUSE велика.

ALT Linux. Spec-файлы вообще ни на что не похожи. Первое, что бросается в глаза, это отсутствие секции BuildRoot и %defattr, что будет иметь довольно печальные последствия для вашего собранного пакета. Также используются свои макросы для определения каталогов и некоторых команд. Преобразовать к стандарту Fedora можно, но желательно не нужно.

PLD. Польский дистрибутив, в последнее время редко стал мне попадаться. Крайне не приятный формат spec-файла, вроде бы все сделал, а не собирается ну никак. Отличить по названию практически нельзя. Исправлять этот пакет следует в последнюю очередь.

Как искать пакеты в сети. Существует несколько поисковых сайтов по rpm-пакетам. Это rpmfind.net (в последнее время совсем бездарный) и rpm.pbone.net. Однако обычно я ищу пакеты в Google. Просто вводите имя-пакета, можете указать версию и src.rpm: liferea-1.2 src.rpm. Вполне самодостаточный поиск. Если очень хочется попытаться найти пакет под Fedora, то следует добавить суффик fc: liferea-1.2 fc src.rpm.

Чем хорош Google? Тем, что он ищет пакеты не только по определённым популярным репозиториям, но и в труднодоступных местах, например, в блогах.

Для Fedora также следует поискать пакеты в специализированных репозиториях ( о них я писал не так давно ), может так случиться, что собирать ничего и не придётся.

Если же ничего подходящего нет, то придётся всё делать самому.

Во второй части мы рассмотрим структуру spec-файла Fedora, а также основные макроопределения spec-файлов других дистрибутивов.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 13:43

Сборка пакетов. Глава 1. RPM. Часть 2. Подготовка к сборке и обзор spec-файла

Сперва давайте разберёмся, что должно быть в системе для сборки rpm-пакета. Обязательно должен быть установлен пакет rpm-build. Без него не будет доступна команда rpmbuild. В зависимостях для сборки пакета в Fedora обычно не принято прописывать компилятор C/C++, по этому поводу рано или поздно вам понадобятся пакеты gcc, cpp, gcc-c++, libstdc++, libstdc++-devel, libgcc. Все остальные зависимости должен попросить сам пакет. Конечно бывают промахи, и в процессе сборки вы понимаете, что что-то упустили, но это обычно бывает довольно редко и не критично.

А что собственно из себя представляет RPM пакет? RPM-пакеты делятся на пакеты с исходниками src.rpm и пакеты готовые к установки %{arch}.rpm. В src.rpm пакетах содержится исходный тарболл (исходник программы), какие-либо другие исходники, пачти и самый главный spec-файл, который управляет процессом сборки. Все эти файлы упакованы в cpio архив. Когда вы пытаетесь войти в src.rpm пакет при помощи файлового менеджера mc вы его увидите. Также в пакете присутствует некоторые файлы с информацией.

В %{arch}.rpm-пакетах содержится cpio-архив с файлами, которые после установки разложатся по соответствующим каталогам, файлы информации и установочные скрипты скрипты.

Также вы можете встретить nosrc.rpm файлы, Обычно их создают для проприетарных программ, которые нельзя включать в дистрибутив (исходников нет, а бинарник каким-то образом нужно переделать). Внутри этого пакета находится обычно только spec-файл, а вот бинарник, который послужит исходником придется кочать с официального сайта. Под Fedora я таких пакетов не помню.

По умолчанию собирать пакеты можно только из-под root'а. В большинстве случаев это безопасно, однако всё равно есть вероятность, что корнем для секции инсталляции окажется каталог / и тогда команда rm -rf $RPM_BUILD_ROOT уничтожит все на свете. Также бывает, что "кривые" пакеты не правильно выполняют инсталляцию, и ставятся не во временный каталог, а прямо куда-нибудь в %{_prefix} (/usr). Часть файлов будет потеряна, хотя на работоспособности пакета на этой машине понятное дело это не скажется. Из-под рута вся сборка происходит в каталоге /usr/src/redhat.

Что нужно сделать, чтобы можно было собирать пакеты из-под обычного пользователя? Первым делом нужно создать в своём домашнем каталоге файл .rpmmacros с примерно следующим содержанием:

Код: Выделить всё

%_topdir /home/ashejn/BUILD_ROOT
%_sourcedir %{_topdir}/SOURCES
%_specdir %{_topdir}/SPECS
%_builddir %{_topdir}/BUILD


В секции %_topdir указывается общий каталог, в котором мы будем собирать пакеты. В нашем случае это каталог BUILD_ROOT находящийся в вашем домашнем каталоге (у меня он ashejn). Структура подкаталогов каталога BUILD_ROOT следующая.

Код: Выделить всё

/BUILD_ROOT
|-- BUILD
|-- RPMS
|   |-- i386
|   |-- i686
|   |-- x86_64
|   `-- noarch
|-- SOURCES
|-- SPECS
`-- SRPMS

Каталоги BUILD, RPMS, SOURCES, SPECS, SRPMS вам необходимо создать вручную, подкаталоги каталога RPMS должны создаться автоматически во время сборки в зависимости от архитектуры.

В последнее время в Fedora принято добавлять в секцию %{release} суффикс fc6 (или fc7, или fc5). В spec-файле фигурирует опция %{?dist}, что означает если переменная %dist определена, то добавить её (в нужное место). Я советую также переопределить её в макросах rpm. Причём вы можете обозвать её как угодно, например, для ASPLinux я писал .110msiu. Только не забудьте поставить в начале точку.

Код: Выделить всё

%dist .fc6


Также в Fedora не принято писать сборщика пакета и вендора в spec-файлах (DAG так не думает). Все это если нужно следует определить раз и навсегда в макросах

Код: Выделить всё

%packager       Arkady L. Shane
%vendor         Yandex


Последним штрихом является цифровая подпись. Сгенерировать её крайне просто, командой gpg --gen-key и клавишей Enter.

Код: Выделить всё

%_signature gpg
%_gpg_path /home/ashejn/.gnupg
%_gpg_name идентификатор_ключа
%_gpgbin /usr/bin/gpg


Идентификатор ключа можно посмотреть командой gpg --list-key в секции pub после слеша ("/").

Основные приготовления к сборке пакетов сделаны, теперь давайте посмотрим что из себя представляет самый главный файл rpm-пакета, spec-файл. Для примера возьмём его из пакета stardict. Этот пакет хорошо подходит для обучения, так как в нем есть несколько тарболов (исходник программы, упакованный tar'ом), получается несколько пакетов и есть такая вещь, как схемы. Обычно spec-файл имеет такое же имя, как и сам пакет (stardict.spec). Однако вы можете добавить версию пакета (stardict-2.spec), удобно если вы пытаетесь поддерживать несколько веток программ. Можно даже дать какое-нибудь другое название, однако это мягко говоря не удобно.

Итак, содержимое файла stardict.spec приведено ниже. Я сразу буду вставлять комментарии после определенных секций, но если вы соедините все блоки в один и тот же файл, то получите полноценный stardict.spec. Spec-файл состоит из секций и шапки:

Код: Выделить всё

Summary:        StarDict dictionary
Name:           stardict
Version:        2.4.8
Release:        4%{?dist}
License:        GPL
URL:            http://stardict.sourceforge.net
Group:          User Interface/Desktops
Source0:        %{name}-%{version}.tar.bz2
Source1:        %{name}-tools-%{version}.tar.bz2
Patch0:         %{name}-2.4.8-desktop.patch
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)


Summary — краткое описание пакета, Name — название, Version — версия, Release - релиз. Последним трем тегам соответствуют макроопределения %{name}, %{version}, %{release}. Их часто используют в дальнейшем. Name и Version обычно совпадает с название тарбола. Если же они отличаются, то в принципе ничего страшного, но придётся в некоторых местах spec-файла действовать нестандартными методами. Если вы собираете пакет из cvs, svn и т. д., то рекомендуется в самом начале файла сделать макроопределение %define date 20070422 (именно в таком формате, сами догадайтесь почему) и тег Release определить следующим образом: Release: %{date}cvs. В данном примере в теге Release используется %{?dist} переопределенный нами в файле .rpmmacros.

Далее, License — лицензия, под которой распространяется программа (обычно указано в самом пакете). Раньше в ходу был также тег Copyright, но сейчас он не используется. URL — сайт программы, Group — группа, в которую будет входить данный пакет. Обычно следует прикинуть, на что этот пакет похож и посмотреть группу похожего пакета. Можно и самому придумать группу.

Source* — исходные тексты, тарболы, просто файлы. В данном примере идут два тарбола с разными программами, что делает сборку намного сложнее. Обычные файлы, например, конфигурации, могут просто копироваться в секции %install при помощи команды install. У нее простой синтаксис, install -m маска_как_у_chmod что куда . При помощи нее можно также создавать каталоги. В нашем примере она не используется, но подробнее про неё можно почитать в man.

Следует знать, что Sourсe и Source0 это одно и тоже

Patch — патчи, исправления, которые вы или кто-то другой выпустили для данного пакета. Не принято изменять исходный текст самой программы, а затем завертывать ее в тарбол. Принято накладывать заплатки. Я рекомендую делать их следующим образом. Распаковываете исходный тарбол, у нас это будет stardict-2.4.8, далее копируете stardict-2.4.8 в stardict-2.4.8.orig. После этого изменяете код в каталоге stardict-2.4.8, выходите из него и отдаете команду diff -ur stardict-2.4.8.orig stardict-2.4.8 > stardict-2.4.8-название_патча.patch. Как видно до навания_патча идёт %{name}-%{version} пакета. В самом spec-файле обязательно следует писать название патча без макроопределений. По крайней мере версию, точно. Иначе при обновлении версии пакета, у вас и обновится версия патча, определённая макросом %{version}, а патч может быть подойдёт к новой версии программы и без каких либо изменений. Если же во время самой сборки патч не смог наложиться, то его следует либо переделать под данную версию программы, либо отключить в секции %{setup}.

BuildRoot — каталог в котором осуществляется сборка. %{_tmppath} — это макроопределение для каталога /var/tmp. Обратите внимание, на конец строки. В "%()" записывается команда к выполнению, тоже что в bash ${}. %{__id_u} ничто иное, как простой вызов команды id -u, такая запись может быть использована в spec-файлах, хотя и не особо популярна в Fedora. Одним из главных недостатков является возможность использования только одного параметра, о чем и говорит стоящий в сторонке параметр -n.

Код: Выделить всё

BuildRequires:  libgnomeui-devel >= 2.2.0, scrollkeeper, gettext

Requires(post): GConf2, scrollkeeper
Requires(postun): scrollkeeper


BuildRequires — секция, в которую через запятую или через пробел прописываются пакеты, которые требуются для сборки нашей программы. Почерпнуть их можно из каких-нибудь файлов README и INSTALL (хотя там редко бывает что-то полезное по этому поводу), из процесса конфигурации (на данный момент обычно это скрипт configure) и из самого процесса сборки (иногда configure что-нибудь пропустит и сборка остановится).

Requires — в эту секцию записываются пакеты или файлы(!), которые будет требовать данный пакет при установке. При сборке в зависимости автоматически пропишутся все библиотеки, которые наш пакет потребует, но вы также можете указать пакеты вручную. RPM также автоматически прописывает зависимости perl и mono (все эти зависимости прописываются не в spec-файл разумеется, а в сам пакет). Если вам не нужно, чтобы зависимости прописывались автоматически, следует прописать в spec-файл новый тег AutoReq: no. Обычно его прописывают при сборки проприетарных программ, так как rpm добавляет внутренние зависимости из собираемой программы.

В нашем примере используются конструкции Requires(post) и Requires(postun) для зависимостей в скриптах установки и удаления. В принципе достаточно и простого Requires. Здесь особенно нечего комментировать. Просто самому StarDict в процессе работы эти зависимости не нужны. Нужны они только при инсталляции и удалении.

Есть ещё несколько полезных тегов, которые здесь не используются.

Provides: название1, название2 — другие названия, помимо %{name}, на которые будет откликаться данный пакет. Удобно указывать, если вы сменили название пакета, а другие пакеты продолжают зависеть от старого названия.

Obsoletes: название1, название2 — удаление указанных пакетов при установки текущего пакета. Как бы говорится, что данный пакет замещает собой указанные (по функциональности, по набору файлов и т. п.). Можно использовать конструкцию название <|>|<=|=|=> версия. Тут вы должны сами понимать, что к чему.

Conflicts: название1, название2 — перечисляются пакеты, которые конфликтуют с текущим. Подразумевается что указанные пакеты нужно вручную удалить, перед установкой нашего. Также используются конструкции со знаками сравнения и версиями (см. выше).

Других тегов для обработки зависимостей, таких как Suggest в стандартном RPM нет. Есть ли они в других дистрибутивах, не знаю. Я видел что-то подобное в рассылке openSUSE. Нужны ли мягкие зависимости, такие как в DEB пакетах, я однозначно ответить не могу.

Epoch: число
— обычно или не указывается совсем или равняется 0. Суть этого параметра вот в чем. Пусть всё наш же пакет stardict имеет версию 2.4.8, а также есть более старый 2.4.5. Так вот если %{epoch} у stardict 2.4.5 будет 1, а у 2.4.8 0, то пакет 2.4.5 будет всегда новее, чем 2.4.8. О чём при установки вам RPM и скажет. Этот параметр удобен, если вы хотите откатиться на предыдущую версию (разумеется, если вы это все выкладываете в публичный репозиторий и хватаете все YUM'ом. Для "домашних" нужд подойдёт параметр к rpm --force). Если определён тег Epoch: 0, то пакет будет иметь приоритет перед пакетом с непоределённым тегом Epoch.

BuildArch: архитектура — архитектура, под которую будет собираться наш пакет. Если эта опция не указана, то пакет соберётся под текущую архитектуру. Обычно эту опцию указывают для того, чтобы собирать пакет архитектуры noarch, то есть пакет в котором нет бинарников.

ExclusiveArch: архитектура1 архитектура2 — архитектуры, под которые данный пакет может быть собран. Обычно используется при сборки модулей к ядру.

На этом шапка заканчивается и начинаются отдельные секции.

Код: Выделить всё

%description
StarDict is an international dictionary written for the GNOME environment.
It has powerful features such as "Glob-style pattern matching," "Scan
seletion word," "Fuzzy search," etc.


Описание главного пакета, того, у которого будет имя %{name}

Код: Выделить всё

%package tools
Summary:        StarDict-Editor
Requires:       %{name} = %{version}-%{release}
Group:          User Interface/Desktops


Здесь мы создаём новый пакет, название которого будет %{name}-tools. Если нужно обозвать пакет совсем по другому, то следует сделать, например, так: %package -n tools-stardict. Версия нового пакета берётся из заданного тега Version. Обратите внимание на Requires. В нём прописана зависимость на главный пакет stardict. Если бы он имел %{epoch}, то необходимо было бы обязательно указать Requires: %{name}-%{epoch}:%{version}-%{release}. Иначе вам просто не удастся установить это пакет.

Код: Выделить всё

%description tools
A simple tool for StarDict.


Описание второго пакета

Код: Выделить всё

%prep
%setup -q -a1
%patch0 -p1


Секция %prep в ней начинается подготовка к сборке. %setup распаковывает исходники. Опция -q не показывает вывод распаковывания архива. Опция -a1 используется для распаковки %{SOURCE1}, второго тарбола внутрь(!) каталога первого тарбола. Соответственно цифра указывает на номер SOURCE. Ещё иногда используется параметр -b, тогда второй тарбол распаковывается в тот же каталог, что и первый. Соответственно если у нас один тарбол, то опции -a, -b не используются.

Если у вас первый каталог в тарболе имеет отличное от %{name}-%{version} название, то rpm не сможет войти автоматом в этот каталог. В таком случае следует немного изменить %setup. Если в архиве stardict-2.4.8.tar.bz2 первый каталог имеет название, например, просто stardict, то выглядеть это будет так: %setup -q -n %{name} -a1.

Сразу после распаковки пакета, перед %patch если нужно можно скопировать файлы, или запустить какие либо программы для изменения исходников. Допустим скопировать файл русификации, или подправить sed'ом какой-нибудь исходник. Просто вызываете здесь cp, sed или ещё что-то. В качестве корня здесь выступает каталог, в который распаковался первый тарболл (за него отвечает переменная $RPM_BUILD_DIR, но она крайне редко используется).

При помощи %patch накладываются патчи. Если вы делали патч как я писал выше, то у вас всегда будет параметр -p1. Также часто используют параметр -b .название_патча, для создания резервной копии.

Код: Выделить всё

%build
pushd %{name}-tools-%{version}
%configure
make %{?_smp_mflags}
popd

%configure
make %{?_smp_mflags}


Секция %build, именно здесь происходит сборка пакета. Обратите внимание на push и popd. Этими командами мы переходим и выходим из каталога второго тарбола. Именно он будет корневым каталогом после push. После команды popd мы вернёмся в каталог первого тарбола. Соответственно если у вас один исходник, то не нужно использовать эти команды.

Так как у нас две программы в одном пакете, то мы выполняем два раза концигурацию %configure и два раза make. Если пакет конфигурируется при помощи autotools, то макросом %configure запускается скрипт configure из корня распакованного тарбола. У него обычно бывает много параметров, их можно посмотреть из командной строки при помощи ./configure --help. После %configure вы можете указать нужные вам параметры. Заметьте, что вызов %configure и ./configre отличаются. В первом случае конфигуратору будут переданы правильные каталоги для инсталляции (а также стандартные параметры), во втором каталоги по умолчанию.

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

Если пакет не использует autotools, то %configure, а может и make использовтаь не нужно, для сборки прочтите файл README и INSTALL.

Когда сборка успешна закончена, в действие вступает секция %install.

Код: Выделить всё

%install
rm -rf $RPM_BUILD_ROOT

pushd %{name}-tools-%{version}
make DESTDIR=$RPM_BUILD_ROOT install
popd

make DESTDIR=$RPM_BUILD_ROOT install

%find_lang %{name}

desktop-file-install --vendor fedora --delete-original          \
  --dir ${RPM_BUILD_ROOT}%{_datadir}/applications               \
  --add-category X-Red-Hat-Base                                 \
  ${RPM_BUILD_ROOT}%{_datadir}/applications/%{name}.desktop


Командой rm мы удаляем (если он есть) каталог предыдущих инсталляций, далее в нашем примере мы идём в каталог второго тарбола и производим установку. В качестве каталога установки через параметр DESTDIR make'у передается переменная $RPM_BUILD_ROOT, это ничто иное, как каталог указанный в теге BuildRoot. Тоже самое выполняется и для основного тарбола.

%find_lang, поиск файлов локализации. Параметром у неё является название файлов, которые будут лежать после установки в каталоге $RPM_BUILD_ROOT/usr/share/locale/*/LC_MESSAGES/*.mo. Обычно оно соответствует %{name}. Если это не так, пишите другое имя.

desktop-file-install — обработка .desktop файла для меню. Там много всяких параметров, почитайте справку. Файлы для меню, хранятся в каталоге /usr/share/applications. Их содержимое не такое сложное. В принципе, если у вас уже правильный .desktop-файл, то вызов этой команды не является обязательным.

--vendor fedora — добавляется вендора, и .desktop-файл будет иметь спереди от своего названия то, что вы укажете, в данном случае это fedora-. --delete-original — удаление старого .desktop-файла, иначе будут установлены 2. --add-category X-Red-Hat-Base добавление категории. Категории могут быть разные, самые популярные Application, Gnome, KDE, Utility, System, Audio, Internet. Именно они влияют на то, в каком подменю будет отображаться наша программа. Так как подменю не так много, то можно вычислить названия каждого просмотром .desktop-файлов программ входящих в каждое из них.

Если вы хотите добавить вашу программу в главное меню, то придётся править файл /etc/xdg/menus/applications.menu из пакета redhat-menus. В том же каталоги лежат файлы и для других меню.

Код: Выделить всё

%clean
rm -rf $RPM_BUILD_ROOT


Секция для удаления нашей временной установки, после сборки пакета.

Код: Выделить всё

%post
export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
gconftool-2 --makefile-install-rule \
  %{_sysconfdir}/gconf/schemas/%{name}.schemas > /dev/null || :


%preun
if [ "$1" -eq 0 ]; then
    export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
    gconftool-2 --makefile-uninstall-rule \
      %{_sysconfdir}/gconf/schemas/%{name}.schemas > /dev/null || :
fi

Секции для установочных скриптов. Вообще их бывает несколько. %pre — выполняется перед установкой, %post — после установки, %preun — перед удалением, %postun — после удаления. В нашем примере устанавливаются и соответственно удаляются схемы Gconf. Если пакет их использует, то каждая из них должна быть перечислена (поищите их в каталоге BuildRoot/etc/gconf/schemas). Для каждого пакета могут быть свои скрипты, поэтому следует также почитать документацию. Если никаких скриптов для правильной работы не нужно, то и секции эти не следует использовать. В этих секциях можно применять bash-скрипты (впрочем как и в любых других секциях).

В секциях %files мы должны указать какие файлы должны быть упакованы в пакеты. Все файлы должны быть оговорены, в противном случае rpm-build выдаст сообщение о неупакованных файлах.

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

Для определения каталогов используются специальные макроопределения. %{_prefix} - /usr, %{_sysconfdir} - /etc, %{_bindir} - /usr/bin, %{_datadir} - /usr/share, %{_libdir} - /usr/lib, %{_lib} - /lib, %{_libexecdir} - /usr/libexec, %{_includedir} - /usr/unclude, %{_mandir} - /usr/share/man, %{_sbindir} - /usr/sbin, %{_localstatedir} - /var.

Код: Выделить всё

%files -f %{name}.lang
%defattr(-, root, root)
%doc AUTHORS COPYING INSTALL README NEWS
%{_sysconfdir}/gconf/schemas/stardict.schemas
%{_bindir}/stardict
%{_bindir}/stardict-editor
%{_libdir}/bonobo/servers/GNOME_Stardict.server
%{_datadir}/applications/*.desktop
%{_datadir}/stardict
%{_datadir}/locale/*/LC_MESSAGES/*
%{_datadir}/pixmaps/stardict.png
%{_datadir}/gnome/help/%{name}/*
%{_datadir}/idl/GNOME_Stardict.idl
%{_datadir}/omf/*
%doc %{_mandir}/man?/*


%doc помечает файлы как документацию. Третья строка копирует указанные файлы в каталог %{_datadir}/doc/%{name}-%{version}. %defattr(-,root,root) указывает, что файлы в rpm пакете должны иметь владельцем root'а, а на файлы должны быть такие же права, как и в процессе установки. Можно также указать и четвёртый параметр, для каталогов (тоже "-"). В spec-файлах от ALT Linux этой строчки нет.

Далее просто перечисляются файлы.

Код: Выделить всё

%files tools
%defattr(-,root,root)
%{_bindir}/stardict-editor


Тоже самое для пакета stardict-tools. Если бы он назывался tools-stardict, то %files выглядел бы так: %files -n tools-%{name}.

Последнее, что идёт в spec-файле, это %changelog. В changelog'е вы указывает изменения в пакете по сравнению с предыдущей версией. Синтаксис его примерно следующий.

Код: Выделить всё

%changelog
* Sun Apr 22 2007 Your Name <your@email> - 2.4.8-4
- update desktop patch


Во второй части статьи мы подготовили "кузнецу" для сборки из-под пользователя и получили базовые знания по spec-файлу. В следующей главе мы рассмотрим некоторые интересные макроопределения, скрипты, определение переменных и параметры сборки rpm-пакета. Также рассмотрим основные подходы к сборки и бекпортирование.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 14:18

Сборка пакетов. Глава 1. RPM. Часть 2. П. 1 Сборка RPM пакета из уже установленного в системе

Иногда случается ситуация, что какой-то пакет уже установлен в системе ( может быть в очень старой системе) и очень хочется получить rpm’ку с ним, а она как раз и не сохранилась. Также может захотеться собрать по быстрому пакет с изменёнными под ваши нужды конфигурационными файлами.

Для решения этой проблемы следует воспользоваться утилитой rpmrebuild. Эта утилита написана на bash, адрес сайта rpmrebuild.sourcefrge.net. Для Fedora 7 я её собрал и положил себе в репозиторий, впрочем, вы её сможете поставить и в fc6, и в более ранние дистрибутивы.

Работать с ней крайне просто. Нужно отдать всего лишь команду:

Код: Выделить всё

rpmrebuild название_установленного_пакета


Если какой-либо файл был изменён, то вам об этом сообщат, но процесс сборки не прервётся.

Rpmrebuild обладает огромным количеством параметров, например, вы можете изменять release пакета, changelog, скрипты, секции Requires, описания пакета и многое другое. Можете даже просто напросто изменить spec-файл, который скрипт сгенерирует сам. Он правда будет немного страшный, но это не играет роли.

Все параметры можно посмотреть при помощи

Код: Выделить всё

rpmrebuild --help


и

Код: Выделить всё

rpmrebuild --help-plugins
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 14:51

Сборка пакетов. Глава 1. RPM. Часть 3. Макроопределения и сборка пакетов

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

Запросы RPM
Сперва, давайте рассмотрим некоторые интересные команды rpm. Например, мы можем очень просто получить практически все параметры пакета. Для этого следует воспользоваться конструкцией

Код: Выделить всё

rpm -q пакет --qf "параметры"
. Для пакета, который в системе не установлен необходимо заменить -q на -qp, а вместо "пакета" использовать имя файла неустановленного пакета.

Параметров довольно много, вот самые основные:

* %{name} — имя пакета
* %{version} — версия пакета
* %{release} — релиз пакета
* %{arch} — архитектура пакета
* %{epoch} — эпоха пакета


Код: Выделить всё

$ rpm -q firefox --qf "%{name}-%{version}-%{release}.%{arch}.rpm"
firefox-2.0.0.4-2.fc7.x86_64.rpm


Из примера видно, что внутри кавычек можно писать любые символы.

Некоторые макроопределения
Теперь рассмотрим определение переменных. Например, мы собираем пакет из SVN, в данном случае обычно используется дата ревизии. В самом начале spec-файла нужно определить переменную date:

Код: Выделить всё

%define date 20070612


Как мы видим, за определение переменных отвечает макроопределение %define. Теперь в любом месте spec-файла мы можем использовать нашу переменную в виде %{date} (скобки не обязательны, но не будем делать так, как ALT Linux). Например, определение основных параметров будет выглядеть примерно так:

Код: Выделить всё

Version: 0.5
Release: 1.svn%{date}%{?dist}


По поводу %{?dist}. Во второй части мы определили этот параметр, обратите внимание на знак вопроса "?". Он означает следующее, если переменная определена, то выводится её значение, в противном случае ничего не выводится.

Крайне популярным макроопределением является конструкция

Код: Выделить всё

%if условие
действие1
%else
действие2
%endif


.

Или подобная без %else. Суть проста, если условие стоящее при %if истина, то выполняется действие1, в противном случае выполняется действие2.

Допустим мы опять же собираем что-нибудь из SVN. Обычно внутри архива, если он из SVN, вместо каталога %{name}-%{version} указывают просто %{name} (архив sim-0.9.5.tar.bz2 внутри имеет каталог sim, так как финального релиза sim 0.9.5 не существует. Конечный же релиз будет иметь первым каталогом sim-0.9.5). Чтобы всякий раз не переписывать spec-файл можно сделать следующие макроопределения:

Код: Выделить всё

%define svn 1
...
%prep
%if %{svn}
%setup -q -n %{name}
%else
%setup -q
%endif


Если переменная svn не определена, то будет выполняться часть сценария после %else. Можно также использовать более строгое условие (не забудьте про кавычки):

Код: Выделить всё

%define svn 1
...
%prep
%if "%{svn}" == "1"
%setup -q -n %{name}
%else
%setup -q
%endif


Внутри всех секций spec-файла мы можем использовать любые команды Linux, без каких либо "наворотов", а вот в шапке файла не всё так просто. Например, нам нужно определить версию firefox для пакета (допустим epiphany) и прописать ее в секцию Requires:. Выглядеть это будет следующим образом:

Код: Выделить всё

Requires:       firefox = %(rpm -q firefox --qf "%%{version}")


Обратите внимание на то, что внешняя команда выполняется в "%()" (почти, как в bash — "$()") и в spec-файле необходимо ставить два знака % в параметрах. Таким образом можно вызывать любые команды Linux, например, для определения версии ядра.

Ещё одним популярным макроопределение является конструкция %ifarch %endif. Если архитектура соответствует указанной после %ifarch, то выполняется какое либо действие. Архитектуры бывают i386, i486, i586, i686, i?86, x86_64, и понятное дело некоторые другие, с которыми вы наверно не столкнётесь.

Как уже отмечалось выше во всех секциях spec-файла вы можете использовать любые команды, включая for, while, if и др.

Сборка пакета
Теперь перейдём непосредственно к сборке пакета. Исходники и патчи должны лежать в каталоге SOURCES, а spec файл в каталог SPECS (см. ч. 2). После этого нужно отдать команду:

Код: Выделить всё

rpmbuild -ba spec-файл


После этого пакет соберётся (или не соберётся, а вывалится с ошибками), и в подкаталогах каталога RPMS появятся бинарные пакеты (а также пакет debuginfo, см. ниже), а в каталоге SRPMS появится исходник.

Очень часто, перед самым завершением сборки, rpmbuild выдаёт сообщение о найденных, но неупакованных файлах. Это означает, что вы просто не указали их в секции %files. Необходимо просто добавить их туда. Если же вы не хотите чтобы эти файлы попадали в пакет, то можно воспользоваться одним из следующих способов:

1. Добавить в секцию %files макроопределение %exclude путь_к_файлу/файл,
2. Добавить в начало spec-файла макроопределение %define _unpackaged_files_terminate_build 0.

Если необходимо собрать только бинарник или только исходник, то вместо -ba следует использовать -bb и -bs соответственно. Из полезных параметров rpmbuild можно отметить --clean (удалить весь мусор), --rmsource (удалить исходники из каталога SOURCE) и --target=архитектура (собрать пакет под конкретную архитектуру).

Можно также выполнять сценарии только в определённой секции. Описывать подобные параметры я не буду, см. man rpmbuild.

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

Код: Выделить всё

%debug_package %{nil}

%__os_install_post    \
        /usr/lib/rpm/redhat/brp-compress \
        /usr/lib/rpm/redhat/brp-strip %{__strip} \
        /usr/lib/rpm/redhat/brp-strip-shared %{__strip} \
        /usr/lib/rpm/redhat/brp-strip-static-archive %{__strip} \
        /usr/lib/rpm/redhat/brp-strip-comment-note %{__strip} %{__objdump} \
%{nil}

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

Цифровые подписи
Для подтверждения достоверности пакета, а тем более для публичного репозитория просто необходимо подписывать свои пакеты. Сперва нам необходимо сгенерировать цифровую подпись, командой gpg --gen-key. Никаких проблем у вас возникнуть не должно, выбирайте метод DSA и длину ключа не меньше 2048, впрочем мы его уже генерировали во второй части, и даже добавляли макроопределения в локальный файл rpm-макросов.

Для подписи пакета при сборки, необходимо передать rpmbuild параметр --sign. Для уже собранного пакета нужно отдать команду rpm --addsign пакет или rpm --resign пакет. Проверить подпись можно командой rpm -Kv пакет.

Бекпортирование
Это слово пришло к нам из мира Debian, где оно подразумевает адаптацию пакета из более нового Debian (либо стабильного, либо нет) в более ранний стабильный. В Fedora подобных терминов нет, так как дистрибутив обновляется раз в пол года. Однако иногда очень хочется собрать какой-либо пакет из более новой Fedora (а то и development) в более старую.

Тут может быть несколько подходов. Первый, просто пересобрать пакет, внимательно изучив зависимости. Может так сложиться, что в более новой Fedora один пакет распался на много маленьких или вообще изменил название. Возможно придётся подсобрать недостающие пакеты.

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

Оба подхода на первый взгляд просты, но могут доставить не мало мороки. С чем вы точно не столкнётесь, так это с проблемой различных макросов в spec-файлах для разных дистрибутивов Fedora. По крайней мере до выхода 5-й версии RPM.

На этом я заканчиваю описывать сборку RPM пакетов и соответственно первую главу. Во второй главе мы рассмотрим сборку DEB пакетов.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 15:32

Сборка пакетов. Глава 2. DEB. Часть 1. Общие понятия.

Deb пакеты используются в таких популярных дистрибутивах, как Debian и Ubuntu. В отличии от различных RPM-base дистрибутивов структура этих пакетов нисколько не отличается друг от друга. По этому будет совсем не сложно пересобрать пакет из одного дистрибутива под другой.

Deb-пакет представляет собой gzip-архив, а также скрипты и дополнительные файлы. Вот типичный пример названия пакета:

liferea_1.2.18-0ubuntu1_amd64.deb

Как мы видим имя пакета отделяется от версии символом подчёркивания, также как и архитектура пакета. Через символ ”-” указывается некоторое подобие release, хотя точного понятия, как в RPM для него не существует.

Архитектуры бывают i386 (как в rpm), amd64 (64-х битный пакет, названный в честь первых процессоров AMD), all (тоже что noarch в RPM, независимый от архитектуры), powerpc, а также различные экзотические архитектуры, которые я приводить не буду.

Думаю будет полезно провести некоторое поверхностное сравнение RPM и DEB. Отличий много, однако со стороны конечного пользователя они будут не так заметны. Вообще когда за нас кто-то всё делает (причём качественно), всё хорошо. Как только мы начинаем пытаться делать что-то сами — все плохо.

Итак, самой известной отличительной чертой Deb является наличие мягких зависимостей (Recomends и Suggest). Многие пользователи видят в этом сверхестественную силу и мощь DEB, хотя что с этими зависимостями делать дальше, вероятно, они не знают. Apt-get не умеет обрабатывать их, Aptitude умеет при помощи двух опций в настройках apt:

Код: Выделить всё

Aptitude::Recommends-Important "true";
Aptitude::Suggests-Important "true";


В любом случае в мягкие зависимости прописываются пакеты, без которых наш пакет работать будет в любом случае. И на мой взгляд абсолютно все равно жёсткая зависимость или мягкая, так как мы либо ставим все пакеты из Recomends или Suggest, либо не ставим ничего, либо система будет чистенькая с урезанными функциями некоторых пакетов, либо грязненькая с кучей всевозможных пакетов.

Вторым полезным отличием является возможность указания в зависимостях логического или.

Код: Выделить всё

Depends: debootstrap | cdebootstrap


В RPM подобная проблема исправлялась добавлением Provides в пакет, от которого зависит собираемый пакет. Однако гораздо проще сделать так, как это делается в DEB.

Ещё в качестве полезности можно выделить вот что. Все скрипты и служебные файлы лежат в каталоге /var/lib/dpkg/info/. Так что мы можем быстро на них взглянуть, а не мучится с различными командами.

Собственно на этом все. По Deb пакету нельзя определить на какой машине он был собран, у пакета нет различных макросов, как в RPM.

В общем как видно, преимущества и недостатки одного и другого довольно сомнительны. Но это только по отношению к конечному пользователю. Как только мы начинаем собирать свой собственный пакет (почти с нуля), недостатки Deb становятся более очевидными.

К ним можно отнести:

1. Множество файлов конфигурации (против 1-го spec у rpm);
2. Множество служебных dh_* команд, которые не совсем понятно что делают;
3. Исходник идёт не одним файлом, а 2-я, 3-я;
4. Сложность в накладывании патчей;
5. Возможность делать одно и тоже несколькими разными способами.

Внутренний язык dh_make тоже не делает сборку особо привлекательной.

Отдельно хочется сказать о цифровой подписи к пакету. Сам Deb пакет, в отличии от RPM, не подписывается, а подписываются различные текстовые файлы, содержащие контрольные суммы. В конечном счёте все доходит до подписи Release.gpg в репозитории. Так что если вы каким-либо образом подсунете в главный репозиторий левый пакет, то идентифицировать его подлинность будет невозможно. Более того, обычно для подписи самого репозитория используется ключ с пустым паролем.

Хотя пакеты для Debian и Ubuntu и лежат все в одном месте, но из-за различных репозиториев и системы pool найти что-либо бывает сложно. Я рекомендую воспользоваться соответственно сайтами packages.debian.org и packages.ubuntu.com. На них вы сможете легко понять, к какому дистрибутиву, какой пакет относится.

В следующей части мы поговорим о сборке Deb-пакетов.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 16:09

Сборка пакетов. Глава 2. DEB. Часть 2. Сборка пакетов

В этой статье мы научимся собирать .deb пакеты, а также подписывать их.

Для сборки пакета нам понадобятся debhelper, dh-make, devscripts, fakeroot, а также необходимые компиляторы и интерпретаторы. Кроме того нам нужна программа, которую будем компилировать. Сам тарбол нам как бы и не нужен, нам нужно только дерево исходников, которое необходимо распаковать. Главный каталог должен называться следующим образом: имяпакета-версияпакета, в противном случае возникнут проблемы.

В итоге у нас должны получиться бинарные файлы, исходник *orig*tar.gz, *diff*gz* и файлы .dsc и .changes. Возможно обойтись без файлов *orig*tar.gz и *diff*gz* заменив их одним тарболом, в котором находятся все служебные файлы, однако начиная с версии Debian 4.0 подобные ухищрения не приветствуются.

Итак, я для удобства рекомендую создать в вашем домашнем каталоге папку, допустим, BUILD, в ней для каждого пакета создавать каталог по его имени, и уже внутри последнего каталога размещать дерево исходников. Для чего так сложно? Потому, что собранные пакеты будут помещаться на уровень выше дерева и у вас скоро весь каталог BUILD забьётся кучей файлов.

Если вы хотите использовать Цифровую подпись, то необходимо добавить в ваш файл .bashrc следующие строки:

Код: Выделить всё

export EMAIL=your@gpg.email
export DEBFULLNAME="YOUR GPG NAME"
export DEBEMAIL=your@gpg.email


Имя и почтовый адрес должны быть такими же, какими вы их задали при создании GPG ключа. Если вы создали ещё и описание, то его тоже необходимо указать в переменной DEBFULLNAME.

Итак, для начала необходимо создать служебные файлы. Для этого нужно зайти в каталог исходников и отдать команду dh_make --createorig. Вам необходимо выбрать нужный тип пакета. Если у вас будет только один бинарный пакет, то нажимаем s, если несколько — то l. Для модулей ядра нужно выбрать k. О cdbs (b) мы поговорим как-нибудь потом.
Можете также вызывать команду dh_make вместе с ключом -c чтобы указать лицензию пакета.

Мы сперва рассмотрим пакет, содержащий несколько бинарников (то, что обычно ни в каких документациях не рассматривается). А потом скажем несколько слов относительно single binary.

После запуска dh_make создастся каталог debian, в котором будет лежать довольно большое количество файлов. Все файлы *.ex и *.EX можно в принципе удалить сразу и создавать только по мере надобности.

В файле control указываются все необходимые параметры. Он делится на секции Source и Package. Секций Package может быть несколько в зависимости от того сколько бинарных пакетов получится при сборке. Ниже приведён пример файла control для пакета liferea:

Код:

Source: liferea Section: gnome Priority: optional Maintainer: Franz Pletz <fpletz@franz-pletz.org> Uploaders: Luis Rodrigo Gallardo Cruz <rodrigo@nul-unu.com> Build-Depends: autotools-dev, debhelper (>> 4.0.0), libgtkhtml2-dev Standards-Version: 3.7.2.0 Package: liferea Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, liferea-xulrunner (=${Source-Version}), dbus-1-utils Description: feed aggregator for GNOME Liferea is a simple FeedReader clone for GNOME. It is a reader for RSS/RDF feeds which also supports CDF channels, Atom/Echo/PIE feeds and OCS directories. . Liferea is an abbreviation for Linux Feed Reader. . Homepage: http://liferea.sourceforge.net/ Package: liferea-xulrunner Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Provides: liferea-mozilla, liferea-gtkhtml Conflicts: liferea-mozilla (<< 1.0.17-1), liferea-gtkhtml (<< 1.0.27-2) Replaces: liferea-mozilla (<< 1.0.17-1) Description: xulrunner-based rendering library for Liferea Liferea is a simple FeedReader clone for GNOME2. It is a reader for RSS/RDF feeds which also supports CDF channels, Atom/Echo/PIE feeds and OCS directories. . Liferea is an abbreviation for Linux Feed Reader. . Homepage: http://liferea.sourceforge.net/ Package: liferea-mozilla Architecture: all Depends: liferea-xulrunner Description: transitional dummy package Previous versions of liferea had several rendering engines to choose from. This is a dummy package to ease transition from those versions. . It can be safely removed from your system after updating. Package: liferea-gtkhtml Architecture: all Depends: liferea-xulrunner Description: transitional dummy package Previous versions of liferea had several rendering engines to choose from. This is a dummy package to ease transition from those versions. . It can be safely removed from your system after updating.


Разберём его поподробней. Итак, в секции Source указывается имя исходника, секция (Section), к которой пакет будет отнесён в репозитории, Priority — приоритет, подробнее смотреть здесь. Maintainer и Uploaders — думаю без вопросов, Build-Depends — пакеты необходимые при сборке пакета, Standards-Version — версия документа Debian-Policy (не нужно трогать).

Далее идёт описание для бинарного пакета, Packages — его имя, Architecture: архитектура пакета, может быть any (сама превратится в нужную платформозависимую архитектуру) и all (платформонезависимую), Depends — зависимости которые обязательно требуются для установки пакета (благодаря двум переменным в этом поле зависимости появятся автоматически, однако иногда следует добавлять их вручную), Description — описание пакета, причём в первой строке используется краткое описание, а в остальных строках, начиная с пробела, длинное. Новые абзацы отделены строкой с точкой.

По поводу зависимостей. Существуют ещё два типа зависимостей Suggests и Recommeds. Первый тип зависимостей нацелен на расширение возможностей нашего пакета, второй настоятельно рекомендует установить данные пакеты. Aptitude ставит зависимости Recommeds по умолчанию, apt-get не обрабатывает ни те, ни другие. Существуют также Pre-Depends, но их использовать не рекомендуется.

В зависимостях могут применяться указания версий, как видно из примера. Допустимыми символами сравнения являются: <<, <=, =, >=, и >> для “строго раньше чем”, “раньше или равно”, “в точности равно”, “равно или позже” и “строго позже чем” соответственно.

Также в control файле могут применяться следующие теги: Provides — дополнительное имя для нашего пакета (эдакое виртуальное), Replaces — список пакетов, которые будут удалены после установки нашего пакета, Conflicts — пакеты с которыми наш пакет заведомо конфликтует.

Вторым по важности файлом является файл rules. Именно в нем находится все необходимое для компиляции пакета и упаковки его в бинарные пакеты. Этот файл есть ничто иное, как скрипт make, с использованием команд dh_*.

В нем действительно много секций, и много строк, но нам нужно будет изменять секции config.status, build и install. В этих секциях, соответственно, необходимо прописать команды для конфигурации пакета (если они нужны), для его сборки и для установки. Если мысленно выкинуть всевозможные dh-команды, то скрипт становится не таким уж страшным. Правда dh-команды разумеется нужны. Ниже приведен файл rules:

Код:

#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. CFLAGS = -g -O2 ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif config.status: configure dh_testdir cp -f /usr/share/misc/config.sub config.sub cp -f /usr/share/misc/config.guess config.guess CFLAGS="$(CFLAGS)" ./configure --prefix=/usr \ --mandir=\$${prefix}/share/man \ --sysconfdir=/etc --disable-gecko \ --disable-gtkhtml2 --enable-sm ln -s $(CURDIR)/liferea.1 $(CURDIR)/debian/liferea-bin.1 ln -s $(CURDIR)/liferea.1 $(CURDIR)/debian/liferea-add-feed.1 build: build-stamp build-stamp: config.status dh_testdir $(MAKE) touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp config.log debian/liferea-bin.1 \ debian/liferea-add-feed.1 -$(MAKE) distclean dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1 $(MAKE) install \ DESTDIR=$(CURDIR)/debian/liferea # add the debian menu icon cp debian/liferea.xpm debian/liferea/usr/share/liferea/pixmaps/ # Link documentation mkdir -p debian/liferea/usr/share/doc/liferea ln -s ../../liferea/doc/html debian/liferea/usr/share/doc/liferea/html dh_movefiles --sourcedir=debian/liferea # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs ChangeLog dh_installdocs dh_installman debian/liferea-bin.1 debian/liferea-add-feed.1 dh_installmenu dh_gconf dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install


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

В секции config.status идет обычный запрос на конфигурацию пакета. Обратите внимание, что вам необходимо правильно задавать каталоги, так как по умолчанию configure выбирает /usr/local. Секция build вызывает секцию build-stamp, в которой происходит обычный make ($(MAKE) = make).

Затем выполняется install. Там идет обычный make install и дополнительные команды для правильной установки данного пакета. Заметьте, что инсталляция происходит в каталог $(CURDIR)/debian/liferea, где $(CURDIR) каталог дерева исходников. Теперь одна из важных вещей. Нам необходимо разобрать файлы из общего каталога liferea по нашим бинарным пакетам. Именно для этих целей и служит команда dh_movefiles. В качестве параметра указывается каталог в который была произведена инсталляция. Если вы инсталлировали пакет в каталог $(CURDIR)/debian/tmp, то никаких параметров dh_movefiles передавать не нужно.

Все данные о том какие файлы в какие пакеты положить dh_movefiles берёт из файлов (в каталоге debian) название-бинарного-пакеты.install. Создайте их столько же, сколько будет бинарных пакетов и пропишите в них названия файлов с полным путём относительно каталога в который была установлена программа, но без первого слеша. Можно использовать маски.

После разбора файлов выполняется секция binary-arch, которая создаёт deb-пакет. В ней, например, видно, как устанавливаются man файлы.

В deb-пакете также могут присутствовать скрипты postinst, preinst, postrm и prerm, которые выполняются соответственно, после инсталляции, перед инсталляцией, после удаления и перед удалением. Для каждого из пакетов необходимо создать файл имя-бинарного-пакета.postinst и т. п. в них можно разместить любые команды.

Теперь рассмотрим changelog. Именно в нем мы будем указывать версию нашего пакета. Версией в Debian называется все, что идёт после имени пакета. В deb нет тегов release и epoch как в rpm, однако вы можете запросто задать что-то наподобие 3:1.0.4-15.feisty.0. До ":" идёт эпоха, после "-" идёт релиз. Файл changelog следует редактировать при помощи команды dch. Если её вызвать без параметра, то будет изменена последняя запись в changelog, а если dch -i, то будет добавлена новая:

Код: Выделить всё

liferea (1.0.27-2) unstable; urgency=low

  * Remove the GtkHTML rendering plugin. This plugin is basically unusable
  on 64bit architectures. liferea-gtkhtml is now just a dummy package for
  upgrades (Closes: #379900, #407152, #361376, #368866).
  * Remove upstream's NEWS file, it contains only version release dates.

 -- Luis Rodrigo Gallardo Cruz <rodrigo@nul-unu.com>  Sun, 11 Feb 2007 21:18:16 -0600

Также в changelog вы можете менять принадлежность пакета к дистрибутиву (сразу после версии). В данно примере идёт unstable, в Ubuntu там должно быть что-то типа feisty, edgy и т. п.

Что касается single binary то там все намного проще. После команды dh_make, вам нужно подправить control и changelog. Возможно немного rules. И далее пакет соберётся сам собой.

Для сборки пакета нам понадобится команда debuild которую следует отдавать всё в том же каталоге исходников. После того, как пакеты соберутся, вы должны будете подписать пакет (если настроили GPG), вернее не пакет, а два текстовых файла, которые появятся в процессе сборки. Это файлы .dsc и .changes. Первый из них несёт информацию об исходнике, второй нужен только для помещения пакета в репозиторий.

У debuild есть параметр clean, который позволяет очистить дерево исходников и папку debian от ненужных файлов.

В этой статье я попытался передать основные принципы сборки deb пакетов, однако прекрасно понимаю, что нюансов здесь очень много, но описать их все я конечно же не смогу. Вам возможно следует почитать Руководство начинающего разработчика Debian, в котором некоторые аспекты изложены поподробней, а также Руководство по политике Debian. В следующей статье мы поговорим о том, как создавать репозитории для rpm и deb пакетов.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 17:06

Сборка пакетов. Глава 2. DEB. Часть 3. Накладывание патчей

Как и в RPM, в deb-пакетах можно накладывать патчи, однако это довольно трудоёмкий и неочевидный процесс. И как всегда это можно делать разными способами. Рассмотрим один из них, dpatch (нам понадобится одноимённый пакет), на примере пакета liferea.

Первым делом нам нужно будет создать сам патч. Для этого, как и в случае с RPM, необходимо иметь два каталога исходников. Первый оригинальный, например, liferea-1.4.3b.orig, второй с изменениями liferea-1.4.3b. Патч накладывается командой

Код: Выделить всё

diff -urN liferea-1.4.3b.orig liferea-1.4.3b > mypatch.patch


Далее необходимо превратить этот патч в формат dpatch. Для этого нужно отдать следующую команду:

Код: Выделить всё

dpatch patch-template -p "01_mypatch" \
"mypatch.patch описание" < mypatch.patch \
> 01_mypatch.dpatch


Вторые кавычки в принципе можно опустить. Далее нужно создать в каталоге debian подкаталог patches, в который необходимо скопировать наш .dpatch (или несколько .dpatch’ей). Также нужно создать в этом подкаталоге файл 00list с именами наших .dpatch’ей (каждое имя на новой строке). В нашем случае он будет выглядеть так:

Код: Выделить всё

01_mypatch


Теперь самое главное. В файл rules сразу после шапки нужно вставить строку

Код: Выделить всё

include /usr/share/dpatch/dpatch.make


Далее в секции, которая выполняется перед конфигурацией пакета (обычно это config.status или если её нет, то build) нужно вставить вызов patch-stamp

Код: Выделить всё

config.status: patch-stamp configure


К секции clean нужно добавить вызов unpatch, думаю понятно для чего:

Код: Выделить всё

clean: unpatch


Также в файл control необходимо добавить зависимость dpatch в поле Build-Depends. После этого можно собирать пакет.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 17:31

Сборка пакетов. Глава 3. Chroot. Mock. Pbuilder

Chroot — это операция изменения корневого каталога. Собирая пакеты в рабочей операционной системе, мы можем дойти до такого момента, когда в системе будет много не нужных библиотек, на которые собираемые пакеты будут линковаться. Также может возникнуть желание собрать пакет под другой дистрибутив, например, под Fedora Core 5, а работаем мы в Fedora 7. В этих случаях целесообразно создать «девственно чистый» образ дистрибутива и собирать пакеты в нем.

Но как создать такой образ? Это делается при помощи утилит mock в Fedora и pbuilder в Debian/Ubuntu. Принцип работы этих утилит следующий. При первом запуске они создают базовый образ операционной системы с минимальным количеством пакетов, необходимых для работы. Это делается либо автоматически (так делает mock) или при помощи определённой команды (pbuilder). Далее образ запаковывается в архив (mock делает это начиная с версии 0.7) и при каждой сборке распаковывается. Далее из репозиториев доставляются необходимые для сборки пакеты и осуществляется сборка. Собранные пакеты складываются в определённый каталог.

Как это делается в Fedora
В Fedora сборкой в chroot занимается mock. В каталоге /etc/mock хранятся файлы конфигураций под разные Fedora и Red Hat. Содержимое этих файлов немного напоминает конфигурацию репозиториев для YUM. Вы можете заменить стандартные репозитории на локальные, тогда процесс будет проходить намного быстрее. Однако если у вас нет выхода в интернет, то вам придётся каким-либо способом сделать копии репозиториев, указанных в секциях [group] и [local]. Эти секции нужны для формирования базового образа.

Вы можете добавить свои репозитории, создав новые секции. Уж точно вам придётся добавить какой-либо свой репозиторий, если собираемый пакет зависит от пакетов, отсутствующих в других репозиториях. Для его создания сложите файлы в какой либо каталог, например, /var/ftp/pub/fedora/myrepo и натравите на него команду:

Код: Выделить всё

createrepo /var/ftp/pub/fedora/myrepo


после чего добавьте в нужный файл конфигурации следующую секцию:

Код: Выделить всё

[myrepo]
name=myrepo
baseurl=file:///var/ftp/pub/fedora/myrepo


По умолчанию используется конфиг default.cfg, который является символической ссылкой на нужный файл.

Сборка пакета осуществляется из-под пользователя. Поэтому необходимо добавить себя в группу mock. Для этого добавьте к строке с именем mock в файле /etc/group после ":" свой логин, например:

Код: Выделить всё

mock:x:495:ashejn


Для сборки пакета следует воспользоваться командой:

Код: Выделить всё

mock [-r дистрибутив] пакет.src.rpm


В качестве дистрибутива используется имя файлов из /etc/mock без расширения .cfg. Если параметр не указан, то используется файл конфигурации default.cfg.

Под архитектурой x86_64 вы также можете собирать приложения для i386. Для этого следует воспользоваться следующей командой:

Код: Выделить всё

setarch i386 mock [-r дистрибутив] пакет.src.rpm


У mock есть по крайней мере один очень полезный параметр. --no-clean позволяет не очищать (не пересоздавать) chroot перед сборкой, чтобы сэкономить время. Удобно, если пакет по какой-либо причине не собрался. Все логи и собранные пакеты будут лежать в каталоге /var/lib/mock/дистрибутив/result.

Mock пока не умеет подписывать пакеты, что в принципе совсем не критично, так как подпись легко добавить при помощи rpm --addsign *.rpm.

Как это делается в Debian/Ubuntu
В Debian/Ubuntu за сборку пакетов в chroot отвечает pbuilder. В принципе им можно пользоваться не только в Debian/Ubuntu, так как это всего лишь набор bash-скриптов. Я собрал этот пакет в Fedora 7 и положил в свой репозиторий. Теперь под Fedora можно собирать пакеты для всевозможных Debian и Ubuntu (ставить этот пакет следует при помощи YUM, так как он потянет за собой другие пакеты).

Pbuilder кажется более навороченным, с кучей параметров, но качество довольно низкое. Первым делом нам необходимо определится под какой дистрибутив мы хотим собирать пакеты. В файле /etc/pbuilderrc следует указать путь к базовому образу, переменная BASETGZ, а также дистрибутив DISTRIBUTION и репозиторий MIRRORSITE в зависимости от системы Debian или Ubuntu. В принципе все эти параметры можно передать pbuilder'у через командную строчу.

После этого следует создать базовый образ командой:

Код: Выделить всё

/usr/sbin/pbuilder create


Для создания базового образа для архитектуры i386 под x86_64 эта команда сильно усложняется:

Код: Выделить всё

/usr/sbin/pbuilder create --debootstrapopts --arch --debootstrapopts i386


Для пересборки пакета нам необходимо иметь исходные тексты .deb-пакета. В них входит файл с расширением .dsc. Необходимо отдать команду:

Код: Выделить всё

/usr/sbin/pbuilder build .dsc-файл


или для архитекты i386 из-под x86_64:

Код: Выделить всё

linux32 /usr/sbin/pbuilder build .dsc-файл


Ф Fedora вместо linux32 следует использовать setarch i386. Собранный пакет будет лежать в каталоге /var/cache/pbuilder/result/. Однако подобная сборка имеет по крайней мере три недостатка: сборка только из-под root, возможна только пересобрка (а что делать если у нас только дерево исходников?) и пакет не будет подписан, что в случае с .deb не так тривиально исправить.

Эта проблема решается при помощи команды pdebuild. Но это опять не сахар. Она не понимает кучи параметров, такие как --basetgz, --distribution, так что вам под каждый дистрибутив и архитектуру придётся исправлять конфигурационный файл, однако его можно создать в домашнем каталоге под именем .pbuilderrc и указать свои каталоги для сборки (в моей сборке на каталог result стоят права 1777, так что собирать можно и в стандартные каталоги). Однако предпочтительнее для каждого дистрибутива создать собственный конфигурационный файл (как в mock) и передавать pdebuild конфиги через параметр --configfile файл.

Эта команда делает тоже, что и стандартная для Debin/Ubuntu — debuild. Для подписи пакета необходимо, чтобы цифровая подпись существовала и вам был известен идентификатор ключа (gpg --list-key в строке pub после "/").

Для сборки пакета необходимо отдать команду:

Код: Выделить всё

pdebuild [--configfile файл_конфигурации] --auto-debsign --debsign-k keyid


при этом необходимо находиться в дереве исходников, в котором находится папка debian с правилами для сборки пакета.

После сборки у вас два раза спросят секретную фразу (для подписи двух файлов) и сборка будет завершена.

В Debian/Ubuntu есть пакет mock. Под этими дистрибутивами вы также сможете собирать пакеты под Fedora. А по чему собственно только под Fedora? Под любой rpm-дистрибутив, который поддерживает подключение к репозиториям через YUM. Вам будет необходимо только создать пакеты с зависимостями для генерации базового образа, что скорее всего не станет тривиальной задачей. В прочем они могут в том или ином виде уже существовать.
Спасибо сказали:

Аватара пользователя
Juliette
Сообщения: 5058
Статус: ROSA Lab
ОС: Ubuntu LTS, Mandriva 2011

Re: Сборка RPM и DEB пакетов

Сообщение Juliette » 15.10.2008 17:49

Сборка пакетов. Глава 4. Создание репозитория (основные понятия)

Я не буду вдаваться в подробности, и уж точно не буду давать пошаговый howto. В основном расскажу об основных приёмах и правилах.

Для RPM никакого выбора нет. Вам понадобится только пакет createrepo. Под репозиторий вам необходимо отвести каталог, который будет виден через http или ftp (если вы хотите использовать репозиторий только локально, то подойдёт любой каталог). Необходимо создать структуру репозитория. Например, такую:

Код: Выделить всё

/var/ftp/myrepo/fedora-7/
/var/ftp/myrepo/fedora-7/i386
/var/ftp/myrepo/fedora-7/SRPMS
/var/ftp/myrepo/fedora-7/x86_64


Все srpm-пакеты нужно складывать в каталог SRPMS, все пакеты noarch необходимо подкладывать в каждый из каталогов (кроме SRPMS). Пакеты i686, i586 также кладутся в каталог i386. По правилам Fedora в каталоге x86_64 могут лежать пакеты i?86 (некоторые системные библиотеки, используемые для совместимости).

Далее необходимо переиндексировать наши репозитории, например, таким элементарным скриптом:

Код: Выделить всё

for i in `ls -Rd /var/ftp/myrepo/fedora-7/*`; do
    createrepo $i;
done


После этого нужно подключить эти репозитории к менеджеру пакетов YUM (или APT-RPM, или Smart).

Если у вас возникает необходимость в удалении старых пакетов из репозитория, то необходимо воспользоваться программой repomanage из пакета yum-utils. Нам понадобится единственная её возможность, отображать список устаревших пакетов.

Скрипт переиндексации примет такой вид:

Код: Выделить всё

for i in `ls -Rd /var/ftp/myrepo/fedora-7/*`; do
    rm -f $(repomanage -o $i)
    createrepo $i;
done


На вход команде rm подаётся список устаревших файлов, который генерируется командой repomanage с ключом -o.

А вот в Debian (и Ubuntu) уже существуют различные программы для ведения репозитория. Это DAK (Debian Archive Kit), reprepro, mini-dinstall, а также apt-ftparchive (просто для переиндексации списка пакетов).

DAK – это главная система для репозитория Debian. Самый большой её недостаток это то, что по ней нет никакой документации кроме маленького howto в самом пакете. Также не понятно, а что именно она умеет. Согласитесь фраза “умеет всё” немного расплывчата. Настройка её очень сложна, она использует posgresql и разумеется умеет работать с pool. Что такое pool можно почитать в документации Debian или просто посмотреть, допустим, здесь.

Reprepro – превосходная замена DAK. Простенькая, быстро настраиваемая, с немного занудным синтаксисом. Работает с pool, умеет перемещать пакеты из unstable в, например, testing. Однако просто убийственным её недостатком является невозможность хранить в одном и том же месте пакеты с разными версиями. Для вашего репозитория вероятно всё равно, а вот там где сидит куча программистов и за день делают 10 версий одного и того же пакета (причём не понятно какой из них стабильный) просто неприемлема.

Увы, если вам нужно хранить много версий одного и того же пакета, то остаётся только mini-dinstall. Он медленный (так как всякий раз заново, при помощи apt-ftparchive переиндексирует репозиторий), не очень надежный и мёртвый (то есть не развивается). Также он не работает с pool’ом, что немного изменяет синтаксис для APT. С другой стороны если написать некоторые скрипты, которые отслеживают его ошибки, если написать скрипты для переноса файлов из unstable в stable, то он не так уж и плох. Единственное, что вы не сможете увеличить, так это скорость переиндексации. Все зависит только от количества пакетов.

Все эти системы обладают incoming механизмом, который позволяет закидывать пакеты в определённый каталог (при помощи dupload или dput), после чего происходит его проверка и запихивание в нужную часть репозитория.

Последние две программы легко настроить просто читая файл конфигурации. Ещё существует debarchiver, который развивается, но что он умеет я сказать не могу, так как практически не пользовался им.
Спасибо сказали: