Spec
Работа с upstream-исходниками
Если имя пакета, имя архива с upstream-исходным кодом и имя директории, содержащейся в архиве, не совпадают, не следует перепаковывать архив, чтобы угодить действиям по умолчанию в RPM. Вместо этого стоит указать все названия в spec-файле явно:
%define origname imms Name: xmms-%origname #... Url: http://www.luminal.org/phpwiki/index.php/IMMS Source: http://www.luminal.org/files/%origname/%origname-%version.tar.bz2 # if we had a published package with original name Obsoletes: %origname %prep %setup -n %origname-%version
Разумеется, это всё относится только к пакетам, собираемым не с помощью Gear.
Включение/выключение подпакетов
Иногда определённые подпакеты нужно собирать только в особых ситуациях (например, статические библиотеки или вариант для bootstrap новой архитектуры). Это делается следующим образом:
# По умолчанию будет выключено. # Одноразово в командной строке rpm/rpmbuild включается с помощью --enable=static %def_disable static [...] # Если заодно необходимо передавать опцию --(disable|enable)-static в configure, # то можно написать следующую конструкцию. # (В разных случаях она будет раскрываться в разные значения.) %configure %{subst_enable static} [...] %if_enabled static %files devel-static [...] %endif
Проверка плагинов
У нас в rpm-build >= 4.0.4-alt100.91 есть механизм проверки плагинов, который используется в разных пакетах. Вот, например, ldv когда-то применил его для irssi, выглядит это так (%_bindir/irssi можно прелоадить, потому что он PIE):
export RPM_LD_PRELOAD_irssi=%buildroot%_bindir/irssi export RPM_FILES_TO_LD_PRELOAD_irssi='%irssi_modules_dir/lib*.so %perl_vendor_autolib/Irssi/*.so' export RPM_LD_PRELOAD_libperl_core='%buildroot%irssi_modules_dir/libperl_core.so' export RPM_FILES_TO_LD_PRELOAD_libperl_core='%irssi_modules_dir/libfe_perl.so %perl_vendor_autolib/Irssi/*.so' %set_verify_elf_method strict
Version
Версия upstream-кода. В случае упаковки промежуточной версии (1.0-rc1, 1.0-20080105) версия среза упаковывается в поле Release: 1.0rc лексикографически круче 1.0, вследствие чего для нормального обновления 1.0rc до 1.0 придётся
- добавлять Serial: 1,
- оформлять как 1.0rel или
- ждать поднятия версии апстримом.
Release
Для пакетов Sisyphus поле Release должно иметь вид в простых случаях — altN, а в сложных (см. ниже) — altN[суффикс].
Релиз пакета используется для указания номера сборки пакета при данной версии upstream-кода, N начинается с 1 для каждой новой upstream-версии и увеличивается на 1 для каждой новой сборки:
- 1.0-alt1
- 1.0-alt2
- 1.0-alt3
- 1.1-alt1
- 1.2-alt1
- 1.2-alt2
- …
Два особых случая — это упаковка промежуточных релизов upstream-кода и упаковка бэкпортов.
Промежуточные upstream-релизы
При сборке промежуточных релизов upstream-кода (срезов по дате, по системе контроля версий), следует указывать информацию о срезе в поле Release:
- 1.0-alt1.r6543
- 1.0-alt1.20080101
- 1.0-alt1.rc1
- 1.0-alt1.rc2
- 1.0-alt1.gitda39a3ee[1]
Если система контроля версий не предоставляет линейной нумерации коммитов, то с каждым новым срезом нужно увеличивать номер релиза:
- 1.0-alt1.hg.da39a3ee
- 1.0-alt2.hg.0d3255bf
- 1.0-alt3.hg.fef95601
При первой сборке финального upstream-релиза следует поднять номер релиза пакета:
- 1.0-alt1.gitda39a3ee
- 1.0-alt2.gitd06f1866
- 1.0-alt3
Использовать релиз alt0 запрещено — пакет с таким релизом, попав в репозиторий, порождает проблемы с бэкпортами (в отличие от, например, alt0.1, который при бэкпорте для p7 становится alt0.0.M70P.1).
Бэкпорты
Epoch
Поле Epoch используется тогда, когда по какой-то причине (странное поведение upstream-а, ошибочная заливка пакета или похожие форс-мажорные обстоятельства) требуется уменьшить версию или релиз пакета по сравнению с имеющимся в репозитории. При этом значение поля Epoch увеличивается на единицу по сравнению с предыдущим (отсутствие поля Epoch эквивалентно значению 0), версия и релиз устанавливаются в нужное значение.
Будьте осторожны — в имя RPM-файлов Epoch не входит, и поэтому необходимо избегать RPM-ов с одинаковыми Version и Release и разными Epoch.
Устаревшим синонимом поля Epoch является Serial.
Summary
Cодержит краткое описание пакета. Оно выводится, например, при поиске пакета через apt-cache search. Значение тэга Summary должно начинаться с заглавной буквы. В конце Summary не должно быть точки.
License
- Лицензия должна быть указана в точности так, как сформулировано в upstream-пакете (в частности, не разрешается отбрасывать или добавлять «or any later version», а также менять указанные версии или смешивать GPL и LGPL).
- Несвободные лицензии должны быть указаны как «distributable»
При указании лицензии рекомендуется пользоваться макросами из пакета rpm-build-licenses, добавив его в список BuildRequires.
Сам текст лицензии упаковывать в пакет нужно только в том случае, если соответствующий текст отсутствует в /usr/share/license (пакет common-licenses). Если же таковой файл там присутствует, то достаточно указать название лицензии в тэге пакета.
Лицензию с добавками к стандартному тексту (например, GPLv2 с дополнительной секцией в ядре Linux) упаковывать обязательно.
Group
Указанная группа должна находиться в списке групп, известном RPM. Этот список располагается в файле /usr/lib/rpm/GROUPS, находящемся в пакете rpm.
Url
В тэге Url настоятельно рекомендуется указывать действующий URL домашней страницы проекта, либо если таковой нет — любого другого места, где можно получить архив с исходным кодом.
Рекомендуется периодически проверять адреса в своих пакетах на предмет того, что они действующие, и проект не переехал (даже если по старому адресу стоит перенаправление на новый, имеет смысл исправить содержимое тэга).
Для тега Url можно использовать утилиту rpmurl из пакета etersoft-build-utils:
rpmurl -c пакет.spec
Source
Если сборка производится без использования gear, то в Source настоятельно рекомендуется указывать действующий URL архива исходного кода относительно тэга Url:
Source: %url/some/thing/%name-%version.tar.bz2
Формат Source для известных хостингов:
# иногда проект называется не так, как пакет, будьте внимательны Source: http://dl.sourceforge.net/%name/%name-%version.tar.bz2 Source: http://download.berlios.de/%name/%name-%version.tar.bz2
Если тарбол формируется из gear-репозитория, то в Source указывается имя файла согласно прописанному в .gear/rules, например
Source: %name-%version.tar
Если исходники берутся из системы контроля версий, то рекомендуется указывать в комментарии рядом команду для получения данного снапшота:
# svn co svn://svnanon.samba.org/samba/trunk samba-trunk -r 1 Source: %name.tar.bz2
Patch
Рекомендуемое именование патчей:
- NAME-VERSION-ORIGIN-WHAT.patch, где
- NAME и VERSION — имя и версия пакета, для которого сделан патч,
- ORIGIN — аббревиатура источников патча (обычно дистрибутивов),
- WHAT — краткое описание патча.
Если патч образован из нескольких частей, полученных из разных источников, ORIGIN должен включать аббревиатуры всех источников. Аббревиатура ALT Linux / Sisyphus — alt. Для патчей, полученных на основе системы контроля версий, ORIGIN должен включать в себя дату или номер ревизии.
В описании патча рекомендуется пользоваться следующими сокращениями:
- makefile — патчи, затрагивающие исключительно Makefile*,
- bound — проверки на границы (буфера, целых чисел и т. д.),
- config — патчи, затрагивающие исключительно конфигурационные файлы,
- configure — патчи, затрагивающие исключительно configure*,
- doc — патчи, затрагивающие исключительно документацию,
- fixes — кумулятивные патчи/исправления по надёжности и/или безопасности,
- format — патчи на использование форматирования строк (типа printf),
- install — патчи на выполнение make install непривилегированным пользователем,
- linux — патчи для портирования По на Linux,
- man — патчи, затрагивающие исключительно man-страницы,
- texinfo — патчи, затрагивающие исключительно документацию в формате texinfo,
- tmp — патчи, предназначенные для решения различных вопросов, связанных с временными файлами,
- vitmp — патчи для поддержки vitmp(1)
- warnings — патчи, исправляющие предупреждения, выданные компилятором
Requires, PreReq
При наличии логических зависимостей между пакетами внутри одного spec-файла, пакетная зависимость между ними должна включать полную версию пакета, например так:
Requires: %name = %epoch:%version-%release
Requires
Используется для обозначения зависимостей между пакетами, которые необходимо удовлетворить для нормальной работы программ, не входящих в пакет с создаваемым/корректируемым спеком.
Requires: java >= 1.6
BuildRequires, BuildPreReq, BuildRequires(pre)
Тэг BuildRequires используется для хранения результатов работы buildreq. По этой причине дополнительные сборочные зависимости, не находящиеся buildreq, рекомендуется хранить в тэге BuildPreReq.
Если в пакете имеются опциональные части (включаемые с помощью конструкций %if или подобных), то сборочные зависимости должны содержать пакеты, достаточные для сборки всех опциональных частей. Этого можно добиться двумя способами:
- запуском buildreq со всеми включенными опциями,
- указанием дополнительных зависимостей в BuildPreReq и периодическим их обновлением.
При необходимости наличия в окружении, где выполняется раскрытие макросов для создания src.rpm, дополнительных пакетов rpm-macros-* либо rpm-build-* их следует указать тэгом BuildRequires(pre). Злоупотреблять им не следует (затрудняет бутстрапы); критерий необходимости именно этой формы -- ошибка (не предупреждение!) при попытке выполнить в недостаточном окружении команду вида
rpm -bs --nodeps этот.spec
Обратите внимание, что для gear-rpm ограничения иные и этот критерий неприменим.
BuildArch
Используется для указания архитектуры (под)пакета. Возможные значения:
- x86_64
- %ix86[2] или индивидуально i386, i586, i686...
- noarch
В случае указания среди тегов основного пакета определяет архитектуру всех подпакетов; для индивидуальных подпакетов — как правило, с данными, документацией либо скриптами — допускается указание только noarch, и то при условии использования rpm-4.0.4-alt94 или более новой сборки.
BuildRoot
Тэг BuildRoot бесполезен для RPM из Sisyphus: обработку BuildRoot RPM производит самостоятельно.
BuildHost
Новый опциональный тэг в Sisyphus RPM. Позволяет переопределить имя сборочного хоста. По умолчанию используется, как и в остальных версиях RPM, результат вызова uname(2).
Prefix
Тэг Prefix в Sisyphus RPM не нужен, он самостоятельно устанавливается в /usr.
Conflicts
Применяется для указания наличия конфликта (обязательно в случае файлового/RPC и желательно в случае существенного смыслового) между данным пакетом и указываемым. Не надо ставить конфликты на то, чего ещё нет и о чём, соответственно, ничего не известно. Достаточно проставить односторонне.
Provides
Используется для указания того факта, что данный пакет предоставляет функциональность иного (переименованного устаревшего названия, широко известного по другим дистрибутивам либо же виртуального). Следует применять только в случае реальной необходимости и, как правило, в форме
Provides: something = %version-%release
При переименовании пакета обязательно сочетается с Obsoletes:.
Obsoletes
Перечисляет пакеты/версии, объявленные устаревшими. Обычно применяется при переименовании пакета в сочетании с Provides: и с указанием версии, меньшей или равной последней известной версии пакета под старым названием:
Name: someproject Version: 1.0 Release: alt1 # ... Provides: oldproject = %version-%release Obsoletes: oldproject <= 0.9.1
%description
Здесь указывается описание пакета. Данное описание учитывается при поиске пакета через apt-cache search и полностью выводится во время просмотра информации о пакете при помощи apt-cache show имя_пакета.
Описание пакета должно содержать информацию, интересную его пользователю, а не сборщику:
- Описание программы или инструмента должно содержать их функционал, а не особенности реализации (язык, используемые библиотеки и т. д.)
- Описание библиотеки должно содержать язык программирования, для которого предназначена библиотека, и решаемую задачу
- …
Длина каждой строки не должна превышать 72 символа ради читабельности в различных случаях.
%prep
%setup
Макрос %setup распаковывает исходный код перед компиляцией.
Конструкция %setup в Sisyphus RPM использует флаг -q (quiet) по умолчанию. Для включения отладочного вывода используйте флаг -v.
Для тарболов с отличающимся от рекомендуемого GNU именованием содержимого (когда архив на верхнем уровне содержит лишь соответствующий каталог имя-версия), можно применять следующий вариант:
%setup -c %setup -DTn %name-%version/%name
%build
%configure
Макрос используется для упрощения выполнения ./configure с соответствующими параметрами данной платформы. Почти всегда вполне достаточно выполнить %configure без параметров. От имени пользователя данный макрос работать не будет.
%build %configure %make_build
При сборке пакетов проверяйте, нет ли в спеке --enable-strip. Обычно от него нет никакого эффекта, кроме убивания debuginfo на корню[3].
Если скрипта configure в архиве исходных текстов нет (обычное явление для исходников из git или иных SCM), но есть configure.ac -- следует добавить перед вызовом %configure макрос %autoreconf. В иных случаях стоит повнимательней ознакомиться с инструкциями по сборке, раз это не было сделано до сих пор.
%make_build
По умолчанию поддерживает при сборке использование нескольких процессоров/ядер.
%install
%makeinstall_std
Рекомендуемый вариант, эквивалентный
%make_install DESTDIR=%buildroot install
%make_install
Этот макрос используется для упрощения установки софта, Makefile которого умеет использовать параметр DESTDIR (в частности, весь софт, использующий automake, это умеет):
%make_install DESTDIR=%buildroot install
или
%make_install DESTDIR=%buildroot %_make_install_target
%makeinstall
Редко используемый макрос, предназначенный для софта, DESTDIR не умеющего, и prefix внутри себя не запоминающего:
%makeinstall
В случае, когда Makefile нужно передать какой-то дополнительный параметр (например, особо странный somefancydir=%buildroot/fancy/dir), это выглядит так:
%makeinstall somefancydir=%buildroot/fancy/dir
Иногда требуется запаковать вспомогательные бинарные программы, не предназначеные для выполнения пользователем (обычно их запускают другие программы). Согласно GNU Coding Standards, их следует класть в директорию, определяемую переменной libexecdir. В ALT Linux ей соответствует макрос %_libexecdir, указывающий на /usr/lib. Рекомендуется создавать в этой директории под-папки по названию пакета:
%makeinstall libexecdir=%buildroot%_libexecdir/fancy
Задать путь можно также на этапе конфигурирования:
%build %configure --libexecdir=%_libexecdir/fancy
Удаление buildroot
В Sisyphus RPM buildroot удаляется самим RPM, и поэтому удалять его вручную не требуется.
%check
Начиная с rpm-4.0.4-alt98.18, для упрощения проведения автоматических тестов собранного кода поддерживается секция %check; типичные примеры её содержания:
- если важно получить ответ на вопрос "не испортилось ли" поскорее, то
%make_build check
- если SMP-сборка не поддерживается, то
make check
- если важно узнать, какие именно тесты не прошли, то следует использовать ключ -k.
Обратите внимание: %check выполняется после %install, т.е. by design не влияет на результат работы %install.
Ненулевой код возврата по умолчанию приводит к останову сборки (в т.ч. и на git.alt); это возможно изменить при помощи ключей --disable check/--without check/--disable test/--without test или макроса
%def_disable check
Кроме того, отключение %check происходит при выполнении под управлением buildreq.
При необходимости вытащить для изучения и/или апстрима, например, testsuite.log применяется[4]:
make check || { find -type f -name testsuite.log -print0 | xargs -r0 cat exit 1 }
BuildRequires только для %check
Для возможности сборки с облегчёнными сборочными зависимостями (например, при bootstrap-е на новой платформе) желательно оформить BuildRequires только для %check как условные. Как следует из описания механизма выше, годится, например, такое выражение:
%{?!_without_test:%{?!_disable_test:%{?!_without_check:%{?!_disable_check:BuildRequires: fakechroot}}}}
но на практике[1][2] часто встречается более короткое выражение:
%{?!_without_check:%{?!_disable_check:BuildRequires: fakechroot}}
(На свой страх можете ещё сократить это условие.)
%clean
Sisyphus RPM автоматически очищает BuildRoot пакета (с помощью макроса %clean_buildroot). Таким образом, ручная очистка BuildRoot является ненужной (а точнее — вредной, поскольку повышает вероятность ошибки).
Если секция %clean пуста, то рекомендуется вообще не включать её в spec-файл.
%files
В отличие от других веток RPM, Sisyphus RPM автоматически подставляет в начало каждой секции %files и в начало каждого файла, включаемого с помощью %files -f, директиву %defattr со значением макроса %_defattr.
Таким образом, ручное указание %defattr является излишним.
%changelog
Ссылки
Примечания
- ↑ для ссылки на коммит удобен git describe
- ↑ См. rpm --eval %ix86
- ↑ http://lists.altlinux.org/pipermail/devel/2011-March/189039.html
- ↑ vsu@ в devel@