RPM: синтаксис spec файла

Материал из Rosalab Wiki
Перейти к: навигация, поиск
В ROSA Desktop для пакетов используется бинарный формат RPM, однако, каждый разработчик имеет собственное представление о стиле оформления Spec-файлов, что может привести в замешательство других разработчиков и мейнтейнеров, работающих с этими пакетами.

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

Подробнее о политиках, например, о политиках сборки библиотек, политике альтернатив и т. п. см. раздел политики сборки пакетов.

Заголовок (Spec Header)

Заголовок Spec-файла содержит важную информацию, необходимую для сборки, о версии пакета, исходном коде, патчах, зависимостях.

Определение макросов

В начале Spec-файла содержатся определения макросов. Например:

%define major           0
%define libname         %mklibname aide %{major}

Все %define должны быть определены именно в этом месте с соответствующими комментариями. Для выравнивания макроопределений используется табуляция как показано выше (используйте двойную табуляцию после определения name или столбец 25 (конец третьей табуляции); это позволит использовать более длинные имена в определениях). Если имя определения длиннее и следующий символ табуляции будет находиться за 26-й колонкой, используйте одиночный пробел, например:

TODO: привести данный пример
Idea.png
Примечание
Определение макросов для имени (name), версии (version) и релиза (release) не имеет смысла, поскольку эти сущности определяются через соответствующие тэги.

Название, версия, релиз

Первый раздел должен содержать стандартное название, версию и тэг релиза:

Name:    aide  
Version: 0.13.1
Release: 1

Краткая сводка, название, исходники и патчи

Следующий раздел заголовка должен выглядеть следующим образом:

Summary:        Advanced Intrusion Detection Environment  
License:        GPLv2+
Group:          Monitoring
URL:            http://sourceforge.net/projects/aide
Source0:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz
Source1:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz.asc
Source2:        aide.conf
Source3:        aidecheck
Source4:        aideupdate
Source5:        aideinit
Source6:        aideinit.8
Patch0:         some.patch

Как видите, всё располагается в линейном порядке:

  1. Summary — краткое описание пакета (в одну строку).
  2. License — см. политика лицензирования.
  3. Group — принадлежность пакета к одной из групп ROSA.
  4. URL — домашняя страница ПО.
  5. Source0... — исходники.
  6. Patch0... — патчи.

Файлы исходников должны начинаться с Source0, не используйте Source:; если в пакете содержится один единственный исходник, используйте Source0, поскольку нет гарантии, что в пакете всегда будет использоваться один исходник. Тоже самое относится к ключевому слову Patch0; всегда начинайте с Patch0:, и никогда не используйте Patch:. Если исходный код имеет URL, по которому его можно получить, то эту информацию необходимо включить.

Табуляции здесь чуть короче, чем определения, главным образом потому, что определения могут быть длиннее, но Source, Name и др. тэгов это не касается. Вместо столбца 25, используйте столбец 17 или конец второй табуляции. Важно, чтобы все значения ключевых слов, и вообще содержимое второй колонки, было выровнено по левому краю, поскольку такое оформление наиболее удобно для чтения.

Наименование патчей

Патчам должны даваться имена в очень ясной манере, чтобы можно быть быстро понять, какая версия патча была применена и откуда он был взят. Поэтому патчи должны удовлетворять следующему соглашению о наименовании: [название_пакета]-[версия]-[описание].patch:

  • [название_пакета] — название пакета, к которому применяется данный патч, например, shadow-utils или gnupg;
  • [версия] - это версия программы, для которой подготовлен патч. Если вы переделываете патч для новой версии программы, не забудьте изменить его имя -- то есть если у вас был патч foo-1.0-rosa-fix.patch и вам пришлось его переработать для версии foo-1.2, то назовите новый патч foo-1.2-rosa-fix.patch. Поскольку патчи хранятся в Git-репозитории, то используйте команду git rename для переименования.
  • [описание] — краткое описание патча.

Зависимости сборки

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

BuildRequires:  flex
BuildRequires:  glibc-devel
BuildRequires:  glibc-static-devel
BuildRequires:  mhash-devel
BuildRequires:  zlib-devel
BuildRequires:  bison


Requires, Obsoletes, Provides, Conflicts и тому подобное

Последний набор тэгов в заголовке RPM указывает, что пакет предоставляет (тэг Provides; такие предоставляемые возможности можно потом указывать в тэгах Requires и BuildRequires других пакетов), какие пакеты он делает устаревшими (тэг Obsoletes), с какими пакетами конфликтует (тэг Conflicts) и от каких зависит (тэг Requires); обратите внимание, что в скобках после этого тэга можно дополнительно указывать ключевые слова post-, pre- и так далее, если зависимость требуется для выполнения соответствующих скриптов).

Requires:       gnupg
Requires(pre):  foo
Requires(postun): foo
Conflicts:      tripwire
Provides:       AIDE+gpg
Obsoletes:      bar

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

  1. сначала указывать Requires
  2. затем - Requires(pre), Requires(post) и подобные
  3. теперь Conflicts
  4. и, наконец, Provides и Obsoletes

Описание

Тэг %description находится в самом конце, в нём содержится описание пакета. Длина строки должна составлять 76 символов.

В итоге, RPM-spec должен выглядеть следующим образом:

Name:			aide
Version:		0.13.1
Release:		1

%define major		0
%define libname		%mklibname aide %{major}
%define somereallylongname foo

Summary:        Advanced Intrusion Detection Environment
License:        GPLv2+
Group:          Monitoring
URL:            http://sourceforge.net/projects/aide
Source0:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz
Source1:        http://prdownloads.sourceforge.net/aide/%{name}-%{version}.tar.gz.asc
Source2:        aide.conf
Source3:        aidecheck
Source4:        aideupdate
Source5:        aideinit
Source6:        aideinit.8
Patch0:         some.patch

Buildrequires:  flex
BuildRequires:  glibc-devel
BuildRequires:  glibc-static-devel
BuildRequires:  mhash-devel
BuildRequires:  zlib-devel
BuildRequires:  bison

Requires:       gnupg
Requires(pre):  foo
Requires(postun): foo
Conflicts:      tripwire
Provides:       AIDE+gpg
Obsoletes:      bar

%description
AIDE (Advanced Intrusion Detection Environment) is a free alternative to
Tripwire. It does the same things as the semi-free Tripwire and more.  It
is a file system integrity monitoring tool.

Для пакетов, которые создают несколько подпакетов, следуйте выше изложенному руководству для каждого подпакета.

%prep

Раздел %prep находится после всех определений пакета. По крайней мере 2 пустые строки должны отделять конец раздела %description от %prep. Простейший раздел %prep выглядит следующим образом:

%prep
%setup -q

Другие соглашения

Системные макросы и макросы пользователя

Системные макросами являются макросы, определённые в файлах Шаблон:Файл - например, %make, %makeinstall_std и др. Системный макрос - это нечто выполняющее что-либо или вычисляющее что-либо. Т. е. системный макрос это не простое определение, например как %{_tmppath}, которое просто переводит путь. Системные макросы записываются без фигурных скобок, например, %mkrel, а не %{mkrel}. Макросы, определённые пользователем, которые включают в себя %{_tmppath} или %{_bindir} записываются в фигурных скобках, например, %{_tmppath}, а не %_tmppath. Если все будут использовать данное соглашение о фигурных скобках, это упростит чтение spec-файла.

Если вы не уверены, использовать ли фигурные скобки, помните, что макросы, подобные %{_libdir}, отдают значение (в данном случае, Шаблон:Файл), в то время как макрос, подобный %_install_info, действительно выполняет некоторый код.

Idea.png
Примечание
  • Используйте %{_libdir}, в не %_libdir.
  • Используйте %_install_info, а не %{_install_info}.
  • Пользуйтесь приведёнными рекомендациями и все spec-файлы станет гораздо легче читать.

Стандартные макросы

При условии использования сходных названий для макросов повышается читабельность spec-файла.

  • %{upstream_name} — если апстрим-название отличается от названия пакета.
  • %{upstream_version} — если апстрим-версия отличается от версии пакета.

Переменные

Переменные, которые действительно являются переменными, например $RPM_OPT_FLAGS или $RPM_BUILD_ROOT, не должны использоваться. Вместо них должны использовать макросы, подобные %{optflags} и %{buildroot}. Переменные "$*" относятся к конструкциям оболочки, но не к RPM-определениям.

Журналы изменений

Журналы изменений хранятся в журналах Git. При выполнении коммита в Git журнал становится частью итогового spec-файла (т. к. журналы коммита создают журнал изменений RPM во время сборки). Делайте записи в журнале достаточно подробными, чтобы позднее не приходилось использовать diff ддя просмтра изменений. Пример плохой записи в журнале:

- fixed foo

Подобная запись ни о чём не говорит и, кто бы ни сделал это изменение, он не сможет сказать, что же было сделано в этом коммите. Вместо этого нужно было записать что-то в этом духе:

- переработан description.patch для новой версии foo
- добавлен foo-manpages.tar.bz2, предоставляющий то-то и то-то
- удален cvsfix32.patch (перенесе в апстрим)

Такая запись в большей степени информирует о сделанных изменениях. Заметьте, что исходники должны ссылаться на свои полные имена (как в примере: вместо S23 используется длинное имя foo-manpages.tar.bz2). Патчам нет необходимости ссылаться на полные имена, но могут ссылаться на часть описания патча. Например, первый комментарий "переработан description.patch для новой версии foo", может относиться к патчу с именем foo-1.2-rosa-description.patch. Префикс foo-1.2-rosa можно опустить, если нет других патчей со словом "description" в содержательной части имени. Если же есть два похожих патча (например, foo-1.2-rosa-description.patch и foo-1.0-cvs-description.patch), то ссылка на "description.patch" в комментарии будет неоднозначна; таких ситуаций следует избегать.

Ни в коем случае не ссылайтесь в комментариях на патчи или файлы исходного кода по их номерам в spec-файле (то есть Source2 или Patch3), поскольку патчи и файлы могут появляться и исчезать. нумерация - изменяться, и спустя некоторое время по комментариям будет невозможно понять, что собственно изменялось.

Обработка исходников

Файлы исходного кода обычно обрабатываются макросом %{SOURCExx}, но это неэффективно по нескольким простым причинам:

  • нет необходимости прыгать вверх-вниз по spec-файлу, чтобы найти, что, например, обозначает %{SOURCE12};
  • файлы исходного кода можно легко перенумеровать без необходимости внесения многочисленных изменений.

Вместо, в spec-файле предпочтительно использовать %{_sourcedir}/foo, т. к. это упрощает чтение файла. Например, сравните:

Source12:	something
...
install -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/pam.d/

с:

Source12:	something.pam
...
install -m 0644 %{_sourcedir}/something %{buildroot}%{_sysconfdir}/pam.d/

Файлы исходного кода не должны содержать макросов %{version} и %{name}, если только они не являются оригинальными файлами исходного кода из апстрима.

Файлы патчей никогда не должны содержать макросов %{version} и %{name}.

Ресурсы