ALT Packaging HOWTO

Материал из ALT Linux Wiki
Версия для печати больше не поддерживается и может содержать ошибки обработки. Обновите закладки браузера и используйте вместо этого функцию печати браузера по умолчанию.


ALT Packaging HOWTO (revision 0.3)

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

Введение

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

  • Обеспечить желаемую функциональность:

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

  • Помочь разработчику:

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

  • Сделать spec-файлы более читабельными:

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

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

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

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

Управление опциями компилятора 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 %_ptflags_optimization".

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

%_make_build: вызов make с параметром, обеспечивающим оптимальную параллельную сборку в данной среде

%_make_install: вызов make c инициализацией переменной INSTALL, что в случае корректной реализации Makefileов пакета позволяет сохранить дату последней модификации файлов, что особенно важно для документации;

%_makeinstall: %make_install <инициализация других переменных, используемых многими Makefileами> install.

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

%_install_info: регистрация новых/обновленных info-страниц.

%_uninstall_info: отмена регистрации удаленных info-страниц.

Устарело с появлением filetriggers

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

%_update_menus: регистрация новых/обновленных меню.

%_clean_menus: отмена регистрации удаленных меню.

Устарело с появлением filetriggers

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

%__libtoolize: путь к скрипту libtoolize

%_configure_script: путь к скрипту configure

%_configure_target: целевая платформа для configure

%_configure_gettext: -without-included-gettext.

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

%post_service: регистрация нового сервиса при установке, перезапуск при обновлении[1][2]

%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), таким образом, добавлены новые возможные значения, являющиеся именами методов поиска зависимостей:

  • lib: включение поиска зависимостей от/для разделяемых библиотек
  • shell: включение поиска зависимостей в shell-скриптах
  • perl: включение поиска зависимостей в perl-скриптах
  • nolib: выключение поиска зависимостей от/для разделяемых библиотек
  • noshell: выключение поиска зависимостей в shell-скриптах
  • noperl: выключение поиска зависимостей в perl-скриптах
  • default: то же, что и yes;
  • none,off: то же, что и no;
  • all: включение всех возможных методов поиска зависимостей.

Значением тэга может являться как один метод, так и перечисление методов. По умолчанию, для каждого под пакета собираемого пакета AutoReq = AutoProv = yes, что на практике означает использование макросов %findreq_default_method и %findprov_default_method для определения методов поиска зависимостей.

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

Вся документация пакета, распознаваемая как man или info-документация, по окончании работы секции %install, сжимается согласно выбранному методу. Поддерживаются следующие методы сжатия:

  • bzip2: сжатие с помощью bzip2 -9
  • gzip: сжатие с помощью gzip -9n
  • auto: сжатие с помощью gzip -9n либо bzip2 -9 в зависимости от того, какой вариант окажется эффективнее
  • none: производится декомпрессия файлов вместо сжатия
  • skip: процедура сжатия пропускается полностью.

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

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

Зачастую возможно уменьшить размер получаемых в результате сборки пакета ELF-файлов без потери качества за счет удаления из них отладочной информации. Поэтому по окончании работы секции %install все ELF-файлы выбранных типов обрабатываются программой strip. Выбор типов файлов определяется значением макроса %_strip_method, которое есть набор из следующих возможных значений:

  • executable: ELF executable;
  • relocatable: ELF relocatable;
  • shared: ELF shared object;
  • static: ar archive.

Кроме того, есть возможность вызывать 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-файл, снижая тем самым его читабельность. К устаревшим конструкциям, в частности, относятся:

  • тэг BuildRoot: (BuildRoot выбирается автоматически);
  • cтроки вида rm -rf $RPM_BUILD_ROOT (BuildRoot очищается автоматически);
  • %_defattr со стандартными аргументами в начале файлов и секций %files (такое поведение действует по умолчанию);
  • секция %clean, пустая либо без разумного содержания.

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

Нет смысла засорять текст spec-файла ненужными фигурными скобками. Избавится от них легко:

perl -pi -e 's/%\{([A-Za-z_0-9]+)\}([^A-Za-z_0-9?*]|$)/%$1$2/g' spec-файл

Или с помощью утилиты cleanup_spec из пакета rpm-utils.

Выравнивание

Используйте табуляции для выравнивания. Избегайте пробельных символов в конце строк.

Значения тэгов

Значение тэга от его имени следует разделять одним пробелом. Элементы списка значений следует разделять запятой с последующим пробелом. Значение тэга Summary следует начинать с прописной буквы и не следует завершать точкой. Значения тэга Summary и секции %description могут содержать названия команд только в не изменённом виде.

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

Рекомендуемый порядок заголовочных тэгов:

  • 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.

ChangeLog

Для формирования первой строки changelog-записи удобно использовать утилиту add_changelog из пакета rpm-utils.

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

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

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

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

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

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

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

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

тэг Provides: старое_имя = %version
тэг Obsoletes: старое_имя

Литература

Примечания

  1. НИКОГДА не используйте %post_service для перезапуска сторонних сервисов. (raorn@)
    /sbin/service %apache2_dname condreload|condrestart ||:
  2. %post_service предназначен для
    • регистрации сервиса при первой установке пакета;
    • перезапуске сервиса при обновлении пакета.
    Запускать сервис автоматически сразу при первой установке пакета не положено. (ldv@)