Packaging HOWTO
(revision 0.3)

Dmitry V. Levin <ldv@altlinux.ru>
ALT Linux Team

Введение

При разработке изменений и дополнений к rpm решались следующие задачи:

Обеспечить желаемую функциональность:
наши пакеты должны отвечать определенным правилам, о которых пойдет речь несколько позже. Для этого надо, чтобы spec-файлы обеспечивали выполнение этих правил.
Помочь разработчику:
так как spec-файлы все еще пишут люди, то их работу нужно свести к тому минимуму, который, собственно, и требует участия человека. Разработчик не должен копировать блоки кода из файла в файл, ибо эта неинтеллектуальная работа отнимает массу сил и чревата ошибками. Для этого есть макросы. Если какой-то код появляется в разных spec-файлах более одного раза, то надо написать макрос(ы).
Сделать spec-файлы более читабельными:
те, кто эти файлы читает - тоже живые люди. Им будет удобнее, если в наименовании, расположении и использовании различных элементов spec-файлов будет определенный порядок.

Особенности этой версии rpm.

Новые макросы.

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

X11R6:
%_x11dir, %_x11bindir, %_x11libdir, %_x11includedir, %_x11mandir, %_x11datadir;
лицензии:
%_licensedir;
меню:
%_menudir, %_iconsdir, %_miconsdir, %_liconsdir;
emacs:
%_emacslispdir;
другие системные:
%_initdir, %_lockdir, %_logdir.

Управление опциями компилятора gcc.

%add_optflags <options>:
добавить указанные параметры в стандартный набор %opflags;
%remove_optflags <options>:
убрать указанные параметры из стандартного набора %opflags;
%optflags_core:
базовые параметры;
%_optlevel:
уровень оптимизации;
%optflags_optimization:
параметры, отвечающие за оптимизацию, кроме архитектурно-зависимых;
%optflags_warnings:
warning options;
%optflags_debug:
debugging options;
%optflags_shared:
параметры, применяемые для создания relocatable файлов;
%optflags_nocpp:
параметры, отключающие поддержку C++ exceptions и C++ RTTI;
%optflags_notraceback:
-fomit-frame-pointer;
%optflags_fastmath:
-ffast-math;
%optflags_strict:
-fstrict-aliasing;
%optflags_kernel:
параметры, используемые при компиляции ядра и его модулей.
По умолчанию, стандартный набор %opflags состоит из "%optflags_core %optflags_warnings %optflags_optimization".

Макросы-надстройки над утилитой make.

%make_build:
вызов make с параметром, обеспечивающим оптимальную параллельную сборку в данной среде;
%make_install:
вызов make c инициализацией переменной INSTALL, что в случае корректной реализации Makefileов пакета позволяет сохранить дату последней модификации файлов, что особенно важно для документации;
%makeinstall:
``%make_install <инициализация других переменных, используемых многими Makefileами> install''.

Регистрация документации в формате info.

%install_info:
регистрация новых/обновленных info-страниц;
%uninstall_info:
отмена регистрации удаленных info-страниц.

Регистрация меню.

%update_menus:
регистрация новых/обновленных меню;
%clean_menus:
отмена регистрации удаленных меню.

Вспомогательные макросы %configure.

%__libtoolize:
путь к скрипту libtoolize;
%_configure_script:
путь к скрипту configure;
%_configure_target:
целевая платформа для configure;
%_configure_gettext:
-without-included-gettext.

Серверные макросы.

%post_service:
регистрация нового сервиса при установке, перезапуск при обновлении;
%preun_service:
отмена регистрации сервиса и его выключение при удалении.

Макросы, определяющие некоторые аспекты packaging policy.

%buildroot:
значение BuildRoot;
%_defattr:
атрибуты файлов и каталогов по умолчанию для каждой секции %files и для каждого файла, включаемого в этих секциях;
%_compress_method:
метод, используемый при сжатии документации в секции %install;
%_strip_method:
метод, используемый при обработке ELF-файлов в секции %install;
%_findreq_default_method:
метод, используемый по умолчанию при поиске требуемых зависимостей;
%_findprov_default_method:
метод, используемый по умолчанию при поиске предоставляемых зависимостей;
%set_strip_method:
изменить значение макроса %_strip_method;

Вызов вспомогательных программ.

%find_lang:
вызов /usr/lib/rpm/find-lang
%strip_executable:
вызов /usr/lib/rpm/brp-strip для обработки ELF executables;
%strip_relocatable:
вызов /usr/lib/rpm/brp-strip для обработки ELF relocatables;
%strip_shared:
вызов /usr/lib/rpm/brp-strip для обработки ELF shared objects;
%strip_static:
вызов /usr/lib/rpm/brp-strip для обработки ELF ar archives;
%cleanup_build:
вызов /usr/lib/rpm/brp-cleanup;
%compress_docs:
вызов /usr/lib/rpm/brp-compress;
%strip_binaries:
вызов /usr/lib/rpm/brp-strip;
%clean_buildroot:
выполнение rm -rf %buildroot, если %buildroot не указывает на настоящий /.

Управление процессом сборки.

%buildmulti:
Альтернативная директива %build для случая, когда в секции %build происходит заполнение %buildroot. Вообще говоря, такой техники стоит избегать во всех случаях, когда это возможно.

Версии некоторых установленных в системе пакетов.

glibc:
%__glibc_version, %__glibc_version_major, %__glibc_version_minor;
python:
%__python_version;
%get_version:
Версия указанного пакета;
%get_release:
Релиз указанного пакета;
%get_serial:
Serial указанного пакета;
%add_serial:
Serial указанного пакета в виде, пригодном для включения в spec-файл.
Эти макросы, как правило, используются в пакетах, сборка которых возможна с различными версиями этих программ, если эти версии правильно учитывать.

Прочие макросы.

%intel:
список архитектур intel, совместимых с i386;
%amd:
список архитектур amd, совместимых с i386;
%ix86:
список всех архитектур, совместимых с i386;
компоненты макроса %packager:
%packagerName, %packagerAddress.

Новыe параметры rpm.

-bE:
новый режим работы rpm, при котором происходит только подстановка макросов;
-nowait-lock:
не блокировать процесс, если база данных rpm занята;
-fancypercent:
отображать дополнительную информацию о процентах проделанной работы при установке/обновлении пакетов.

Новые возможности rpm.

Автоматический поиск требуемых и предоставляемых зависимостей.

В дополнение к стандартному поиску зависимостей от/для разделяемых библиотек, реализована поддержка поиска требуемых зависимостей для shell и perl-скриптов, а также поддержка поиска предоставляемых зависимостей для perl-скриптов.

Изменение семантики тэгов, управляющих поиском зависимостей.

Новые возможности rpm по автоматическому поиску зависимостей при сборке пакетов управляются, как и прежде, значениями тэгов AutoReq, AutoProv и AutoReqProv. К стандартным значениям yes/no (true/false), таким образом, добавлены новые возможные значения, являющиеся именами методов поиска зависимостей: Значением тэга может являться как один метод, так и перечисление методов. По умолчанию, для каждого под пакета собираемого пакета AutoReq = AutoProv = yes, что на практике означает использование макросов %_findreq_default_method и %_findprov_default_method для определения методов поиска зависимостей.

Автоматическое сжатие man и info-документации с поддержкой различных методов сжатия.

Вся документация пакета, распознаваемая как man или info-документация, по окончании работы секции %install, сжимается согласно выбранному методу. Поддерживаются следующие методы сжатия: Какой метод будет использован в каждом конкретном случае, зависит от значения макроса %_compress_method; значение по умолчанию для этого макроса - auto. По окончании процедуры сжатия производится выравнивание ссылок, которые, возможно, требуют коррекции в связи с изменениями имен файлов в процессе их сжатия.

Автоматическое удаление отладочной информации из ELF-файлов с поддержкой различных стратегий выбора файлов, подлежащих обработке.

Зачастую возможно уменьшить размер получаемых в результате сборки пакета ELF-файлов без потери качества за счет удаления из них отладочной информации. Поэтому по окончании работы секции %install все ELF-файлы выбранных типов обрабатываются программой strip. Выбор типов файлов определяется значением макроса %_strip_method, которое есть набор из следующих возможных значений: Кроме того, есть возможность вызывать strip вручную, для этой цели предназначены макросы %strip_executable, %strip_relocatable, %strip_shared, %strip_static. Синтаксис этих макросов подробно изложен в ``/usr/lib/rpm/brp-strip -help''.

Автоматическая перекомпиляция python-модулей.

Как известно, python-модули обычно компилируют в байтовую форму для увеличения быстродействия при последующей работе с ними. Каждый такой модуль, помимо всего прочего, хранит время своего создания и полное имя файла, в котором должен находиться. В связи с последним обстоятельством скомпилированные модули, созданные в результате работы секции %install, непригодны, ибо не могут быть использованы после установки пакета. По этой причине теперь по окончании работы секции %install производится перекомпиляция всех python-модулей таким образом, чтобы их можно было использовать после установки пакета. В качестве байт-компилятора будет использоваться программа, имя которой хранится в макросе %__python. Обычно это /usr/bin/python, однако в некоторых случаях может потребоваться изменить это значение на другое (например, в случае сборки пакета python или если по какой-то причине перекомпиляция не нужна).

BuildRoot.

Времена, когда тэг BuildRoot в spec-файле определял, какой каталог rpm будет использовать в качестве BuildRoot, прошли безвозвратно. Теперь этот таг не несет никакой информации и может (и должен) быть опущен. Вместо этого используется значение макроса %buildroot, который определен как ``%{_tmppath}/%{name}-buildroot'' в файле /usr/lib/rpm/macros и может быть переопределен в любом месте, где допускается определять макросы. В случае, если макрос %buildroot не определен либо его значение представляет собой недопустимое значение ``/'', сборка пакета не будет выполнена.

Автоматическая очистка BuildRoot.

Перед выполнением секции %install и по окончании выполнения секции %clean rpm автоматически очищает BuildRoot с помощью макроса %clean_buildroot. Это значит, что больше не нужно использовать эти ужасные ``rm -rf $RPM_BUILD_ROOT''. Секция %clean вообще может (и должна) быть опущена, если в ней не содержится ничего, кроме этого ``rm''. В тех редких случаях, когда в spec-файле производится заполнение BuildRoot не в секции %install, как это должно быть, а в секции %build, что в принципе неправильно, можно перенести точку очистки BuildRoot из начала секции %install в начало секции %build, если заменить директиву %build на макрос %buildmulti.

Упрощение секции %files.

Ранее в начале каждой секции %files было необходимо указывать атрибуты файлов и каталогов создаваемых пакетов с помощью довольно однообразно используемой директивы %defattr. Теперь это происходит автоматически в начале каждой секции %files, а также в начале каждого файла, включаемого в секцию %files с помощью опции -f. Точнее говоря, в качестве этой директивы используется значение макроса %_defattr. Таким образом, прежнее использование директивы %defattr в начале секций и файлов следует считать упраздненным.

Сборка пакетов привилегированным пользователем.

То, что когда-то было необходимостью, со временем стало излишним, а порой и просто опасным. Теперь, когда все пакеты, кроме одного-единственного MAKEDEV, можно (и нужно) собирать непривилегированным пользователем во избежание риска разрушения системы и некорректной сборки, сборка пакетов привилегированным пользователем по умолчанию запрещена. Этот запрет можно снять путем изменения значения макроса %_allow_root_build.

Пожелания packager'у.

Устаревшие конструкции.

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

Фигурные скобки.

Нет смысла засорять текст spec-файла ненужными фигурными скобками. Избавится от них легко:
perl -pi -e 's/%\{([A-Za-z_0-9]+)\}([^A-Za-z_0-9?*]|$)/%$1$2/g' spec-файл

Порядок тэгов.

Рекомендуемый порядок заголовочных тэгов: Name, Version, Release, Serial, далее Summary, License, Group, Url, Packager, BuildArch, потом Source, Patch, далее Provides, Requires, PreReqs, Conflicts, и, наконец, Prefix, BuildPreReqs, BuildRequires. Разумеется, не все из вышеперечисленных тэгов, как правило, используются, равно как встречаются и другие редко используемые тэги. В связи с тем, что BuildRequires зарезервирован для автоматически вычисляемых зависимостей, для указания особых зависимостей следует использовать BuildPreReq.

Файлы локализации.

Если в состав пакета входят файлы локализации либо другие файлы на разных языках, стоит использовать макрос %find_lang. Подробная информация есть в ``/usr/lib/rpm/find-lang -h''

Группы.

Следите за значением тэгов Group: они должны соответствовать действительности и при этом принадлежать фиксированному множеству, перечисленному в файле /usr/lib/rpm/GROUPS.

Внутрипакетные зависимости.

При работе с мультипакетными spec-файлами соблюдайте правило внутрипакетных зависимостей: Если один пакет в какой-либо мере зависит от другого подпакета, то эта зависимость должна быть указана полностью, включая не только имя, но также верcию, релиз и serial (если есть). Например, ``Requires: %name = %version-%release''. Обратите внимание на синтаксис: знак равенства, в отличие от дефиса, окружен пробелами.

Разделяемые библиотеки.

Пакеты, содержащие как разделяемые библиотеки, так и использующие их программы, должны быть разделены на подпакеты таким образом, чтобы в подпакет, содержащий разделяемые библиотеки, не входили использующие их программы. Это позволит уменьшить количество циклических зависимостей. По традиции, имена пакетов, состоящих только из разделяемых библиотек, должны начинаться с префикса ``lib`` либо содержать его внутри слова. При разделении подпакетов следует помнить о внутрипакетных зависимостях.

Статические библиотеки.

Статические библиотеки должны паковаться в отдельные подпакеты, что связано со спецификой их использования. Если имя devel-подпакета заканчивается суффиксом -devel, то имя нового devel-static-подпакета будет заканчиваться суффиксом -devel-static. При разделении подпакетов следует помнить о внутрипакетных зависимостях: В списке зависимостей devel-static-подпакета должна присутствовать зависимость от -devel = %version-%release.

Переименование пакетов.

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

Литература