Переход ROSA с RPM 5 на RPM 4 — различия между версиями

Материал из Rosalab Wiki
Перейти к: навигация, поиск
(Копия ревизии 17801 статьи Основы RPM)
 
 
(не показано 127 промежуточных версий 2 участников)
Строка 1: Строка 1:
{{Введение|Этот документ нацелен на то, чтобы помочь людям, которые хотят выпускать пакеты для дистрибутива ROSA Desktop. В частности, он подчёркивает, чем пакеты ROSA отличаются от пакетов, написанных для других дистрибутивов, основанных на RPM. Этот документ может быть полезен разработчикам ROSA, а также сторонним разработчикам.}}
+
{{Введение|Начиная с rosa2021.1, дистрибутив ROSA Fresh переходит с пакетных менеджеров RPM 5 и urpmi на RPM 4 и DNF. Эта статья описывает основные отличия для пользователей и сборщиков пакетов.}}
  
ROSA Desktop — дистрибутив операционной системы GNU/Linux — выпускается и издаётся компанией РОСА, силами различных добровольцев, тестеров, переводчиков.
+
== Откуда куда переход ==
  
= Предисловие =
+
Более восьми лет в дистрибутивах ROSA Desktop использовался пакетный менеджер [[RPM5]] - форк RPM4, созданный Джеффом Джонсоном. Долгое время RPM5 развивался гораздо активнее своего родителя, что и обсуловило его выбор для РОСЫ. Однако постепенно активность по разработке RPM5 угасла, а RPM4 наоборот - возродился и постепенно не только вобрал большинство интересных свойств RPM5, но и получил множество новых. В настоящее время сайт http://rpm5.org уже недоступен, а ROSA Fresh переходит обратно на RPM 4.
  
Предполагается, что читатель имеет опыт использования Linux. Ему должны быть известны основные команды, структура каталогов, и ему уже приходилось использовать {{программа|rpm}} хотя бы для установки пакетов.
+
Было:
 +
* низкоуровневая система управления пакетами RPM 5.4.10 (с более чем сотней патчей, специфичных для РОСЫ)
 +
* высокоуровневый пакетный менеджер urpmi
 +
* mock-urpm
  
Этот документ построен таким образом, чтобы провести читателя шаг за шагом к получению rpm-пакета, который смог бы хорошо интегрироваться в ROSA Desktop.  
+
Стало:
 +
* низкоуровневая система управления пакетами RPM <s>4.15.1</s> 4.17.0
 +
* высокоуровневый пакетный менеджер {{Prog|DNF}}
 +
* исчез RPM-тег DistEpoch (не путать с Epoch), но появился DistTag
 +
* вместо mock-urpm используется оригинальный mock
 +
* наиболее часто используемые в командах {{Cmd|urpmi}} и {{Cmd|urpme}} функции преобразовываются в команды {{Cmd|dnf}} ([https://github.com/rpm-software-management/dnf-URPM dnf-URPM])
 +
* будет работающий {{Prog|PackageKit}}, на основе которого планируется графический "Магазин приложений"
  
В первом приближении, '''RPM''' обозначает три понятия:
+
Затронутые платформы: rosa2021.1 (в будущем релизы ROSA >= 12) и новее, в старых (rosa2012.1, rosa2012lts, rosa2014.1, rosa2016.1, rosa2019.0) пакетная система не меняется.
  
* программу, предназначенную для установки или создания пакетов;
+
Про этот переход было рассказано на конференции OSDAY-2020, ознакомиться с выступлением и слайдами презентации можно здесь: https://nixtux.ru/1052
* формат, использующийся в пакетах (двоичных или исходного кода), созданных программой {{программа|rpm}};
+
* файл, который называется «пакетом», содержащий бинарный или исходный код, и информационный заголовок. Заголовок содержит инструкции по установке и удалению программы.
+
  
Программа {{программа|rpm}}, с пользовательской точки зрения — мощный менеджер пакетов. Она играет роль ''посредника'' для любых действий, выполняемых с пакетами rpm. Кроме того, она может:
+
== Причины для перехода ==
  
* установить или обновить пакет, учитывая зависимости;
+
* ни RPM 5, ни urpmi более не разрабатываются, ROSA и PLD остались единственными их использующими дистрибутивами, причем PLD уже более года прорабатывает переход на rpm4; в мире Linux нецелесообразно пытаться малыми силами тащить такую важную инфраструктурную вещь, как пакетная система
* во время установки пакета подготовить действия, чтобы сделать установленную программу готовой к использованию;
+
* в RPM 5 в свое время были важные функции, которых не было в RPM 4, но теперь ситуация изменилась в обратную сторону
* восстановить случайно удалённые файлы, принадлежащие пакету;
+
* апстрим RPM 4 в последнее время очень живой, RPM 4 активно развивается
* показать информацию о том, что данный пакет уже установлен;
+
* неудовлетворительное качество кода RPM 5 в РОСЕ, в котором так и осталось более сотни "костылей" со времен спешного перехода Mandriva на RPM 5 и много недоделанного функционала. Поддержка усложняется тем, что внутри кода RPM 5 содержатся копии многих сторонних проектов и отвечающий за что-то одно код размазан по огромному количеству файлов (например, см. коммит [https://abf.io/soft/rpm5/commit/5bf4d7c6391be2408e59680999d8a83fb279d64a 5bf4d7]: банально идентификаторы алгоритмов хеширования пришлось добавить в большое количество файлов)
* найти пакет, к которому относится определённый файл;
+
* urpmi, конечно, немного жалко, но желающих в одиночку тянуть urpmi и perl-URPM не нашлось, а какого-либо критически важного функционала, отсутствующего в DNF, в urpmi нет
* проверить текущую установку на выполнение требования зависимостей уже установленных пакетов;
+
* нет качественных биндингов urpmi<->PackageKit, а их разработка и поддержка займет большое количество времени, которое можно потратить на другие вещи, и не очень целесообразна, поскольку есть много нюансов; если делать их только самим, то качество получится низким
* др.
+
  
С точки зрения программиста, программа {{программа|rpm}} — упаковщик, скрывающий в одном единственном rpm-файле всю информацию, необходимую для установки программы на данную платформу.
+
== Общий план перехода ==
  
Важно различать с самого начала пакеты с исходным кодом {{File|.src.rpm}}, и бинарные пакеты (пакеты, содержащие двоичный код) {{File|.<archtype>.rpm}}.
+
(возможны изменения, то, что еще не сделано, является приблизительным видением дальнейшей работы)
  
Первые содержат полное дерево исходного кода, т. е. кода написанного программистом, плюс весь материал, добавленный упаковщиком, необходимый для настройки, компиляции и установки программы. Как правило, этот материал состоит из спек-файла и патчей (если они есть).
+
* (СДЕЛАНО) [https://pagure.io/omv-urpmi-to-dnf-migration собрать] стек rpm4 с временными хаками, чтобы можно было использовать ранее собранные rpm5 пакеты *.rpm, например, игнорируя отсутствующую в стеке rpm4 %DISTEPOCH
 
+
* (СДЕЛАНО) обеспечить совместимость нового rpm4 с максимально возможным количеством старых макросов
Вторые содержат откомпилированный бинарный код и все файлы (документация, файлы настроек, пиктограммы, ...), которые должны устанавливаться на целевой системе. Он также содержит процедуру, используемую для помещения файлов в соответствующие каталоги файловой системы, и действия, которые необходимо выполнить, чтобы получить нормально функционирующую программу.
+
* (СДЕЛАНО) автоматизированно внести массовые изменения в спеки (*.spec) так, чтобы они стали совместимы с RPM 4: меняются как места, которые строго необходимо заменить, так и те, где старый и продолжающий работать макрос меняется на его новый вариант
 
+
* (СДЕЛАНО) обеспечить совместимость старого rpm5 с измененными спеками, чтобы можно было из одного спека собирать пакеты и для rpm5 в платформах rosa2016.1 и rosa2019.0 и для rpm4 в платформе rosa2019.1
= Установка программного обеспечения =
+
* (СДЕЛАНО) научить abf-console-client работать с RPM 4 (теперь апстрим общий с OpenMandriva — https://github.com/OpenMandrivaSoftware/abf-console-client, а старый клиент из ROSA на python2 — https://abf.io/soft/abf-console-client — остается только для RPM5)
 
+
* (В ПРОЦЕССЕ) провести массовую пересборку пакетов main и contrib, выявив и исправив типовые проблемы (например, уже [https://abf.io/import/rpm/commit/f0381cf1bc4d3d4be0a46172340466fb2f98d6ef запатчен] find-lang.sh из rpm4)
== Основы ==
+
* (СДЕЛАНО) ранее применявшимся в OpenMandriva скриптом автоматического обновления пакетов, где это возможно, обновить пакеты
 
+
* (СДЕЛАНО)привести [[Файловые триггеры RPM|файловые триггеры RPM 5]] и %trigger* к [https://rpm.org/user_doc/file_triggers.html файловым триггерам RPM 4] (возможно, замапить новые %trigger* в старые для переиспользования спеков rpm4 в rpm5...). [https://abf.io/import/grub2/commit/e239fd6d82eac79d2492b70f209e5541250348f5 Пример] переделывание триггеров.
Хотя изначально программа {{программа|rpm}} была разработана для дистрибутива [http://www.redhat.com Red Hat Linux], она также работает и в других дистрибутивах, основанных на rpm: [http://www.openmandriva.org OpenMandriva], [http://www.suse.com/index_us.html Suse], [http://www.getfedora.org Fedora] и т. д.; на всех этих системах программа {{программа|rpm}} уже установлена.
+
* (СДЕЛАНО) обновить и починить gdb (gdb-add-index теперь используется в rpm, а gdb сейчас сломан из-за несовместимости с Python 3.8)
 
+
* ([https://abf.io/import/qml-rpm-generators СДЕЛАНО], но не заапстримлено) портировать [https://abf.io/soft/rpm5/commit/3e3987c7ba54d8b043986ceacc90679f051f1ebf генератор зависимостей QML] и желательно заапстримить его
Бинарный rpm-пакет, который вы будете собирать для ROSA, может не работать в других дистрибутивах.
+
* ([https://abf.io/import/devel-rpm-generators СДЕЛАНО]) сделать [https://rpm.org/user_doc/dependency_generators.html генератор] devel() или использовать от Mageia в составе rpm-openmandriva-setup; сделан свой
 
+
* (СДЕЛАНО) починить не собирающиеся пакеты, возможно, снова обновив glibc и gcc
== Сборка пакетов для ROSA Desktop ==
+
* либо отвязать [https://abf.io/soft/drakxtools drakxtools] от perl-URPM (или перейти на manatools, как минимум настройку часов оттуда точно нужно взять, т.к. она умеет не только в ntpd, а еще и в chrony и systemd-timesyncd, а это [https://abf.io/import/ipa-client47/blob/rosa2019.1/0001-Restore-ntpd-support.patch важно]), либо придется оставить urpmi в качестве существующего параллельно с DNF пакетного менеджера, как в Mageia
 
+
* если будет решено оставить urpmi и perl-URPM, то, во-первых, взять их версии из Mageia (они умеют работать c rpm4), во-вторых, перенести /usr/{sbin,bin}/{urpmi,urpme} куда-нибудь в /usr/lib/, а в (s)bin отставить [https://github.com/rpm-software-management/dnf-URPM dnf-URPM]
Сборка пакетов для Cooker (т. е. разрабатываемой версии ROSA Desktop) всегда сопровождается применением патчей и прочих улучшений со стороны {{программа|rpm}}. Перед началом сборки убедитесь, что в системе установлены все перечисленные ниже пакеты:
+
* (СДЕЛАНО) после обновления perl-URPM до версии из Mageia или его убирания обновить perl
 
+
* если получится избавиться от urpmi, наверняка стоит избавиться от префикса lib64 в названии пакетов, который существует из-за неумения urpmi отличать пакеты с одинаковым названием, но одинаковой архитектурой (но вопрос требует тщательного обдумывания, в т.ч. — не пострадает ли wine)
<pre>
+
* (СДЕЛАНО) переработать пакет [https://abf.io/import/rosa-repos rosa-repos]: вынести main, contrib, non-free и т.д. в отдельные подпакеты
$ sudo urpmi rpm rpm-build spec-helper libtool rpmlint
+
* (СДЕЛАНО) собрать и обеспечить работу GUI для управления пакетами dnfdranoga
</pre>
+
* сделать генерацию метаданных appstream из всего репозитория
 
+
* во все пакеты автоматически добавлять метаданные /usr/share/metainfo/*.xml, чтобы в графических "магазинах приложений" были все пакеты, а не только лишь те, в которых есть /usr/share/metainfo/*.xml; возможно, скрыть системные пакеты, имена которых начинаются на lib; для пакетов с бинарными модулями ядра сделать так, чтобы только -latest мета-пакеты были в метаданных и при этом были с красивым понятным описанием
* {{Pkg|rpm}} — сам rpm;
+
* обновить весь стек GNOME и затем обеспечить работу gnome-software
* {{Pkg|rpm-build}} — содержит сценарии, используемые при сборке пакетов;
+
* поскольку в drmdrake был GUI для управления репозиториями, а в dnfdranoga его нет, в пакеты rosa-repos-* добавить метаданные с описанием назначения этих репозиториев и с его переводом на русский язык; в магазинах приложений сделать отдельную категорию пакетов "Репозитории ROSA"; это позволит включать и отключать репозитории одной кнопкой "Установить"/"Удалить" пакет, также улучшит централизацию поставки конфигураций репозиториев
* [[Development/Howto/Spec-Helper|{{Pkg|spec-helper}}]] — инструмент для минимализации спек-файлов с помощью некоторой автоматизации: разбор бинарных файлов, сжатие страниц руководств (man-страниц);
+
* собрать, обновить и обеспечить работу packagekit
* {{Pkg|libtool}} — используется некоторыми конфигурационными сценариями для сборки совместно используемых библиотек;
+
* обеспечить работу оффлайн-обновлений через packagekit+systemd
* {{Pkg|rpmlint}} — используется для проверки корректности сгенерированного файла {{File|src.rpm}}.
+
* портировать хеши файлов по ГОСТ Р 34.11-2012 из rpm5 в rpm4 и желательно заапстримить (rpm4 уже переключен на libgcrypt по умолчанию)
 
+
* начать использовать security.ima и интегрировать подписывание в сборочницу, в т.ч. проработать вопрос с ГОСТ
= Предварительные задачи =
+
* придумать, как существующие системы обновить до rosa2021.1 с rpm4 и задокументировать (будут проблемы с конвертированием БД rpm)
 
+
* осуществить полный переезд в /usr
== Создание требуемых папок ==
+
* (СДЕЛАНО) проработать нюансы, возникшие после смены %_libexecdir = %_libdir на %_libexecdir = /usr/libexec
 
+
* (СДЕЛАНО) сделать что-то с "бекендом" для urpmi в пакете [https://abf.io/import/system-config-printer system-config-printer], желательно выкинуть и использовать апстримную интеграцию с PackageKit; а сам system-config-printer отвязать от consolehelper и перейти на апстримную интеграцию с policykit, чтобы работала печать тестовых заданий с авторизацией по тикету Kerberos текущего пользователя
Перед тем, как приступить к сборке, нужно позаботиться об организации «рабочего места»: программе {{программа|rpm}} необходимо определённое дерево каталогов в вашем «домашнем» каталоге. Это дерево можно создать с помощью следующей команды: {{Cmd|mkdir -p ~/rpm/{BUILD,RPMS/$ARCH,RPMS/noarch,SOURCES,SRPMS,SPECS,tmp} }}.
+
 
+
Замените '''$ARCH''' на название архитектуры, для который планируется выполнять сборку. Обычно это ''i586'' или ''x86_64'', но может быть также ''sparc'', ''alpha'' или ''ppc''.
+
 
+
{{примечание|Сборка ''rpm''-пакетов с правами суперпользователя может быть опасной, потому что бинарные файлы устанавливаются в систему перед пакетированием, таким образом, всегда нужно собирать пакеты с правами нормального пользователя, если вы не хотите случайно засорить систему.}}
+
 
+
<b>Дерево каталогов должно иметь следующую структуру:</b>
+
 
+
* {{File|~/rpm/BUILD}}: каталог для собранных исходников.
+
* {{File|~/rpm/RPMS}}: содержит каталоги, по одному каталогу на каждую архитектуру, куда кладутся бинарные пакеты после сборки.
+
* {{File|~/rpm/RPMS/i586}}: каталог для хранения rpm-пакетов для процессоров ''i586''.
+
* {{File|~/rpm/RPMS/x86_64}}: каталог для хранения rpm-пакетов для процессоров ''x86_64''.
+
* {{File|~/rpm/RPMS/noarch}}: каталог для хранения rpm-пакетов, не зависящих от архитектуры процессора.
+
* {{File|~/rpm/SOURCES}}: файлы исходного кода (например, {{File|mypackage.tar.bz2}}).
+
* {{File|~/rpm/SPECS}}: спек-файлы, которые мы должны построить.
+
* {{File|~/rpm/SRPMS}}: собранные ''src.rpm''-пакеты.
+
* {{File|~/rpm/tmp}}: для временных файлов, которые создаются программой {{программа|rpm}} во время сборки пакетов.
+
 
+
{{примечание|программе ''rpm'' необходимы каталоги для различных архитектур в ''~/rpm/RPMS''. Если они отсутствуют, вы получите сообщение об ошибке.}}
+
 
+
== Не создавайте файл {{File|.rpmmacros}} ==
+
 
+
Ряд руководств по сборке пакетов RPM советуют создать в «домашнем» каталоге файл конфигурации {{File|.rpmmacros}} с персональной информацией, которая будет добавлена в метаданные пакета, такой как значения %packager, %vendor и другие. Не делайте этого. Все подобные поля заполняются автоматически системой сборки. Однако, Вы все-таки можете создать этот файл, если Вы хотите указать другую директорию для сборки, отличную от /home/user/rpm. В этом случае укажите значения только для %_topdir и %_tmppath макросам. Не указывайте значения для других макросов.
+
 
+
= Сборка RPM =
+
 
+
== Из существующих «исходников» RPM ==
+
 
+
Сборка с использованием существующих исходных кодов возможна в том случае, если пакет уже есть в репозиториях дистрибутива.
+
 
+
Последнюю версию rpm-файла можно взять из Cooker. Список зеркал Cooker находится на странице [[Development/Mirrors|зеркала Cooker]]. Там можно найти:
+
 
+
; '''SRPMS''' : Каталог для хранения rpm с «исходниками» ({{источник|main}}, {{источник|contrib}}, {{источник|non-free}}, др.) для различных процессорных архитектур (''i586'', ''x86_64'', …);
+
; '''media/main''' : Для бинарных rpm из {{источник|main}};
+
; '''media/contrib''' : Для бинарных rpm из {{источник|contrib}};
+
; '''media/non-free''' : Для бинарных rpm из {{источник|non-free}};
+
<strike>* '''media/jpackage'' для бинарных rpm noarch.</strike> (jpackage нет)
+
 
+
Чтобы изменить source rpm для ROSA Linux, введите команду {{Cmd|rpm -ivh мой_пакет.src.rpm}}. Эта команда установит все файлы с исходными кодами в созданный вами каталог {{File|~/rpm}}.  
+
 
+
{{Примечание|Программу ''urpmi'' можно настроить таким образом, чтобы она сама загружала «исходники».}}
+
 
+
Например:
+
 
+
<pre>
+
[camille@kenobi ~/rpm]$ rpm -i /cooker/SRPMS/ktron-1.0.1-2mdv.src.rpm
+
[camille@kenobi ~/rpm]$ ls -R *  
+
SRPMS:
+
SPECS:
+
ktron.spec
+
SOURCES:
+
ktron-1.0.1.tar.bz2
+
RPMS:
+
noarch/ i686/ i586/ i386/
+
BUILD:
+
</pre>
+
 
+
Из приведённого выше примера видно, что программа {{программа|rpm}} установила в rpm-дерево файл с исходными кодами {{File|ktron-1.0.1.tar.bz2}} и спек-файл. Было бы полезным пересобрать текущую версию пакета, чтобы понять, как он компилируется. Для этого нужно воспользоваться программой {{программа|rpmbuild}}, запустив её с опцией {{Cmd|buildall}}:
+
 
+
<pre>
+
[camille@kenobi ~/rpm]$ cd ~/rpm/SPECS
+
[camille@kenobi ~/rpm]$ rpmbuild -ba ktron.spec
+
[camille@kenobi ~/rpm]$ ls -l ~/rpm/RPMS/i586/ktron-1.0.1-2mdv.i586.rpm
+
[camille@kenobi ~/rpm]$ ls -l ~/rpm/SRPMS/ktron-1.0.1-2mdv.src.rpm
+
</pre>
+
 
+
Если сборка завершилась без ошибок (а она, кстати, может длиться несколько часов, если собирается какой-нибудь сложный пакет, например, ядро), собранный пакет и пакет с исходными кодами будут находиться в каталогах {{File|~/rpm/RPMS/i586}} и {{File|~/rpm/SRPMS/}} соответственно. Для того, чтобы установить собранный пакет, необходимо получить права суперпользователя. Для этого нужно ввести в терминале команду {{Cmd|su}} и ввести пароль суперпользователя. Чтобы выйти из режима суперпользователя используйте клавиатурное сочетание клавиш «Ctrl+D» или наберите команду {{cmd|exit}}. Для сборки и пересборки пакетов с «исходниками» привилегий суперпользователя не требуется.
+
 
+
Журнал сборки может быть достаточно объёмным, его можно сохранить для последующего просмотра.
+
 
+
В подкаталогах {{File|~/rpm/BUILD}} обычно можно получить доступ к пропатченным «исходникам» (если один или более патчей находились в каталоге {{File|~/rpm/SOURCES}}), бинарникам, скомпилированным библиотекам, страницам руководств и т. д. Спек-файл описывает исходный код и патч-файлы, способы сборки и установки пакета.
+
 
+
Теперь, чтобы исправить {{программа|ktron}}, нужно лишь внести изменения в спек-файл, а затем пересобрать пакет.
+
 
+
{{Примечание|Каждый пакет, собираемый ROSA Desktop, использует систему контроля версий CVS. Это позволяет записывать каждое состояние пакета, т. е. разработчик может обратиться к архиву для просмотра сделанных изменений. Если сделанные изменения по каким-либо причинам не являются желательными, разработчик может их отменить.}}
+
 
+
Каждый спек-файл хранится в модуле ''SPECS/<package>'' или ''contrib-SPECS/<package>''. К нему можно получить доступ на [http://cvs.mandriva.com/ cvs.mandriva.com].
+
 
+
== Сборка из исходных текстов ==
+
 
+
Допустим, вы нашли интересную программу на сайте [http://freshmeat.net/ Freshmeat] или [http://sourceforge.net/ Sourceforge], и вы хотите, чтобы эта программа стала доступной для всех пользователей ROSA Desktop.
+
 
+
Скачайте архив с исходным кодом и поместите его в каталог {{File|SOURCES}}.
+
 
+
=== Предварительные проверки ===
+
 
+
; Лицензия: Несмотря на распространённость лицензии GPL, есть ещё множество не-GPL лицензий. Необходимо точно определить лицензию программного обеспечения, чтобы узнать, можно ли включать его в дистрибутив. Мы не принимаем программы, использующие проприетарные лицензии, но для клуба есть несколько исключений. Также, мы не можем принять программы, которые не позволяют нам свободно их распространять. Список лицензий, которые разрешены к использованию в дистрибутиве, находится на странице [http://wiki.mandriva.com/ru/Development/Packaging/Licenses|лицензии Mandriva].
+
; Сжатие tar-архива: Мы рекомендуем использовать исходный tar-архив без каких-либо изменений. Если исходники распространяются с использованием различных методов сжатия, мы часто отдаём предпочтение {{File|.tar.bz2}}. Избегайте сжатия патчей (полученные {{программа|diff}} и др. подобными программами) и других текстовых файлов (файлы настроек, сценарии и т. д.), т. к. они занимают, как правило, очень мало места, в противном случае будет сложнее увидеть изменения в файлах различий (diff-файлах) Subversion (Subversion в свою очередь сам использует некоторую форму сжатия).
+
 
+
{{примечание|Для критических к безопасности пакетов мы рекомендуем не изменять исходный код, т. к. это приведёт к изменению контрольной суммы и подписи. Мы рекомендуем оставлять такие пакеты в их исходном состоянии, примером такого пакета может служить OpenSSH.}}
+
 
+
== Внутри spec-файла ==
+
 
+
Вот мы и добрались до одной из важнейших глав этого документа. [[RPM синтакс spec файла RU|Spec-файл]] содержит всю необходимую информацию для:
+
 
+
* компиляции программы, сборки исходного кода и бинарного rpm-пакета;
+
* установки и удаления программы.
+
 
+
Короче говоря, спек-файл описывает моделируемую компиляцию и установку, говорит {{программа|rpm}}, какие файлы, полученные в результате инсталляции, должны быть упакованы, и как они должны в итоге устанавливаться в системе. Команды выполняются с использованием командной оболочки {{программа|/bin/sh}}, таким образом, конструкции команд вида {{Cmd|[ -f configure.in ] && autoconf}} являются корректными и их можно применять.
+
 
+
Мы рассмотрим основные возможности, используемые в одном из спек-файлов. По мере того, как вы будете собирать всё больше и больше rpm-пакетов, вы поймёте, что существуют некоторые дополнительные параметры, о которых мы не рассказывали. Более подробную информацию можно получить в книге [http://rikers.org/rpmbook/ Maximum RPM] (см. раздел 7).
+
 
+
{{Примечание|Мы рекомендуем открыть пару спек-файлов, чтобы  посмотреть, как они работают. Список спек-файлов и патчей можно получить [https://abf.io/import/ здесь]. Вы можете взять [http://wiki.rosalab.ru/en/index.php/Template_Spec_Files шаблоны для спек-файлов], чтобы начать изучение с чистого листа.}}
+
 
+
Рассмотрим следующий пример спек-файла, взятого из Cooker:
+
 
+
<pre>
+
Name:          gif2png
+
Summary:        Tools for converting websites from using GIFs to using PNGs
+
Version:        2.0.1
+
Release:        1
+
Source0:        http://www.tuxedo.org/~esr/gif2png/%{name}-%{version}.tar.bz2
+
Source1:        %{name}-%{version}-rosa-addon.tar.bz2
+
Patch0:        gif2png-2.0.1-bugfix.patch
+
URL:            http://www.tuxedo.org/~esr/gif2png/
+
 
+
Group:          Applications/Multimedia
+
License:        MIT-like
+
Requires:      python
+
 
+
%description
+
Tools for converting GIFs to PNGs. The program gif2png converts GIF files
+
to PNG files. The Python script web2png converts an entire web tree, also
+
patching HTML pages to keep IMG SRC references correct.
+
 
+
%prep
+
%setup -q -a 1
+
%patch -p1
+
 
+
%build
+
%configure
+
%make
+
 
+
%install
+
%makeinstall
+
 
+
%files
+
%defattr(0755,root,root)  
+
%doc README NEWS COPYING AUTHORS
+
%{_mandir}/man1/gif2png.1*
+
%{_mandir}/man1/web2png.1*
+
%{_bindir}/gif2png
+
%{_bindir}/web2png
+
 
+
# При подготовке пакетов для ROSA не создавайте раздел %changelog самостоятельно!
+
%changelog
+
* Mon Nov 02 1999 Camille Begnis <camille@mandrakesoft.com> 2.0.1-rosa2012
+
- Upgraded to 2.0.1
+
 
+
* Mon Oct 25 1999 Camille Begnis <camille@mandrakesoft.com> 2.0.0-rosa2012
+
- Specfile adaptations for Mandrake
+
- add python requirement
+
- gz to bz2 compression
+
</pre>
+
 
+
Символ «%» в начале строки может означать:
+
 
+
* начало секции (раздела) (''prep'', ''build'', ''install'', ''clean'');
+
* встроенный макрос сценария командной оболочки (''setup'', ''patch'');
+
* директива, используемая специальными секциями (разделами) (''defattr'', ''doc'', ...).
+
 
+
=== Раздел заголовка (''header'') ===
+
 
+
<pre>
+
Name:    gif2png
+
Version:  2.0.1
+
Release:  1
+
</pre>
+
 
+
Эти три строки автоматически определяют константы, которые можно использовать в других разделах спек-файла, называемые {{macro|%{name} }}, {{macro|%{version} }} и {{macro|%{release} }}. Некоторые пакеты могут формировать релиз с помощью устаревшего макроса {{macro|%mkrel}}, который в дистрибутивах ROSA просто возвращает свой аргумент.
+
 
+
Кроме того, есть несколько тегов, о которых вы, возможно, захотели бы узнать, но которых нет в примере спек-файла. Есть некоторые теги, которые вы можете встретить. Никто не требует, чтобы вы помнили все теги, если вы только приступили к сборке rpm-пакетов, но после некоторого времени этот список может послужить хорошей отправной точкой!
+
 
+
Теперь настало время объяснить, как формируется имя пакета. Очень важно всегда следовать этому соглашению, чтобы ваша работа была понятной для остальных.
+
 
+
* Бинарный пакет обозначается следующим образом: {{Pkg|имя-версия-релиз.arch.rpm}} (''name''-''version''-''release''.arch.rpm)
+
* Пакет с исходным кодом обозначается следующим образом: {{Pkg|имя-версия-релиз.src.rpm}} (''name''-''version''-''release''.src.rpm) (т. е. в нашем случае — {{Pkg|gif2png-2.0.1-1mdk.src.rpm}})
+
 
+
Имя, в основном, выбирается, исходя из названия главного бинарного пакета, хотя, при наличии веских причин, можно использовать другое имя.
+
 
+
Версия — это номер в имени оригинального исходного файла архива: {{File|name-version.tar.gz}}.
+
 
+
Релиз — это число, следующее за версией, увеличиваемое с каждой новой сборкой пакета, которая может быть связана с применением дополнительных патчей, изменениями внесёнными в спек-файл и даже тривиальным обновлением пиктограммы.
+
 
+
<pre>
+
Summary: tools for converting websites from using GIFs to using PNGs
+
</pre>
+
 
+
Эта строка представляет собой описание пакета.
+
 
+
<pre>
+
Source0:        http://www.tuxedo.org/~esr/gif2png/%{name}-%{version}.tar.bz2
+
</pre>
+
 
+
Эта строка говорит {{программа|rpm}}, какой файл исходного кода должен быть использован для сборки пакета. Заметьте, что имени файла предшествует полный URL (что, в общем случае, не обязательно), указывающий на веб-сайт, на котором расположен оригинальный исходный код. {{программа|rpm}} уберёт URL, сохранив только имя файла, и произведёт поиск в каталоге {{File|SOURCES}}. Хотя предоставление полного URL и не является обязательным, его использование строго рекомендуется, таким образом любой желающий сможет узнать, где можно скачать исходники.
+
 
+
{{Примечание|Информация о URL позволяет таким инструментам, как ''rpmbuildupdate'', автоматически пересобирать новые версии программ (подробнее см. [[Development/Packaging/Tools/rpmbuildupdate|rpmbuildupdate]]).}}
+
 
+
Если файлов с исходным кодом несколько, используйте несколько строк, начинающихся с ''Source1: …'', ''Source2: …'' и т. д. соответственно.
+
 
+
<pre>
+
Patch0:        gif2png-2.0.1-bugfix.patch
+
</pre>
+
 
+
Это необязательный тег. Его можно использовать в двух случаях:
+
 
+
# Вы исправили ошибку в исходном коде программы и [[Rpmbuild_and_git|создали патч]], который должен быть применён к исходному коду программы перед компиляцией.
+
# Вы узнали, что для данного пакета программы где-то в сети есть патч, и скачали этот патч.
+
 
+
Все патчи должны находиться в каталоге {{File|SOURCES}}. Если патчей несколько, то они должны называться ''Patch1'', ''Patch2'' и т. д.
+
 
+
<pre>
+
URL:            http://www.tuxedo.org/~esr/gif2png/
+
</pre>
+
 
+
Эта строка указывает на домашнюю страницу программы. Её использование не является обязательным, но мы всё же рекомендуем её указывать.
+
 
+
<pre>
+
Group:          Multimedia
+
</pre>
+
 
+
Этот фрагмент говорит программе {{программа|rpm}}, в какой части дерева пакетов разместить наш пакет. Эта возможность используется фронт-эндами пакетных менеджеров таких, как {{программа|rpmdrake}} и {{программа|kpackage}}.  
+
 
+
Полная структура групп, которая, кстати говоря, отличается от аналогичных групп Red Hat, представлена на странице [[Packaging group]]. Очень важно следовать принятым соглашениям о группах, иначе ваш пакет внесёт неразбериху в дерево пакетов.
+
 
+
<pre>
+
License:        MIT-like
+
</pre>
+
 
+
Этот тег определяет лицензию, выбранную держателем авторских прав, которая будет применяться к программному обеспечению, находящемуся в пакете. Чаще всего это GPL. На страницах [[Development/Packaging/Licenses|лицензии РОСА]] и [[Licensing policy|политика лицензирования]] представлены полные списки разрешённых к использованию лицензий.
+
 
+
 
+
<pre>
+
BuildRequires:  python
+
</pre>
+
 
+
Обозначает, что для компиляции rpm потребуются библиотеки языка python, часто необходимо указывать, например, libpyglib-gi2, python-devel, если какой-то пакет не найти сразу, то можно поискать его с помощью команды urpmi -p ИмяПакета, так как он может содержаться в другом пакете, это указывается командой
+
 
+
<pre>
+
Provides:  libgif2png   
+
</pre>
+
 
+
в Provides указывается имя библиотеки, которая может использоваться другими программами (предоставляется)
+
 
+
<pre>
+
Requires:      python
+
</pre>
+
 
+
Эта строка была добавлена, потому что одна из программ, включённых в пакет, является сценарием написанным на языке программирования Python. Это означает, что для корректной работы программы потребуется интерпретатор {{программа|python}}.
+
 
+
Можно использовать требование к минимальной (или конкретной) версии. Например:
+
 
+
<pre>
+
Requires: python >= 1.5.1
+
</pre>
+
 
+
В редких случаях приложение может конфликтовать с другими уже установленными библиотеками или старыми версиями приложений, чтобы убрать их из системы при установке нужно сообщить об этом пользователю, для этого используется тег
+
 
+
<pre>
+
Conflicts: python <= 1.0.0
+
</pre>
+
 
+
Некоторые пакеты становятся устаревшими после установки новых библиотек, чтобы отметить их и удалить используется тег
+
 
+
<pre>
+
Obsoletes: gif2png < 2.0.0
+
</pre>
+
 
+
 
+
Ниже следует тег описания:
+
 
+
<pre>
+
%description
+
Tools for converting GIFs to PNGs. The program gif2png converts GIF files
+
to PNG files. The Python script web2png converts an entire web tree, also
+
patching HTML pages to keep IMG SRC references correct.
+
</pre>
+
 
+
Это совершенно особый тег внутри заголовочной части спек-файла, потому что он содержит текст, который может занимать произвольное количество строк и параграфов. Текст содержит полное описание программного обеспечения, которое помогает пользователю решить нужно ли устанавливать данный пакет или нет.
+
В целях улучшения восприятия спек-файлов, переводы тегов ''summary'' и '' description'' хранятся в специальных файлах, называемых {{File|<package>.po}}.
+
 
+
Эти файлы хранятся в [http://cvs.mandriva.com/cgi-bin/viewvc.cgi/poSPECS/ poSPECS модуле] в CVS Cooker. Когда создаётся новый пакет, основной po-файл автоматически создаётся в этом модуле для будущих переводов.
+
 
+
Этот метод подразумевает, что весь текст внутри спек-файла написал на английском языке. Однако, есть пакеты, предназначенные для определённых языков (например, {{Pkg|ispell-de}}). В этом случае рекомендуется наличие текста на двух языках: на английском и на языке, для которого предназначен этот пакет. Для этого надо будет использовать специальные теги: ''Summary(de)'': .. и {{Процесс|%description -l de}}.
+
 
+
=== Раздел подготовки к сборке (''prep'') ===
+
 
+
<pre>
+
%prep 
+
%setup -q -a 1
+
%patch0 -p1
+
</pre>
+
 
+
В этом резделе записан первый сценарий, выполняемый программой {{программа|rpm}}. Он делает следующее:
+
 
+
* создаёт каталог верхнего уровня для сборки (в {{File|BUILD}});
+
* распаковывает оригинальный исходный код в каталог сборки;
+
* применяет патчи (если они есть) к исходному коду.
+
 
+
<pre>
+
%setup -q -a 1
+
</pre>
+
 
+
Это встроенный макрос, который выполняет следующие действия:
+
* переходит в дерево сборки;
+
* распаковывает исходный код ('''-q''' означает, что распаковка сопровождается минимальным выводом информации);
+
* изменяет владельца и права доступа к файлам с исходным кодом.
+
+
По умолчанию распаковывается первый исходный код (т. е. который имеет номер 0), для любых других исходников необходимо использовать дополнительные параметры, в нашем примере фрагмент '''-a 1''' говорит, что мы также хотим распаковать исходный код с номером 1.
+
 
+
Есть и другие интересные возможности при использовании макроса {{Процесс|%setup}}:
+
 
+
* '''-c name''' — переключатель '''-с''' говорит, что сначала должен создаваться каталог, и только затем должен осуществляться переход в этот каталог и происходить распаковка Source0. Это может оказаться полезным в том случае, если пакет ''tar.bz'' не имеет родительского каталога.
+
* '''-D''' — не удалять каталог перед распаковкой. Полезно лишь при наличии более одного макроса ''setup''. Может использоваться только в ''setup''-макросах, следующих за первым (но в первом — никогда).
+
* '''-T''' — этот параметр перекрывает действие по умолчанию распаковки ''Source'' из tar-архива и требует '''-b 0''' или '''-a 0''' для получения распакованного главного файла исходного кода. Этот параметр Необходим при наличии вторичных исходников.
+
* '''-n name''' — используйте этот переключатель, если имя rpm-пакета отличается от имени, получаемого при распаковке ''Source''. Например: если имя rpm-пакета {{Pkg|program-version-revision}}, а ''Source'' распаковывается в {{Pkg|program-version-date}}, процесс сборки ''rpm'' не сможет перейти в каталог {{File|program-version}}, поэтому используйте '''-n program-version-date''', тогда {{программа|rpm}} будет знать о новом каталоге, в котором и следует продолжить работу.
+
 
+
<pre>
+
%patch0 -p1
+
</pre>
+
 
+
Макрос, ответственный за применение патчей к исходникам. Его параметр '''-p<num>''' передаётся патч-программе. Допустим, что у вас есть другой патч ''Patch1'', объявленный в разделе ''header'', в таком случае вы должны будете добавить строку {{Процесс|%patch1 -p1}}. Добавление команды {{Cmd|-b .your_suffix}} является хорошим тоном, ведь таким образом вы можете сообщить другим, что делает ваш патч, или кто выполнил патч. Например, если Вася сделал патч, то он мог бы написать {{Процесс|%patch -p1 -b .vasya}}, или, если патч сделал Петя, тогда это могло бы быть {{Процесс|%patch -p1 -b .petya}}.
+
 
+
=== Раздел сборки (''build'') ===
+
 
+
<pre>
+
%build
+
</pre>
+
 
+
Этот раздел должен содержать сценарий, отвечающий за фактическую сборку программного обеспечения. Раздел состоит из команд, используемых при сборке пакета из дерева исходников, извлечённого из tar-архива.
+
 
+
<pre>
+
%configure
+
</pre>
+
 
+
Эта строка используется для настройки исходников. Макрос {{Процесс|%configure}} запускает команду {{Cmd|./configure}} со множеством дополнений таких, как <pre>export CFLAGS="$RPM_OPT_FLAGS"</pre> перед началом настройки (''configure''), и параметрами такими, как <pre>i586-mandrake-linux --prefix=/usr --datadir=/usr/share</pre> и т. д.
+
 
+
Иногда такие аргументы не поддерживаются сценарием configure. В таком случае, найдите причину и запустите {{Cmd|./configure}} с соответствующими параметрами. С помощью {{Процесс|%{''target''platform} }} сообщите о целевой платформе вызову configure, если это поддерживается. Конечно, нужно избегать определения архитектуры в спек-файле; для x86 она будет определена в i586-mandrake-linux, как показно в примере выше.
+
 
+
{{примечание|Чтобы использовать макрос ''%configure'' с разделяемыми библиотеками, понадобится пакет ''libtool''.}}
+
 
+
При сборке и тестировании вашего пакета, вы должны удостовериться, что целевой хост действительно является i586; особенно, когда компиляция происходит на процессорах более высокого типа, конфигурационный скрипт по умолчанию должен обнаружить ваш процессор, и произвести для него оптимизацию. Цель макроса {{macro|%configure}} отменить это поведение.
+
 
+
<pre>
+
%make
+
</pre>
+
 
+
Это простой макрос, который подготоваливает в основном make с соответствующими мультипроцессорными параметрами {{Cmd|-j<num>}}.
+
 
+
Для исходников, использующих xmkmf, вы должны заменить следующий make этим:
+
 
+
<pre>
+
make CDEBUGFLAGS="$RPM_OPT_FLAGS" CXXDEBUGFLAGS="$RPM_OPT_FLAGS"
+
</pre>
+
 
+
Для других пакетов, в большинстве случае (но не во всех) будет работать и просто make.
+
 
+
=== Раздел установки (''install'') ===
+
 
+
<pre>
+
%install
+
</pre>
+
 
+
В этом разделе должен содержаться сценарий, отвечающий за фактическую установку пакета в симулируемый установочный каталог: {{File|%{buildroot}}}.
+
 
+
Он должен содержать все команды, необходимые для того, чтобы сделать программу готовой к запуску на пользовательской системе.
+
 
+
<pre>
+
%makeinstall
+
</pre>
+
 
+
Это строка устанавливает программу в симулируемый установочный каталог для autoconf-исходников. Этот макрос будет расширен до "{{Cmd|make install}}" со множеством параметров для установки в симулируемый каталог {{File|%{buildroot}}}, например, <pre>prefix=%{buildroot}%{_prefix} bindir=%{buildroot}%{_bindir}</pre> и т. д.
+
 
+
В некоторых случаях сценарий configure может быть частично поломан. Возможно, вам понадобится погрузится в Makefile'ы, чтобы найти дополнительные параметры, чтобы установить его правильно. Один из наиболее распространённых: иногда вам нужно использовать make DESTDIR=%{buildroot} install.
+
 
+
Чтобы сохранить место на жёстком диске и время загрузки, ROSA использует lzma для сжатия man и info страниц. Это делается автоматически инструментарием rpm.
+
 
+
=== Раздел очистки (''clean'') ===
+
 
+
''Не используйте'' раздел clean в spec-файлах ROSA. При необходимости, используйте {{cmd|rpmbuild --clean ...}}.
+
 
+
=== Раздел файлов (''files'') ===
+
 
+
<pre>
+
%files
+
</pre>
+
 
+
Этот раздел состоит из списка файлов, находящихся в симулируемом дереве каталогов; эти файлы будут использоваться при сборке пакета.
+
 
+
Список файлов должен быть написан в спек-файле вручную. Он может быть создан из списка файлов, созданных программой {{программа|rpm}} в дереве каталога сборки. Чтобы создать список, наберите команду {{Cmd|rpmbuild -bi mypackage.spec}}, процесс сборки остановится сразу после симулируемой установки. Затем, просмотрите каталог симулируемой установки (в нашем случае {{File|~/rpm/tmp/gif2png-buildroot}}), чтобы увидеть, какие файлы предполагается положить в пакет (чаще всего кладутся все файлы).
+
 
+
Вы никогда не должны использовать {{программа|find}} для получения списка файлов пакета; необходимо явно перечислять все файлы, что позводит избежать ошибок при сборке новых версий ПО. Единственным исключением являются файлы локализации, для которых следует использовать {{Процесс|%find_lang %{name} }} в разделе {{Процесс|%install}} и добавить {{Процесс|%files -f %{name}.lang}} в секцию {{Процесс|%files}} (см. описание макросов ниже).
+
 
+
Замечание о структуре каталогов: установленные файлы пакета '''должны''' следовать рекомендациям FHS [http://www.pathname.com/fhs http://www.pathname.com/fhs].
+
 
+
<pre>
+
%defattr(0755,root,root)
+
</pre>
+
 
+
Этот тег задаёт атрибуты, которые будут применяться ко всем файлам, копируемым в систему пользователя. Аргументы означают:
+
 
+
* -: все атрибуты для регулярных файлов остаются неизменными;
+
* root: владелец файла — root;
+
* root: группа файла — root;
+
* 0755: атрибуты, применённые ко всем каталогам, принадлежащим пакету — 0755 (''rwxr-xr-x'').
+
 
+
<pre>
+
%doc README NEWS COPYING AUTHORS
+
</pre>
+
 
+
Специальный тег {{Процесс|%doc}} помечает файлы, которые являются частью документации пакета. Файлы документации будут помещены в {{File|/usr/share/doc/gif2png-2.0.1/}}. Этот каталог будет создан автоматически. Файлы {{Процесс|%doc}} задаются относительно каталога извлечённых из tar-архива исходников в каталоге {{File|BUILD}}.
+
 
+
<pre>
+
%{_mandir}/man1/gif2png.1*
+
%{_mandir}/man1/web2png.1*
+
</pre>
+
 
+
Рекомендуется перечислять в отдельности каждую man или info-страницу.
+
 
+
Также, вы можете задаться вопросом: почему вместо {{File|gif2png.1.lzma}} используется {{File|gif2png.1*}}? Это сделано для того, чтобы сохранить совместимость с другими системами, которые используют сжатие gzip вместо lzma. Если вы нашли такие ссылки на lzma сжатие в спеке, замените их регулярным выражением, как в примере выше. Чаще всего вы можете использовать {{macro|%{_mandir}/man1/*}}, что соответствует всем файлам в директории man1.
+
 
+
<pre>
+
%{_bindir}/gif2png
+
%{_bindir}/web2png
+
</pre>
+
 
+
Как вы можете видеть, для каждого необходимого пути есть макрос нужного типа. Вот наиболее полезные:
+
(полный список доступен в файле {{File|/usr/lib/rpm/macros}}): {{Процесс|%{_prefix} }}, {{Процесс|%{_bindir} }}, {{Процесс|%{_sbindir} }}, {{Процесс|%{_datadir} }}, {{Процесс|%{_libdir} }}, {{Процесс|%{_sysconfdir} }}, {{Процесс|%{_mandir} }}, {{Процесс|%{_infodir} }}. Для игр используйте {{Процесс|%{_gamesbindir} }} и {{Процесс|%{_gamesdatadir} }}.
+
 
+
=== Раздел журнала изменений (''changelog'') ===
+
 
+
''Внимание!'' Здесь представлена общая информация о секции ''changelog''. Вы ''не должны'' добавлять эту секцию в spec-файл самостоятельно, поскольку она генерируется автоматически из истории изменений в системе контроля версий.
+
 
+
==== Что такое журналы изменений ====
+
 
+
<pre>
+
%changelog
+
</pre>
+
 
+
Этот раздел предназначен для хранения записей о различных изменениях, сделанных в пакете. Каждая новая сборка пакета должна сопровождаться параграфом в этом разделе, также как и каждый новый номер версии программы. Соблюдается следующая структура этих параграфов:
+
 
+
<pre>
+
* Mon Nov 02 1999 Camille Begnis <camille@mandrakesoft.com> 2.0.1-1mdk
+
</pre>
+
 
+
* первая строка параграфа начинается со знака звёздочки «*» и отделяется от неё пробелом;
+
* три буквы, обозначающие день недели;
+
* три буквы, обозначающие месяц;
+
* две цифры дня месяца;
+
* четыре цифры года;
+
* имя человека, создавшего пакет;
+
* его же фамилия;
+
* его же адрес электронной почты в угловых скобках «<>»;
+
* текущая версия и релиз.
+
 
+
<pre>
+
- Upgraded to 2.0.1
+
</pre>
+
 
+
Затем следует одна строка, начинающаяся с «-», в которой описывается изменение в пакете.
+
 
+
Примеры:
+
 
+
<pre>
+
- spec file stolen from korganizer.
+
- last snapshot before release
+
- ROSA adaptations.
+
- Fix bug in /etc/zsh use USERNAME instead of USER.
+
- Remove petit bouchon which annoys other players.
+
- Improve /etc/z* to source the /etc/profile.d/ files.
+
- fix typo in examples directory name
+
- fixed QT libs version requirements
+
- add patch to handle Earl Grey tea
+
</pre>
+
 
+
По умолчанию в собранный пакет помещаются только записи не старше 1 года. Это поведение может быть изменено настройкой значения {{macro|%_changelog_truncate}}
+
 
+
==== История изменений в системе контроля версий ====
+
Информация для секции ''changelog'' автоматически генерируется из истории изменений системы контроля версий. Каждая строка сообщения из истории изменений становится записью в секции ''changelog'', начинающейся с дефиса.
+
Сообщения автоматически группируются по имени и email-адресу автора.
+
 
+
Если вы не хотите, чтобы строка из истории изменений попала в changelog пакета, добавьте в начале строки "SILENT: ". Пустые строки также игнорируются.
+
 
+
== Сборка ==
+
 
+
Наконец, наш спек-файл готов. Наберите грудью побольше воздуха, присядьте и наберите команду {{Cmd|rpmbuild -ba mypackage.spec}}.
+
 
+
Также можно добавить параметр {{Cmd|--clean}}, который очистит каталог {{File|BUILD}} после завершения сборки пакета. Это может оказаться полезным, если у вас мало свободного места на жёстком диске.
+
 
+
Процесс может закончиться со следующими результатами:
+
 
+
* exit 0;
+
* все остальные случаи.
+
 
+
There are then two possibilities for the last line of your process:
+
 
+
* 0.01% probabilities: + exit 0
+
* 99.99% probabilities for other cases.
+
 
+
You are in the second case? Congratulations you passed the test, you are not an alien.
+
 
+
Good luck, so long, have a look to rpm building options ({{cmd|man rpmbuild}} ) to debug your work, look at other persons' specfiles, etc..
+
 
+
There is a very clean way to build packages: use {{cmd|rpmbuild -bs --rmspec --rmsource}} (in order to remove anything from the original build) and then do a {{cmd|rpmbuild --rebuild}}.
+
 
+
== Оптимизация процесса сборки ==
+
 
+
Когда вы запускаете команду для сборки вашего пакета, вы точно были уведмлены сообщением вида: {{Cmd|foo-devel is necessary for foo2}}.
+
 
+
Это означает, что нужна информация из других пакетов, использующихся для разработки (обычно, такие файлы имеют названия вида {{File|foo.h}}). Если у вас их нет, компиляция остановится, или, даже если компиляция закончится успешно, пакет будет лишён некоторых возможностей.
+
 
+
Сборочный кластер ROSA имеет множество таких предустановленных пакетов для разработки (''devel''-пакетов). В случае, если один из обязательных пакетов не был перечислен в спек-файле, пакет будет собран на кластере в любом случае. Но отсутствие такой информации не позволит собрать пакет на машинах, на которых отсутствует devel-пакет, делая отладку и обновление более трудной.
+
 
+
Взгляните на веб-сайт программы, для которой подготавливается пакет, там можно найти информацию о необходимых компонентах.
+
 
+
Чтобы найти эти "missing BuildRequires", выполняя сборку, в системе должны присутствовать только самые основные пакеты для разработки:
+
 
+
* {{Pkg|glibc-devel}}
+
* {{Pkg|libncurses5-devel}}
+
* {{Pkg|libstdc++6-devel}}
+
 
+
После этого устанавливайте только те пакеты для разработчиков, которые попросит команда сборки {{программа|rpm}}.  
+
 
+
Запуская сборку, следите за сообщениями ''checking for...''
+
 
+
Если вы увидите что-то наподобие ''checking for foo...  foo.h not found'', это означает, что заголовочный файл в вашей системе не найден.
+
Найдите пакет для разработк, содержащий ''foo.h'', но будьте осторожны: вы можете найти больше одного пакета. Поэтому выберите тот, что подходит в наибольшей степени. К примеру, не следует выбирать пакет, имеющий отношение к компьютерной сети, если вы собираете приложение, предназначенное для работы со звуком.
+
 
+
Затем, установите пакет в систему, не забудьте добавить его имя в раздел  ''BuildRequires'' вашего спек-файла.
+
 
+
Отсутствующие заголовочные файлы могут быть найдены во время компиляции. Если она останавливается, проверьте наличие других {{File|foo.h}} и примените тот же способ.
+
 
+
= Проверка RPM-пакета =
+
 
+
== Основные проверки ==
+
 
+
Перво-наперво нужно проверить следующее:
+
 
+
* созданы ли rpm в соответствующих каталогах с корректными именами (в каталогах {{File|~/rpm/SRPMS/}} и {{File|~/rpm/RPMS/i586/}});
+
* корректна ли информация, полученная с помощью команды {{Cmd|rpm -qlivp --changelog мой_пакет.(src.)rpm}}.
+
 
+
== Запуск Rpmlint ==
+
 
+
После этого, вы должны воспользоваться утилитой [[Rpmlint]], которая выполнит различные проверки пакета. Перед запуском {{Cmd|rpmlint}} убедитесь, что у вас установлен пакет {{pkg|rpmlint-mandriva-policy}}, содержащий правила проверки для Росы. Наберите {{Cmd|rpmlint мой_пакет.<archtype>.rpm}} для получения отчёта об определённом пакете. Чтобы получить более подробную информацию, используйте ключ {{Cmd|-i}}. Вы должны проверить {{File|rpm}} и {{File|src.rpm}}. Дополнительную информацию по ошибкам, которые встречаются при сборке, можно найти на странице [[Problems and issues with packaging|проблемы сборки пакетов]].
+
 
+
== Install test ==
+
 
+
Теперь необходимо проверить установку и обновление пакета на любой машине (желательно отличной от той, на которой проходила сборка), и удостовериться, что:
+
 
+
* Созданы все необходимые файлы с нужными правами и владельцами
+
* Все скрипты, выполняющиейся при установке, отработали успешно
+
* У всех исполняемых файлов установлен бит ''executable'', а файлы с документацией доступны всем пользователям
+
 
+
Для полноты тестирования можно также проверить процесс удаления пакета, функциональность установленного ПО и тому подобное.
+
 
+
Если все тесты прошли успешно, то вы почти у цели - осталось только отправить пакет в репозиторий.
+
 
+
= Что-то пошло не так? =
+
 
+
Если вы читаете этот документ, то это уже хорошо. Если вы не найдете ответ на интересующий вас вопрос здесь, попробуйте также обратиться к следующим источникам:
+
 
+
# Официальный документ ''RPM-HOWTO'' (устанавливается в систему вместе с программой {{программа|rpm}}).
+
# Книга Red Hat ''Maximum RPM'', которая доступна на [http://www.redhat.com/docs/books/max-rpm/max-rpm-html/ http://www.redhat.com/docs/books/max-rpm/max-rpm-html/].
+
# посмотрите на spec-файлы схожих пакетов - возможно, их авторы сталкивались со схожими проблемами
+
# Задайте вопрос в почтовой рассылкеразработчиков ROSA .
+
 
+
Если вы полагаете, что найденные вами решения могут быть полезны остальным, сообщите об этом авторам документов, в которые вы бы хотели добавить описания этих решений.
+
 
+
= Предустановочные и постустановочные сценарии =
+
 
+
== Основы ==
+
 
+
RPM-пакет представляет из себя нечто большее, чем просто архив с файлами, которые извлекаются в определённые каталоги на клиентских системах.
+
 
+
Система предоставляет программистам мощную возможность: предустановочные и постустановочные сценарии. Эти сценарии позволяют сборщику пакета вписать фрагмент кода, который будет запущен на клиентской машине при установке или удалении пакета.
+
 
+
Эти сценарии создаются из любых допустимых команд интерпретатора командной строки. Вот четыре из них:
+
 
+
Имеются некоторые предупреждения относительно этих сценариев. Во-первых, вы должны уложиться в размер буфера 8192, во-вторых, сценарии не должны быть интерактивными. Всё, что требует от пользователя ручного ввода, является неверным, т. к. это нарушает неинтерактивность процедур установки RPM.
+
 
+
* {{macro|%pre}} - этот сценарий выполняется перед установкой пакета в систему.
+
* {{macro|%post}} - этот сценарий выполняется после установки пакета в систему.
+
* {{macro|%preun}} - этот сценарий выполняется перед удалением пакета из системы.
+
* {{macro|%postun}} - этот сценарий выполняется после удаления пакета из системы.
+
 
+
Назначение таких сценариев может быть чрезвычайно многообразным. Сценарии должны быть спроектированы таким образом, чтобы не навредить системе. Помните, что сценарии выполняются от имени суперпользователя. Они относятся к задачам системного администрирования, завершающим установку нового приложения. Например:
+
 
+
* Добавить в {{prog|cron}} запуск программы через равные интервалы времени
+
* Запустить {{prog|chkconfig}}, чтобы запустить службу во время загрузки
+
 
* ...
 
* ...
  
== Работа с обновлениями ==
+
== Изменения во флагах компилятора (CFLAGS, %optflags) по умолчанию ==
 
+
Работа с пакетами осложняется тем фактом, что пакет может быть обновлен, а не просто установлен или удален. проблема заключается в том, что при обновлении скрипт {{macro|%postun}} новой версии пакета запускается после скрипта {{macro|%post}} старой версии, и то, что сделал последний скрипт, может быть потеряно.
+
 
+
Часто полезно убедиться, что те или иные действия производятся только при установке/удалении пакета, но не при обновлении. Для обработки таких ситуаций RPM передает специальный аргумент скриптам {{macro|%pre}}, {{macro|%preun}}, {{macro|%post}} и {{macro|%postun}}.
+
 
+
Аргумент содержит количество  различных версий данного пакета, которые будут установлены на машине после выполнения данного скрипта. Например, при установке нового пакета, скриптам {{macro|%pre}} и {{macro|%post}} будет передано значение "1". При обновлении пакета, скрипты {{macro|%pre}} и {{macro|%post}} новой версии получат значение "2", скрипты {{macro|%preun}} и {{macro|%postun}} старой версии - "1".
+
 
+
{| border="1"
+
|+ align="bottom" style="font-size: 10px; font-weight: bold;" | Таблица A-1. Значение параметра, передаваемого pre и post скриптам
+
! style="background:#efefef;" | Параметр \ Скрипт
+
! style="background:#efefef;" | %pre
+
! style="background:#efefef;" | %post
+
! style="background:#efefef;" | %preun
+
! style="background:#efefef;" | %postun
+
|-
+
| первоначальная установка || 1 || 1 || N/C || N/C
+
|-
+
| обновление || 2 || 2 || 1 || 1
+
|-
+
| удаление || N/C || N/C || 0 || 0
+
|}
+
 
+
Наличие такого параметра позволяет программистам различать, в какой ситуации запускается скрипт - при установке или при обновлении пакета.
+
 
+
* Для скриптов установки ({{macro|%post}}, {{macro|%pre}}) - если параметр $1 равен "1", то происходит первоначальная установка
+
* Для скриптов удаления ({{macro|%postun}}, {{macro|%preun}}) - если параметр $1 равен "0", то происходит удаление пакета; иначе это обновление либо установка с опцией --force.
+
 
+
Для проверки значение параметра, можно использовать следующую конструкцию:
+
 
+
<pre>
+
%postun
+
if [ $1 -eq 0 ]; then
+
    ### Выполнение действий, специфичных для удаления пакета
+
fi
+
if [ $1 -eq 1 ]; then
+
    ### Выполнение действий, специфичных для обновления пакета
+
fi
+
</pre>
+
 
+
= Файловые триггеры =
+
 
+
Чтобы избавиться от необходимости выполнения часто встречающихся задач - таких как выполнение "%post -p /sbin/ldconfig" или "%update_menus" - в ROSA используются [[файловые триггеры RPM]].
+
  
= More macros =
+
Части флагов не оказалось после перехода на rpm4, здесь описаны размышления, какие вернуть, а какие нет. Можно переделать.
  
При сборке пакетов для Росы, вы можете использовать в spec-файле различные макросы для выполнения типичных задач.
+
- <s>убран -fPIC: флаг был в [https://file-store.rosalinux.ru/api/v1/file_stores/99c5fa561dd0d897bfa8cd97f2aa60781bc578d4 cpu-os-macros.tar.gz], импортированном из Mandriva и не менявшимся, зачем он нужен в %optflags, я не понял, поэтому обратно в RPM4 не добавляю; пришлось в [https://abf.io/import/qt4/commit/ca3940d88781a5c4f30039d5d5d2df4e7f1071f2 qt4] и [https://abf.io/import/qt5-qtbase/commit/3d8a7088d29084a5ac124c1486d8ca5ae406da90 qt5-qtbase] добавить -fPIC вручную;</s>
  
* Обработка info-старниц:
+
-fPIC [https://abf.io/import/rpm-openmandriva-setup/commit/10fc8925fc9f09ccfb34af1e1eff42e2c65e0fe8 возвращен]; чтобы не было [https://wiki.gentoo.org/wiki/Project:AMD64/Fixing_-fPIC_Errors_Guide#Case_4:_Linking_dynamically_against_static_archives проблем] с линковкой разделяемых библиотек, собранных с -fPIC, со статичными библиотеками, собранными без -fPIC, -fPIC возвращен в %optflags по умолчанию
  
<pre>
+
Если необходимо отключить -fPIC для конкретного пакета, то можно сделать так:
%post
+
  %global _fpic_cflags %{nil}
%__install_info %{name}.info
+
  
%preun
+
- убран -ffat-lto-objects: он был в rpm5/macros/mandriva.in, но не ясно, зачем тратить машинное время на компиляцию одновременно вариантов для LTO и нет, когда как LTO не используется в дистрибутиве, не понятно;
%__install_info %{name}.info
+
</pre>
+
  
* Обновление системы меню. В Росе используется [[XDG_menu_system_policy|Меню XDG]].
+
- убран -fno-delete-null-pointer-checks: он был тоже в rpm5/macros/mandriva.in, но зачем нужно изменять поведение gcc по умолчанию таким образом, не очень ясно; можно будет вернуть
  
<pre>
+
UPD: этот флаг [https://abf.io/import/webkit/commit/48f3a3544d602351856ad60c00d8bdac44a3f558 был] вручную восстановлен в пакете webkit  в соответствии с рекомендацией от 1С — проприетарной программы, использующей системный libwebkitgtk-3.0 ([https://bugzilla.altlinux.org/show_bug.cgi?id=36998#c28 ALT#36998#c28]). Возможно, его стоит вернуть глобально?
%post
+
%{update_menus}
+
  
%postun
+
Полезные обсуждения по теме: https://news.ycombinator.com/item?id=17360316, https://github.com/RIOT-OS/RIOT/issues/12039
%{clean_menus}
+
</pre>
+
  
* Обработка файлов локализации. Хорошей практикой является не ручное перечисление всех {{file|.mo}}-файлов, которые обычно находятся в поддиректориях {{file|/usr/share/locale/..}}, а использование специального макроса в секции {{macro|%install}}, которые создаст отдельный файл с перечнем файлов с локализациями:
+
- убран -fvar-tracking-assignments: надобность сомнительная, кому нужно дебажить, может сам собрать ПО, в т.ч. с -O0 вместо -O2, а еще не все компиляторы понимают этот флаг (clang вообще не понимает этот флаг, при его наличии приходится изобретать костыли вроде [https://nixtux.ru/768 %clang_gcc_wrapper])
  
<pre>
+
- убран -frecord-gcc-switches: надобность не очень понятна, а clang-у мешает
%find_lang %{name}
+
</pre>
+
  
Созданный файл необходимо указать в секции ''files'':
+
- было -fstack-protector в rpm5, стало -fstack-protector-strong в rpm4
  
<pre>
+
В rpm5:
%files -f %{name}.lang
+
</pre>
+
  
* Макропопределения, используемые при сборке - {{macro|%configure}} и {{macro|%makeinstall}}. Они автоматически устанавливают префикс для установки, а также различные директории (такие как bindir, datadir и другие). Как правило, эти макросыф отлично работают с небольшими пакетами, но могут потербовать дополнительной настройке при сборке сложных продуктов. Макрос {{macro|%make}} вызывает команду make с соответствующей опцией {{cmd|-j<num>}}, распараллеливая сборку на многоядерных машинах. Если вам все-таки необходимо вызвать скрипт {{prog|./configure}} напрямую, ''никогда'' не указывайте название целевой аппаратной архитектуры. Для этих целей есть макрос {{macro|%{''target''platform} }} (или даже {{macro|%{''target''cpu} }}, если необходима более точная информация).
+
  rosa-2016 ~ # rpm --eval %optflags | sed -e 's, ,\n,g' | sed -e 's,^\-,,g' -e 's,^\-,,g' | sort -u
* Сборка серверного ПО. Для сборки, от которого требуется повышенная надежность в ущерб производительности, мы используем специальный макрос {{macro|%serverbuild}}, который необходимо вызвать до начала самой сборки. Этот макрос выставляет необходимые значения флагов оптимизации. Секция {{macro|%build}} при этом выгдядит следующим образом:
+
  ffat-lto-objects
 +
  fno-delete-null-pointer-checks
 +
  fPIC
 +
  frecord-gcc-switches
 +
  fstack-protector
 +
  fvar-tracking-assignments
 +
  gdwarf-4
 +
  O2
 +
  param=ssp-buffer-size=4
 +
  pipe
 +
  Wa,--compress-debug-sections
 +
  Werror=format-security
 +
  Wformat
 +
  Wp,-D_FORTIFY_SOURCE=2
 +
  Wstrict-aliasing=2
  
<pre>
+
В rpm4:
%build
+
%serverbuild
+
%configure
+
%make
+
</pre>
+
  
* Макросы для init-скриптов. При установке пакета, в котором содержится init-скрипт (файл в директории {{file|/etc/init.d}}), необходимо зарегистрировать этот скрипт вызовом {{cmd|chkconfig --add ..}}; при обновлении, этого делать не надо, но если скрипт работает, то он должен быть перезапущен; при удалении пакета, необходимо удалить информацию о скрипте. Для этих целей у нас есть соответсвующий макрос:
+
  bash-4.4# rpm --eval %optflags | sed -e 's, ,\n,g' | sed -e 's,^\-,,g' -e 's,^\-,,g' | sort -u
 +
  D_FORTIFY_SOURCE=2
 +
  O2
 +
  Werror=format-security
 +
  Wformat
 +
  Wstrict-aliasing=2
 +
  fomit-frame-pointer
 +
  fPIC
 +
  fstack-protector-strong
 +
  gdwarf-4
 +
  m64
 +
  mtune=generic
 +
  param=ssp-buffer-size=4
 +
  pipe
  
<pre>
+
  RPM5 RPM4
%post
+
 
%_post_service <initscript-name>
+
  Есть в RPM5
 +
  ffat-lto-objects -
 +
  fno-delete-null-pointer-checks -
 +
  frecord-gcc-switches -
 +
  fvar-tracking-assignments -
 +
  Wa,--compress-debug-sections -
 +
 
 +
  Есть в RPM4
 +
  - fomit-frame-pointer
 +
  - m64
 +
  - mtune=generic
 +
 
 +
  Общее
 +
  fstack-protector fstack-protector-strong
 +
  fPIC fPIC
 +
  gdwarf-4 gdwarf-4
 +
  O2 O2
 +
  param=ssp-buffer-size=4 param=ssp-buffer-size=4
 +
  pipe pipe
 +
  Werror=format-security Werror=format-security
 +
  Wformat Wformat
 +
  Wp,-D_FORTIFY_SOURCE=2 D_FORTIFY_SOURCE=2
 +
  Wstrict-aliasing=2 Wstrict-aliasing=2
  
%preun
 
%_preun_service <initscript-name>
 
</pre>
 
  
* Обработка ''ghost''-файлов. Некоторые пакеты (в частности, многие игры), содержат файлы, которые в некоторый момент времени могут отсутствовать в системе. Такие файлы необходимо помечать как ''ghost'' и обрабатывать с помощью специальных макросов:
+
== Особенности перевода спеков на RPM 4 ==
  
<pre>
+
Скрипт rpm5-to-rpm4.sh, который автоматически вносит правки в спеки, здесь: https://gitlab.com/abf-mirror/abf-mirror-scripts
%install
+
  
(...)
+
Если вы видите коммиты от "NixTux Commit Bot" с текстом: "bot: rpm5 -> rpm4 (N)", — где N — номер итерации прохода скрипта по всем пакетам в abf.io/import/, то это коммиты, сделанные этим скриптом. Каковы были изменения в скрипте между итерациями, можно посмотреть в git по ссылке выше.
  
mkdir -p %{buildroot}/var/lib/games
+
* Появились макросы:
touch %{buildroot}/var/lib/games/powermanga.hi
+
  
%post
+
  Макрос    Значение в rpm4    Значение в rpm5
%create_ghostfile /var/lib/games/powermanga.hi root games 664
+
  %rpm4      1                  0
 +
  %rpm5      0                  1
 +
  %_rpm      4                  5
  
(...)
+
* Если нет иного выхода адаптировать спек под разные версии rpm, то можно сделать if/else:
 +
  %if %rpm4
 +
  < вариант для rpm4 >
 +
  %else
 +
  < вариант для rpm5 >
 +
  %endif
  
%files
+
Если хочется заморочиться и сделать так, чтобы была ошибка сборки, если ни один из вариантов %if не сработал, то можно написать так:
%attr(664, root, games) %ghost /var/lib/games/powermanga.hi
+
  %if 0%{?rpm4}
</pre>
+
  < вариант для rpm4 >
 +
  %else
 +
  %if 0%{?rpm5}
 +
  < вариант для rpm5 >
 +
  %else
 +
  %{error:Error!}
 +
  %endif
 +
  %endif
 +
Эта конструкция применит "< вариант для rpm4 >", если макрос %rpm4 задан и равен 1, "< вариант для rpm5 >", если макрос %rpm5 задан и равен 1, а если ни один из двух вариантов не подошел, то сборка упадет с ошибкой с текстом "Error!". Лучше избегать таких сложных конструкций!
  
Макрос {{macro|%create_ghostfile}} будет развернут в следующую конструкцию:
+
* уменьшено количество пакетов в базовой сборочной системе, так, basesystem-build больше не зависит от initscripts, gpg и др. (см. [https://abf.io/import/basesystem/commits/rosa2019.1 коммиты]), а из-за отсутствия initscripts больше нет, например, procps-ng с командой ps; минимизация сборочной системы — это скорее хорошо, чем плохо, т.к. ускоряет сборку, а мейнтейнер пакета будет вынужден лучше понимать, как происходит его сборка; при необходимости "потерянные" зависимости добавьте в BuildRequires вручную, [https://abf.io/import/perl/commit/e2785eeabcfb5a0cf1b06c6fb884291d46d7eebd пример]."BuildRequires: /usr/bin/python2"
  
<pre>
+
По причине отсутствия пакетов python / python3 в базовой системе в BuildRequires не работают макросы %python* из этих пакетов. Однако пакет python3 подтягивается через cmake-rpm-generators.
if [ ! -f /var/lib/games/powermanga.hi ]; then
+
  touch /var/lib/games/powermanga.hi
+
  chown root.games /var/lib/games/powermanga.hi
+
  chmod 664 /var/lib/games/powermanga.hi
+
fi
+
</pre>
+
  
* Привязка типов фалов .desktop / MIME к приложениям: система меню XDG позволяет привязывать приложения к файлам с заданным MIME-типом в файлах {{file|.desktop}}. При установке или удалении {{file|.desktop}}-файла, необходимо запустить утилиту {{prog|update-desktop-database}}, используя соответствующие макросы:
+
Больше нет krb5-devel, поэтому в некоторых пакетах нужно прописать: "BuildRequires: pkgconfig(krb5" или "BuildRequires: pkgconfig(krb5-gssapi)", в некоторых пакетах с дурацкими сборочными скриптами, которые полагаются на автоматику и в которых нельзя в явном виде включить или выключить GSSAPI, например, в curl, рекомендуется добавить проверку по образцу:
 +
  %check
 +
  readelf -a %{buildroot}%{_libdir}/libcurl.so | grep NEEDED | grep -q libgssapi
  
<pre>
+
* из базовой сборочной системы убран /usr/bin/python, делайте "BuildRequires: /usr/bin/python" или "BuildRequires: /usr/bin/python2" или "BuildRequires: /usr/bin/python3" при необходимости; обратите внимание, что python3-devel, он же pkgconfig(python3) и аналогично python-devel/pkgconfig(python) не подтягивают /usr/bin/python(3). Характерная ошибка:
%post
+
  BUILDSTDERR: sh: /usr/bin/python: No such file or directory
%update_desktop_database
+
В настоящий момент /usr/bin/python — это python2.
  
%postun
+
* Suggests и Requires(missingok) теперь '''Recommends''': в RPM 5 были только Suggests и Requires(missingok) (а Suggests был алиасом Requires(missingok), а в RPM 4 есть и то, и то, но Recommends работает так, как работал Suggests, а Suggests используется для иных вещей, поэтому заменяем "Suggests:" на "Recommends:", а чтобы такие спеки продолжали работать в RPM 5, мы [https://abf.io/soft/rpm5/commit/fb49a705c7f8fb716f7e5a7ed945bb91901e73ff научили] его понимать Suggests: теперь он считает и Suggests, и Recommends одинаково эквивалентными "Requires(missingok)"
%clean_desktop_database
+
</pre>
+
  
* База данных MIME-типов Freedesktop.org: база данных, используемая для получения всех возможных типов MIME с соответствующими расширениями файлов или их "магическими" числами, должна обновляться посредством вызова следующих макросов:
+
* Фильтры для автоматического генератора зависимостей (requires) и провайдов (provides) поменялись следующим образом, ниже сначала вариант RPM 4 (новый), затем RPM 5 (старый):
<pre>
+
  %__requires_exclude -> %__noautoreq
 +
  %__provides_exclude -> %__noautoprov
 +
  %__requires_exclude_from -> %__noautoreqfiles
 +
  %__provides_exclude_from -> %__noautoprovfiles
 +
Нет возможности легко научить RPM 4 понимать %__noautoreq, %__noautoprov, %__noautoreqfiles и %__noautoprovfiles, но есть возможность легко научить RPM 5 понимать оба варианта, что мы и [https://abf.io/soft/rpm5/commit/8c91a49b1f0b167db1b97e2394659f73531d2dfc сделали].
 +
Теперь, если в спеке указаны одновременно старый макрос и эквивалентный ему новый макрос, например:
 +
  %define __noautoreq 'libGL.*'
 +
  %global __requires_exclude 'libGL.*'
 +
...то rpm5 будет брать только значение старого (__noautoreq) и игнорировать новый (__requires_exclude). Если же указан только новый (__requires_exclude), то будет браться его значение. В большинстве случаев достаточно использовать только новый вариант от RPM 4, т.е. только
 +
  %global __requires_exclude libGL.*
 +
...но, если вдруг понадобится задать разные правила для RPM 5 и RPM 4, то укажите оба варианта, тогда RPM 5 возьмет только свой прежний вариант, а RPM 4 только свой. Обратите внимание, что RPM 4 не понимает старые варианты от RPM 5, поэтому для RPM 4 обязательно указать __requires_exclude, а не __noautoreq. %global и %define здесь примерно одно и то же и для RPM 4, и для RPM 5, но документация от разработчиков RPM 4 рекомендует использовать %global, когда как в rpm5 более предпочтительно было %define.
  
%post
+
rpm4 не понимает значения %__requires_exclude(_from)/%__provides_exclude(_from) в кавычках. Кавычки нужно убрать.
%update_mime_database
+
  
%postun
+
Про варианты от RPM 4 читайте [https://docs.fedoraproject.org/en-US/packaging-guidelines/AutoProvidesAndRequiresFiltering/ здесь].
%clean_mime_database
+
</pre>
+
  
* Кэш иконок: <b>все</b> пакеты, содержащие иконки, устанавливаемые в {{file|/usr/share/icons/hicolor}} (или другие директории, предусмотренные спецификациями freedesktop, - например, {{file|/usr/share/icons/gnome}} или {{file|/usr/share/icons/crystalsvg}} ) <b>должны</b> обновлять кэш иконок, как показано в следующем примере (данное требование не относится к иконкам, хранящимся в {{file|/usr/share/icons}}, {{file|/usr/share/icons/mini}} или {{file|/usr/share/icons/large}}):
+
Мы тщательно не изучали особенности раскрытия регулярных выражений в этих макросах-фильтрах, возможны нюансы, новые варианты сделаны эквивалентными старым для большинства типовых случаев.
  
<pre>
+
* В пакете [https://abf.io/import/rpm-openmandriva-setup rpm-openmandriva-setup] собраны макросы, которые существовали в RPM 5 и которых теперь нет в RPM 4, чтобы они продолжали работать в ROSA. Какие-то макросы просто скопированы, какие-то преобразовываются в их новые варианты. Также мы [https://abf.io/soft/rpm5/commit/d642081cb2497f64eff9e4a2db7c0ee60662f469 добавили] некоторые широко распространенные новые макросы от rpm4 в rpm5, чтобы после их замены в спеках описанным выше скриптом спеки продолжали работать для rosa2016.1 и rosa2019.0 без изменений.
...
+
%file
+
...
+
%{_iconsdir}/hicolor/*
+
%{_iconsdir}/crystalsvg/*
+
....
+
  
%post
+
Типовые замены макросов:
%update_icon_cache hicolor
+
  %configure2_5x -> %configure
%update_icon_cache crystalsvg
+
  %_sys_macros_dir -> %_rpmmacrodir
 +
  %_rpmhome -> %_rpmconfigdir
  
%postun
+
Возможные, но нерекомендуемые замены:
%update_icon_cache hicolor
+
  %make -> %make_build
%update_icon_cache crystalsvg
+
  %makeinstall_std -> %make_install
</pre>
+
  %setup_compile_flags -> %set_build_flags
 +
  %ldflags -> %build_ldflags
  
* Регистрация схем GConf: Схемы GNOME GConf должны устанавливаться и удаляться с помощью следующих макросов:
+
Также появились %build_cflags (CFLAGS, флаги компилятора Си), %build_cxxflags (CXXFLAGS, флаги компилятора Cи++), %build_fflags (FFLAGS, флаги компилятора Фортран); в rpm5 они сделаны эквивалентными %optflags; %optflags продолжает существовать, как и раньше.
  
<pre>
+
Макросы %make_* стали унифицированы с %ninja_*, %meson_* и др., т.е. build означает сборку, install — установку. Возможно изменение политики в отношение макросов.
...
+
# каждый ключ схемы соответствует файлу с именем /etc/gconf/schemas/<key>.schemas
+
%define schemas apps_gnome_settings_daemon_default_editordesktop_gnome_font_rendering desktop_gnome_peripherals_keyboard_xkb fontilus themus
+
  
%post
+
* rpm5 с описанными выше изменениями уже опубликован в rosa2019.0 и rosa2016.1
%post_install_gconf_schemas %{schemas}
+
  
%preun
+
* rpm4 не позволяет закомментировать %define:
%preun_uninstall_gconf_schemas %{schemas}
+
  #%define xxx yyy
</pre>
+
не будет работать, нужно заменить "#%define" на "#define"
 +
* в rpm4 не поддерживаются стадии BuildRequires, т.е. записи BuildRequires(check), BuildRequires(pre) заменяем на BuildRequires; потеря не велика, это использовалось очень редко и, как оказалось, во всем репозитории только одним из авторов этой статьи, при чем там, где без этого можно обойтись, просто для пущей красоты было
 +
* %_libexecdir теперь не /usr/lib(64), а /usr/libexec
 +
* в RPM 5 директории %_bindir, %_libdir и др. наследовали значение %_prefix, в rpm4 не наследуют, пример правок в пакете [https://abf.io/import/libressl/commits/rosa2019.1 libressl] (мы думаем над тем, как решить эту проблему, чтобы снова наследовалось значение %_prefix)
 +
* в RPM 4 есть такой макрос:
 +
  %__pkgconfig_path    ^((%{_libdir}|%{_datadir})/pkgconfig/.*\.pc|%{_bindir}/pkg-config)$
 +
Если значение %_libdir переназначено, то файлы *.pc для создания Requires и Provides скриптом [https://github.com/rpm-software-management/rpm/blob/master/scripts/pkgconfigdeps.sh scripts/pkgconfigdeps.sh] будут искаться, возможно, не там, где вы хотите
  
* Обновление бд scrollkeeper: если устанавливается файл {{file|.omf}}, то необходимо обновить базу данных scrollkeeper (используемую для индексирования документации в формате docbook):
+
[https://abf.io/import/libressl/commit/bcce10a2c4018284b314965c2b1492913d638712 Пример] решения (переназначим этот макрос, указав нужные пути):
 +
  %global __pkgconfig_path ^(%{_olibdir}/pkgconfig/.*\\.pc|%{_obindir}/pkg-config)$
 +
В RPM 5 такого макроса нет, поэтому этот %global/%define ему безразличен.
 +
* в RPM нельзя поставить %attr() на символическую ссылку, RPM 5 игнорировал такое, а RPM 4 выдает ошибку в явном виде, пример:
 +
  Explicit %attr() mode not applicable to symlink: /builddir/build/BUILDROOT/log4cpp-1.0-6.i386/usr/lib/liblog4cpp.so
 +
Исправление — убрать лишний %attr
 +
* в сборочнице теперь отключен доступ в сеть, часть пакетов не собирается с ошибкой вида:
 +
  BUILDSTDERR: error: Bad source: /builddir/build/SOURCES/mds-2.4.2.2.tar.gz: No such file or directory
 +
В таких случаях нужно вручную или с помощью "abf put" закачать исходники пакета на ABF. Раз такие пакеты собирались ранее, значит в них достаточно автоматизированно сделать "abf put" и закоммитить, но для этого нужно составить список таких пакетов
 +
* rpm5 съедал все содержимое папки с %doc, даже если туда положить что-то лишнее, а rpm4 требует явного указания всего содержимого папки /usr/share/doc/%name. Пример ошибки:
 +
  DEBUG: BUILDSTDERR: error: Installed (but unpackaged) file(s) found:
 +
  DEBUG: BUILDSTDERR:    /usr/share/doc/miau/examples/miaurc
 +
При этом в пакете было:
 +
  %doc AUTHORS ChangeLog README TODO misc/miaurc
 +
Файл examples/miaurc не прописан ни в %files, ни в %doc, а rpm5 игнорировал такую недоработку спека.
  
<pre>
+
Другой пример:
...
+
  # (cg) Copy the whole contrib dir as docs. It contains useful scripts.
%post
+
  mkdir -p %{buildroot}%{_datadir}/doc/git-core
%update_scrollkeeper
+
  cp -ar contrib %{buildroot}%{_datadir}/doc/git-core
 +
Это рассчитано на поведение rpm5, для rpm4 так делать не нужно.
 +
* rpm5 позволял написать: "%package -n %{name}", а rpm4 выдает ошибку:
 +
  BUILDSTDERR: error: line 133: %package -n ipa-client47: package ipa-client47 already exists
 +
Это логично, потому что %package, грубо говоря, используется для подпакетов, а пакет с именем %name уже и так автоматически задан. [https://abf.io/import/ipa-client47/commit/ac6f9e967687fa0aafe72c2b573ccef2cd9fab3f Пример] исправления.
 +
* в RPM4 в макрос %configure входит:
  
%postun
+
  find . -name config.guess -o -name config.sub | while read i ; do
%clean_scrollkeeper
+
          [ -f /usr/share/libtool/config/"$(basename "$i")" ] && /bin/rm -f "$i" && /bin/cp -fv /usr/share/libtool/config/"$(basename "$i")" "$i" ;
</pre>
+
  done ;
 +
  if [ -e configure.ac -a -e Makefile.am ]; then
 +
    find . -name configure.ac |xargs dirname |while read D; do
 +
      pushd $D;
 +
      if grep -qE '(LT_INIT|LIBTOOL)' configure.ac >/dev/null; then
 +
        libtoolize --force ;
 +
      fi ;
 +
      aclocal $((find . -name "*.m4" 2>/dev/null |grep -vE 'ac(local|include).m4' | xargs dirname) | grep -v '^.$' |sort |uniq |cut -d/ -f2- |while read R; do [ -e $R/configure.ac ] || echo -n "-I$R "; done) ;
 +
      automake -a --foreign ;
 +
      autoconf ;
 +
      popd ;
 +
    done ;
 +
  fi ;
  
= Interaction with urpmi and rpmdrake =
+
Этого не было и нет в %configure(2_5x) в RPM 5, но представляется полезным действием для актуализации сборочных скриптов тарболлов, что особенно важно при сборке на не-x86. Это может потребовать добавления новых BuildRequires, например, gettext-devel.
  
Sometimes it's necessary to warn the user about some particular care that should be taken when upgrading or installing a specific version of a package. {{pkg|rpmdrake-2.1.3-11mdk}} and above supports this: it searches in rpms for text files named {{file|README.install.urpmi}}, {{file|README.update.urpmi}} or {{file|README.urpmi}}, and displays them.
+
Если это пересоздание configure нужно отключить (например, при сборке пакетов libtool и autoconf, где такое действие вызывает как бы циклическую зависимость от самих себя), то:
 +
  %define _disable_rebuild_configure 1
  
{{file|README.install.urpmi}} is displayed only for installed packages; {{file|README.update.urpmi}} only for upgraded packages; {{file|README.urpmi}} is displayed in both cases.
+
* %exclude работает по-разному: в rpm, если в списке файлов (%files) есть %exclude, то он применяется, чтобы какой-то из файлов, попадающий в перечисленные файлы, не включать в этот список, например: есть файлы file.php, file.sh, file.c, а вы пишите:
 +
  %files
 +
  file.*
 +
  %exclude file.php
 +
Тогда в пакет попадут file.c и file.sh, а file.php не попадет. Но, если вы его вручную не удалите и не положите ни в один пакет, rpm5 выдаст ошибку о неупакованном файле, а rpm4 не выдаст и сам удалит этот файл. Изменение поведения rpm4 обсуждается [https://github.com/rpm-software-management/rpm/issues/994 здесь].
  
= Группы пакетов ROSA =
+
* rpm5 позволял не иметь %description в пакете, rpm4 не позволяет, [https://abf.io/import/samba/commit/63261f0c07f30f705f78176c2b26a4fc8f996116 пример]
  
Каждый пакет должен относиться к одной из [[Packaging_group|групп RPM]], используемых в ROSA.
+
* rpm4 в явном виде пытается раскрыть (expand) макросы в закомментирвоанных строках и при необходимости выдает ошибку. Например, была строка:
 +
  # todo - use native %systemd_post
 +
Была выдана ошибка:
 +
  $ rpmspec --parse --trace kdebase4-workspace.spec
 +
  <...>
 +
    1>  %post^-n kdm
 +
    1>  %systemd_post^
 +
    2>    %{expand:%%{?__systemd_someargs_%#}}^
 +
    3>      %#^
 +
    3>      %{?__systemd_someargs_0}^
 +
    4>        %{error:This macro requires some arguments}^
 +
    1>  %{?_color_output}^{!?_color_output:auto}
 +
    1>  %{!?_color_output:auto}^
 +
  error: This macro requires some arguments
 +
[https://abf.io/import/kdebase4-workspace/commit/397dd8cbff897bbf65360da2ec7a90afb20e4996 Решение]: превратить "%systemd_post" в "%%systemd_post"
  
= Лицензии =
+
* генератор зависимостей и провайдов Perl в RPM 4 "смотрит глубже". Например, в пакете autoconf2.1 на строку
 +
  require "find.pl";
 +
была выставлена зависимость:
 +
  Requires: perl(find.pl)
 +
Но ни один пакет такое не провайдит. RPM 5 такую зависимость не выставлял. [https://abf.io/import/autoconf2.1/commit/8ba0e8375bca02dc3cef22ee2e0417a600c1718b Решилось] патчем, который заменил "require "find.pl";" на "use File::Find qw(find);".
  
По вопросам, относящимся к лицензиям ПО, собираемого в пакеты, обращайтесь к [[Licensing policy]].
+
* байтовая компиляция в Python: теперь для каждого файла *.py создаются скомпилированные  *.pyc и *.pyo. Если их не создавать, то они будут создаваться при первом запуске ПО, пусть лучше поставляются уже скомпилированными в пакете. Для этого в списке файлов "*.py" заменить на "*.py*". При необходимости сборка *.pyc и *.pyo отключается так:
 +
  %define _python_bytecompile_build 0
  
= Alternative: checkinstall =
+
* Перевод дополнительных макросов в пакетах на установку через %install_macro:
 +
В RPM 4 и 5 используются разные места для размещения дополнительных макросов, но, что самое главное, отличаются имена файлов с макросами: в RPM 5 это *.macros, а в RPM 4 — macros.*. В связис  этим был придуман макрос '''%install_macro''', который создает универсальный метод установки макросов и в rpm4, и в rpm5. Макрос был добавлен [https://abf.io/import/rpm/blob/rosa2019.1/0001-Add-macro-to-install-files-with-macros.patch в rpm4] и [https://abf.io/soft/rpm5/commit/3d193c2fd90721f63c9fc3e3183c61822a858e75 в rpm5]. [https://abf.io/import/ninja/commit/154c4316aa881dc5074e747a9c728724374a38e8 Пример]:
 +
  %install_macro ninja %{SOURCE2}
 +
устанавливает файл %{SOURCE2} в папку с макросами, на rpm4 называя файл macros.ninja, а на rpm5 — ninja.macros. В список файлов пакета (%files) пишем:
 +
  %{_rpmmacrodir}/*%{name}*
 +
Под "*%{name}*" попадают и "%{name}.macros", и "macros.%{name}", что позволяет использовать один и тот же спек для сборки и на rpm4, и на rpm5, не делая if/else.
  
A very easy way to build RPMs for personal use is to install the checkinstall package; compile from source as usual (./configure && make && sudo make install), but just replace the {{cmd|make install}} step by {{cmd|checkinstall}}. This automates building an RPM, and is very simple to use. The advantage is that you don't ever have to bypass the package manager when compiling from source. (However, it's probably A Good Idea to build RPMs "properly" as described above, if you intend to distribute them to others.)
+
Примеры перевода пакетов на новую схему установки макросов: [https://abf.io/import/meson/commit/919dffa717e12244f920a4dddde8a314174d06e8 meson], [https://abf.io/import/ninja/commit/154c4316aa881dc5074e747a9c728724374a38e8 ninja], [https://abf.io/import/python/commit/0d2d59cce64562222a7d28f4511db7a57f0ccd8a python2], [https://abf.io/import/python3/commit/b89610d921684a301ac190decf412f7d3e4fb31f python3], [https://abf.io/import/qt5-macros/commit/483f7933638b2e6a743502ca1e3f7183db91457d qt5-macros], [https://abf.io/import/waf/commit/b5db950a83f71d9e46805a33524302e7f16cb92d waf], [https://abf.io/import/firefox/commit/e045d12c848b1632667f53062169230152e9ffa8 firefox]
  
= Некоторые ссылки =
+
* В rpm4 нет %track. Это была такая особая секция спека rpm5, аналог watch-файла в debian, для автоматизации отслеживания новых релизов. Но почти нигде не использовалась. [https://abf.io/import/cmocka/commit/6b9cbc7106a6d3053ec1009373710ec1e3873de5 Пример] удаления %track из спека.
  
== RPM ==
+
* Большинство %*trans* несовместимы в rpm5 и rpm4, в [https://abf.io/import/systemd/tree/rosa2019.1 systemd] я сделал так:
 +
  %if 0%{?rpm4}
 +
  # rpm4 filetriggers
 +
  %include %{SOURCE23}
 +
  %else
 +
  %if 0%{?rpm5}
 +
  # rpm5 filetriggers
 +
  %include %{SOURCE24}
 +
  %else
 +
  %{error:No file triggers have been included!}
 +
  %endif
 +
  %endif
 +
где [https://abf.io/import/systemd/blob/rosa2019.1/triggers.rpm4 %{SOURCE23}] и [https://abf.io/import/systemd/blob/rosa2019.1/triggers.rpm5 %{SOURCE24}] — файлы, которые будут включены в спек, как если бы были его частью.
  
* [http://www.ibm.com/developerworks/linux/library/l-rpm1/index.html Статья IBM по сборке rpm]
+
* Добавлен генератор OrderWithRequires
*  [http://www.redhat.com/magazine/002dec04/features/betterliving-part2/ Статья из журнала redhat по сборке rpm]
+
*  [http://www.gurulabs.com/GURULABS-RPM-LAB/GURULABS-RPM-GUIDE-v1.0.PDF Учебное пособие в формате Pdf, созданное  GuruLabs, по сборке rpm]
+
*  [http://fedora.redhat.com/docs/drafts/rpm-guide-en/ Руководство RPM Red Hat]
+
*  [http://wiki.centos.org/HowTos/SetupRpmBuildEnvironment CentOS how to setup RPM Build Environment]
+
  
== Использование diff и patch ==
+
Генератор: https://abf.io/import/order-rpm-generators
  
* [http://www.ylsoftware.com/news/243 Использование diff и patch]
+
Патч RPM, добавляющий нужный для его работа функционал: https://github.com/rpm-software-management/rpm/pull/1257
  
[[Категория:Управление пакетами]]
+
Во все пакеты добавляет: "OrderWithRequires: setup filesystem basesystem-minimal" + systemd при наличии файлов
[[Категория:Packaging Guidelines]]
+
  '/(usr/lib|lib|etc)/(systemd|sysusers.d|tmpfiles.d)/.*$'
[[Категория:Инструменты_разработки]]
+
и chkconfig при наличии файлов
 +
'/etc/(rc\..*|init\.d)/.*$'.
 +
OrderWithRequires делает что-то приблизительно эквивалентное Requires(pre) (или без pre?), но только если указанный пакет существует в транзакции иными путями.
  
[[en:Packaging_HowTo]]
+
Этот генератор позволяет выправить порядок установки пакетов в больших транзакциях типа сборки образа с 3,5к пакетов, где иначе часть пакетов с сервисами или конфигами systemd, systemd-sysusers, systemd-tmpfiles ставятся, когда сам systemd еще не существует, из-за чего образ или чрут получается корявым.

Текущая версия на 11:48, 12 октября 2021

Начиная с rosa2021.1, дистрибутив ROSA Fresh переходит с пакетных менеджеров RPM 5 и urpmi на RPM 4 и DNF. Эта статья описывает основные отличия для пользователей и сборщиков пакетов.

Откуда куда переход

Более восьми лет в дистрибутивах ROSA Desktop использовался пакетный менеджер RPM5 - форк RPM4, созданный Джеффом Джонсоном. Долгое время RPM5 развивался гораздо активнее своего родителя, что и обсуловило его выбор для РОСЫ. Однако постепенно активность по разработке RPM5 угасла, а RPM4 наоборот - возродился и постепенно не только вобрал большинство интересных свойств RPM5, но и получил множество новых. В настоящее время сайт http://rpm5.org уже недоступен, а ROSA Fresh переходит обратно на RPM 4.

Было:

  • низкоуровневая система управления пакетами RPM 5.4.10 (с более чем сотней патчей, специфичных для РОСЫ)
  • высокоуровневый пакетный менеджер urpmi
  • mock-urpm

Стало:

  • низкоуровневая система управления пакетами RPM 4.15.1 4.17.0
  • высокоуровневый пакетный менеджер DNF
  • исчез RPM-тег DistEpoch (не путать с Epoch), но появился DistTag
  • вместо mock-urpm используется оригинальный mock
  • наиболее часто используемые в командах urpmi и urpme функции преобразовываются в команды dnf (dnf-URPM)
  • будет работающий PackageKit, на основе которого планируется графический "Магазин приложений"

Затронутые платформы: rosa2021.1 (в будущем релизы ROSA >= 12) и новее, в старых (rosa2012.1, rosa2012lts, rosa2014.1, rosa2016.1, rosa2019.0) пакетная система не меняется.

Про этот переход было рассказано на конференции OSDAY-2020, ознакомиться с выступлением и слайдами презентации можно здесь: https://nixtux.ru/1052

Причины для перехода

  • ни RPM 5, ни urpmi более не разрабатываются, ROSA и PLD остались единственными их использующими дистрибутивами, причем PLD уже более года прорабатывает переход на rpm4; в мире Linux нецелесообразно пытаться малыми силами тащить такую важную инфраструктурную вещь, как пакетная система
  • в RPM 5 в свое время были важные функции, которых не было в RPM 4, но теперь ситуация изменилась в обратную сторону
  • апстрим RPM 4 в последнее время очень живой, RPM 4 активно развивается
  • неудовлетворительное качество кода RPM 5 в РОСЕ, в котором так и осталось более сотни "костылей" со времен спешного перехода Mandriva на RPM 5 и много недоделанного функционала. Поддержка усложняется тем, что внутри кода RPM 5 содержатся копии многих сторонних проектов и отвечающий за что-то одно код размазан по огромному количеству файлов (например, см. коммит 5bf4d7: банально идентификаторы алгоритмов хеширования пришлось добавить в большое количество файлов)
  • urpmi, конечно, немного жалко, но желающих в одиночку тянуть urpmi и perl-URPM не нашлось, а какого-либо критически важного функционала, отсутствующего в DNF, в urpmi нет
  • нет качественных биндингов urpmi<->PackageKit, а их разработка и поддержка займет большое количество времени, которое можно потратить на другие вещи, и не очень целесообразна, поскольку есть много нюансов; если делать их только самим, то качество получится низким

Общий план перехода

(возможны изменения, то, что еще не сделано, является приблизительным видением дальнейшей работы)

  • (СДЕЛАНО) собрать стек rpm4 с временными хаками, чтобы можно было использовать ранее собранные rpm5 пакеты *.rpm, например, игнорируя отсутствующую в стеке rpm4 %DISTEPOCH
  • (СДЕЛАНО) обеспечить совместимость нового rpm4 с максимально возможным количеством старых макросов
  • (СДЕЛАНО) автоматизированно внести массовые изменения в спеки (*.spec) так, чтобы они стали совместимы с RPM 4: меняются как места, которые строго необходимо заменить, так и те, где старый и продолжающий работать макрос меняется на его новый вариант
  • (СДЕЛАНО) обеспечить совместимость старого rpm5 с измененными спеками, чтобы можно было из одного спека собирать пакеты и для rpm5 в платформах rosa2016.1 и rosa2019.0 и для rpm4 в платформе rosa2019.1
  • (СДЕЛАНО) научить abf-console-client работать с RPM 4 (теперь апстрим общий с OpenMandriva — https://github.com/OpenMandrivaSoftware/abf-console-client, а старый клиент из ROSA на python2 — https://abf.io/soft/abf-console-client — остается только для RPM5)
  • (В ПРОЦЕССЕ) провести массовую пересборку пакетов main и contrib, выявив и исправив типовые проблемы (например, уже запатчен find-lang.sh из rpm4)
  • (СДЕЛАНО) ранее применявшимся в OpenMandriva скриптом автоматического обновления пакетов, где это возможно, обновить пакеты
  • (СДЕЛАНО)привести файловые триггеры RPM 5 и %trigger* к файловым триггерам RPM 4 (возможно, замапить новые %trigger* в старые для переиспользования спеков rpm4 в rpm5...). Пример переделывание триггеров.
  • (СДЕЛАНО) обновить и починить gdb (gdb-add-index теперь используется в rpm, а gdb сейчас сломан из-за несовместимости с Python 3.8)
  • (СДЕЛАНО, но не заапстримлено) портировать генератор зависимостей QML и желательно заапстримить его
  • (СДЕЛАНО) сделать генератор devel() или использовать от Mageia в составе rpm-openmandriva-setup; сделан свой
  • (СДЕЛАНО) починить не собирающиеся пакеты, возможно, снова обновив glibc и gcc
  • либо отвязать drakxtools от perl-URPM (или перейти на manatools, как минимум настройку часов оттуда точно нужно взять, т.к. она умеет не только в ntpd, а еще и в chrony и systemd-timesyncd, а это важно), либо придется оставить urpmi в качестве существующего параллельно с DNF пакетного менеджера, как в Mageia
  • если будет решено оставить urpmi и perl-URPM, то, во-первых, взять их версии из Mageia (они умеют работать c rpm4), во-вторых, перенести /usr/{sbin,bin}/{urpmi,urpme} куда-нибудь в /usr/lib/, а в (s)bin отставить dnf-URPM
  • (СДЕЛАНО) после обновления perl-URPM до версии из Mageia или его убирания обновить perl
  • если получится избавиться от urpmi, наверняка стоит избавиться от префикса lib64 в названии пакетов, который существует из-за неумения urpmi отличать пакеты с одинаковым названием, но одинаковой архитектурой (но вопрос требует тщательного обдумывания, в т.ч. — не пострадает ли wine)
  • (СДЕЛАНО) переработать пакет rosa-repos: вынести main, contrib, non-free и т.д. в отдельные подпакеты
  • (СДЕЛАНО) собрать и обеспечить работу GUI для управления пакетами dnfdranoga
  • сделать генерацию метаданных appstream из всего репозитория
  • во все пакеты автоматически добавлять метаданные /usr/share/metainfo/*.xml, чтобы в графических "магазинах приложений" были все пакеты, а не только лишь те, в которых есть /usr/share/metainfo/*.xml; возможно, скрыть системные пакеты, имена которых начинаются на lib; для пакетов с бинарными модулями ядра сделать так, чтобы только -latest мета-пакеты были в метаданных и при этом были с красивым понятным описанием
  • обновить весь стек GNOME и затем обеспечить работу gnome-software
  • поскольку в drmdrake был GUI для управления репозиториями, а в dnfdranoga его нет, в пакеты rosa-repos-* добавить метаданные с описанием назначения этих репозиториев и с его переводом на русский язык; в магазинах приложений сделать отдельную категорию пакетов "Репозитории ROSA"; это позволит включать и отключать репозитории одной кнопкой "Установить"/"Удалить" пакет, также улучшит централизацию поставки конфигураций репозиториев
  • собрать, обновить и обеспечить работу packagekit
  • обеспечить работу оффлайн-обновлений через packagekit+systemd
  • портировать хеши файлов по ГОСТ Р 34.11-2012 из rpm5 в rpm4 и желательно заапстримить (rpm4 уже переключен на libgcrypt по умолчанию)
  • начать использовать security.ima и интегрировать подписывание в сборочницу, в т.ч. проработать вопрос с ГОСТ
  • придумать, как существующие системы обновить до rosa2021.1 с rpm4 и задокументировать (будут проблемы с конвертированием БД rpm)
  • осуществить полный переезд в /usr
  • (СДЕЛАНО) проработать нюансы, возникшие после смены %_libexecdir = %_libdir на %_libexecdir = /usr/libexec
  • (СДЕЛАНО) сделать что-то с "бекендом" для urpmi в пакете system-config-printer, желательно выкинуть и использовать апстримную интеграцию с PackageKit; а сам system-config-printer отвязать от consolehelper и перейти на апстримную интеграцию с policykit, чтобы работала печать тестовых заданий с авторизацией по тикету Kerberos текущего пользователя
  • ...

Изменения во флагах компилятора (CFLAGS, %optflags) по умолчанию

Части флагов не оказалось после перехода на rpm4, здесь описаны размышления, какие вернуть, а какие нет. Можно переделать.

- убран -fPIC: флаг был в cpu-os-macros.tar.gz, импортированном из Mandriva и не менявшимся, зачем он нужен в %optflags, я не понял, поэтому обратно в RPM4 не добавляю; пришлось в qt4 и qt5-qtbase добавить -fPIC вручную;

-fPIC возвращен; чтобы не было проблем с линковкой разделяемых библиотек, собранных с -fPIC, со статичными библиотеками, собранными без -fPIC, -fPIC возвращен в %optflags по умолчанию

Если необходимо отключить -fPIC для конкретного пакета, то можно сделать так:

 %global _fpic_cflags %{nil}

- убран -ffat-lto-objects: он был в rpm5/macros/mandriva.in, но не ясно, зачем тратить машинное время на компиляцию одновременно вариантов для LTO и нет, когда как LTO не используется в дистрибутиве, не понятно;

- убран -fno-delete-null-pointer-checks: он был тоже в rpm5/macros/mandriva.in, но зачем нужно изменять поведение gcc по умолчанию таким образом, не очень ясно; можно будет вернуть

UPD: этот флаг был вручную восстановлен в пакете webkit в соответствии с рекомендацией от 1С — проприетарной программы, использующей системный libwebkitgtk-3.0 (ALT#36998#c28). Возможно, его стоит вернуть глобально?

Полезные обсуждения по теме: https://news.ycombinator.com/item?id=17360316, https://github.com/RIOT-OS/RIOT/issues/12039

- убран -fvar-tracking-assignments: надобность сомнительная, кому нужно дебажить, может сам собрать ПО, в т.ч. с -O0 вместо -O2, а еще не все компиляторы понимают этот флаг (clang вообще не понимает этот флаг, при его наличии приходится изобретать костыли вроде %clang_gcc_wrapper)

- убран -frecord-gcc-switches: надобность не очень понятна, а clang-у мешает

- было -fstack-protector в rpm5, стало -fstack-protector-strong в rpm4

В rpm5:

 rosa-2016 ~ # rpm --eval %optflags | sed -e 's, ,\n,g' | sed -e 's,^\-,,g' -e 's,^\-,,g' | sort -u
 ffat-lto-objects
 fno-delete-null-pointer-checks
 fPIC
 frecord-gcc-switches
 fstack-protector
 fvar-tracking-assignments
 gdwarf-4
 O2
 param=ssp-buffer-size=4
 pipe
 Wa,--compress-debug-sections
 Werror=format-security
 Wformat
 Wp,-D_FORTIFY_SOURCE=2
 Wstrict-aliasing=2

В rpm4:

 bash-4.4# rpm --eval %optflags | sed -e 's, ,\n,g' | sed -e 's,^\-,,g' -e 's,^\-,,g' | sort -u
 D_FORTIFY_SOURCE=2
 O2
 Werror=format-security
 Wformat
 Wstrict-aliasing=2
 fomit-frame-pointer
 fPIC
 fstack-protector-strong
 gdwarf-4
 m64
 mtune=generic
 param=ssp-buffer-size=4
 pipe
 RPM5				RPM4
 				
 		Есть в RPM5	
 ffat-lto-objects		-
 fno-delete-null-pointer-checks	-
 frecord-gcc-switches		-
 fvar-tracking-assignments	-
 Wa,--compress-debug-sections	-
 				
 		Есть в RPM4	
 -				fomit-frame-pointer
 -				m64
 -				mtune=generic
 				
 		Общее		
 fstack-protector		fstack-protector-strong
 fPIC				fPIC
 gdwarf-4			gdwarf-4
 O2				O2
 param=ssp-buffer-size=4	param=ssp-buffer-size=4
 pipe				pipe
 Werror=format-security	Werror=format-security
 Wformat			Wformat
 Wp,-D_FORTIFY_SOURCE=2	D_FORTIFY_SOURCE=2
 Wstrict-aliasing=2		Wstrict-aliasing=2


Особенности перевода спеков на RPM 4

Скрипт rpm5-to-rpm4.sh, который автоматически вносит правки в спеки, здесь: https://gitlab.com/abf-mirror/abf-mirror-scripts

Если вы видите коммиты от "NixTux Commit Bot" с текстом: "bot: rpm5 -> rpm4 (N)", — где N — номер итерации прохода скрипта по всем пакетам в abf.io/import/, то это коммиты, сделанные этим скриптом. Каковы были изменения в скрипте между итерациями, можно посмотреть в git по ссылке выше.

  • Появились макросы:
 Макрос     Значение в rpm4     Значение в rpm5
 %rpm4      1                   0
 %rpm5      0                   1
 %_rpm      4                   5
  • Если нет иного выхода адаптировать спек под разные версии rpm, то можно сделать if/else:
 %if %rpm4
 < вариант для rpm4 >
 %else
 < вариант для rpm5 >
 %endif

Если хочется заморочиться и сделать так, чтобы была ошибка сборки, если ни один из вариантов %if не сработал, то можно написать так:

 %if 0%{?rpm4}
 < вариант для rpm4 >
 %else
 %if 0%{?rpm5}
 < вариант для rpm5 >
 %else
 %{error:Error!}
 %endif
 %endif

Эта конструкция применит "< вариант для rpm4 >", если макрос %rpm4 задан и равен 1, "< вариант для rpm5 >", если макрос %rpm5 задан и равен 1, а если ни один из двух вариантов не подошел, то сборка упадет с ошибкой с текстом "Error!". Лучше избегать таких сложных конструкций!

  • уменьшено количество пакетов в базовой сборочной системе, так, basesystem-build больше не зависит от initscripts, gpg и др. (см. коммиты), а из-за отсутствия initscripts больше нет, например, procps-ng с командой ps; минимизация сборочной системы — это скорее хорошо, чем плохо, т.к. ускоряет сборку, а мейнтейнер пакета будет вынужден лучше понимать, как происходит его сборка; при необходимости "потерянные" зависимости добавьте в BuildRequires вручную, пример."BuildRequires: /usr/bin/python2"

По причине отсутствия пакетов python / python3 в базовой системе в BuildRequires не работают макросы %python* из этих пакетов. Однако пакет python3 подтягивается через cmake-rpm-generators.

Больше нет krb5-devel, поэтому в некоторых пакетах нужно прописать: "BuildRequires: pkgconfig(krb5" или "BuildRequires: pkgconfig(krb5-gssapi)", в некоторых пакетах с дурацкими сборочными скриптами, которые полагаются на автоматику и в которых нельзя в явном виде включить или выключить GSSAPI, например, в curl, рекомендуется добавить проверку по образцу:

 %check
 readelf -a %{buildroot}%{_libdir}/libcurl.so | grep NEEDED | grep -q libgssapi
  • из базовой сборочной системы убран /usr/bin/python, делайте "BuildRequires: /usr/bin/python" или "BuildRequires: /usr/bin/python2" или "BuildRequires: /usr/bin/python3" при необходимости; обратите внимание, что python3-devel, он же pkgconfig(python3) и аналогично python-devel/pkgconfig(python) не подтягивают /usr/bin/python(3). Характерная ошибка:
 BUILDSTDERR: sh: /usr/bin/python: No such file or directory

В настоящий момент /usr/bin/python — это python2.

  • Suggests и Requires(missingok) теперь Recommends: в RPM 5 были только Suggests и Requires(missingok) (а Suggests был алиасом Requires(missingok), а в RPM 4 есть и то, и то, но Recommends работает так, как работал Suggests, а Suggests используется для иных вещей, поэтому заменяем "Suggests:" на "Recommends:", а чтобы такие спеки продолжали работать в RPM 5, мы научили его понимать Suggests: теперь он считает и Suggests, и Recommends одинаково эквивалентными "Requires(missingok)"
  • Фильтры для автоматического генератора зависимостей (requires) и провайдов (provides) поменялись следующим образом, ниже сначала вариант RPM 4 (новый), затем RPM 5 (старый):
 %__requires_exclude -> %__noautoreq
 %__provides_exclude -> %__noautoprov
 %__requires_exclude_from -> %__noautoreqfiles
 %__provides_exclude_from -> %__noautoprovfiles

Нет возможности легко научить RPM 4 понимать %__noautoreq, %__noautoprov, %__noautoreqfiles и %__noautoprovfiles, но есть возможность легко научить RPM 5 понимать оба варианта, что мы и сделали. Теперь, если в спеке указаны одновременно старый макрос и эквивалентный ему новый макрос, например:

 %define __noautoreq 'libGL.*'
 %global __requires_exclude 'libGL.*'

...то rpm5 будет брать только значение старого (__noautoreq) и игнорировать новый (__requires_exclude). Если же указан только новый (__requires_exclude), то будет браться его значение. В большинстве случаев достаточно использовать только новый вариант от RPM 4, т.е. только

 %global __requires_exclude libGL.*

...но, если вдруг понадобится задать разные правила для RPM 5 и RPM 4, то укажите оба варианта, тогда RPM 5 возьмет только свой прежний вариант, а RPM 4 только свой. Обратите внимание, что RPM 4 не понимает старые варианты от RPM 5, поэтому для RPM 4 обязательно указать __requires_exclude, а не __noautoreq. %global и %define здесь примерно одно и то же и для RPM 4, и для RPM 5, но документация от разработчиков RPM 4 рекомендует использовать %global, когда как в rpm5 более предпочтительно было %define.

rpm4 не понимает значения %__requires_exclude(_from)/%__provides_exclude(_from) в кавычках. Кавычки нужно убрать.

Про варианты от RPM 4 читайте здесь.

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

  • В пакете rpm-openmandriva-setup собраны макросы, которые существовали в RPM 5 и которых теперь нет в RPM 4, чтобы они продолжали работать в ROSA. Какие-то макросы просто скопированы, какие-то преобразовываются в их новые варианты. Также мы добавили некоторые широко распространенные новые макросы от rpm4 в rpm5, чтобы после их замены в спеках описанным выше скриптом спеки продолжали работать для rosa2016.1 и rosa2019.0 без изменений.

Типовые замены макросов:

 %configure2_5x -> %configure
 %_sys_macros_dir -> %_rpmmacrodir
 %_rpmhome -> %_rpmconfigdir

Возможные, но нерекомендуемые замены:

 %make -> %make_build
 %makeinstall_std -> %make_install
 %setup_compile_flags -> %set_build_flags
 %ldflags -> %build_ldflags

Также появились %build_cflags (CFLAGS, флаги компилятора Си), %build_cxxflags (CXXFLAGS, флаги компилятора Cи++), %build_fflags (FFLAGS, флаги компилятора Фортран); в rpm5 они сделаны эквивалентными %optflags; %optflags продолжает существовать, как и раньше.

Макросы %make_* стали унифицированы с %ninja_*, %meson_* и др., т.е. build означает сборку, install — установку. Возможно изменение политики в отношение макросов.

  • rpm5 с описанными выше изменениями уже опубликован в rosa2019.0 и rosa2016.1
  • rpm4 не позволяет закомментировать %define:
 #%define xxx yyy

не будет работать, нужно заменить "#%define" на "#define"

  • в rpm4 не поддерживаются стадии BuildRequires, т.е. записи BuildRequires(check), BuildRequires(pre) заменяем на BuildRequires; потеря не велика, это использовалось очень редко и, как оказалось, во всем репозитории только одним из авторов этой статьи, при чем там, где без этого можно обойтись, просто для пущей красоты было
  •  %_libexecdir теперь не /usr/lib(64), а /usr/libexec
  • в RPM 5 директории %_bindir, %_libdir и др. наследовали значение %_prefix, в rpm4 не наследуют, пример правок в пакете libressl (мы думаем над тем, как решить эту проблему, чтобы снова наследовалось значение %_prefix)
  • в RPM 4 есть такой макрос:
 %__pkgconfig_path    ^((%{_libdir}|%{_datadir})/pkgconfig/.*\.pc|%{_bindir}/pkg-config)$

Если значение %_libdir переназначено, то файлы *.pc для создания Requires и Provides скриптом scripts/pkgconfigdeps.sh будут искаться, возможно, не там, где вы хотите

Пример решения (переназначим этот макрос, указав нужные пути):

 %global __pkgconfig_path ^(%{_olibdir}/pkgconfig/.*\\.pc|%{_obindir}/pkg-config)$

В RPM 5 такого макроса нет, поэтому этот %global/%define ему безразличен.

  • в RPM нельзя поставить %attr() на символическую ссылку, RPM 5 игнорировал такое, а RPM 4 выдает ошибку в явном виде, пример:
 Explicit %attr() mode not applicable to symlink: /builddir/build/BUILDROOT/log4cpp-1.0-6.i386/usr/lib/liblog4cpp.so

Исправление — убрать лишний %attr

  • в сборочнице теперь отключен доступ в сеть, часть пакетов не собирается с ошибкой вида:
 BUILDSTDERR: error: Bad source: /builddir/build/SOURCES/mds-2.4.2.2.tar.gz: No such file or directory

В таких случаях нужно вручную или с помощью "abf put" закачать исходники пакета на ABF. Раз такие пакеты собирались ранее, значит в них достаточно автоматизированно сделать "abf put" и закоммитить, но для этого нужно составить список таких пакетов

  • rpm5 съедал все содержимое папки с %doc, даже если туда положить что-то лишнее, а rpm4 требует явного указания всего содержимого папки /usr/share/doc/%name. Пример ошибки:
 DEBUG: BUILDSTDERR: error: Installed (but unpackaged) file(s) found:
 DEBUG: BUILDSTDERR:    /usr/share/doc/miau/examples/miaurc

При этом в пакете было:

 %doc AUTHORS ChangeLog README TODO misc/miaurc

Файл examples/miaurc не прописан ни в %files, ни в %doc, а rpm5 игнорировал такую недоработку спека.

Другой пример:

 # (cg) Copy the whole contrib dir as docs. It contains useful scripts.
 mkdir -p %{buildroot}%{_datadir}/doc/git-core
 cp -ar contrib %{buildroot}%{_datadir}/doc/git-core

Это рассчитано на поведение rpm5, для rpm4 так делать не нужно.

  • rpm5 позволял написать: "%package -n %{name}", а rpm4 выдает ошибку:
 BUILDSTDERR: error: line 133: %package -n ipa-client47: package ipa-client47 already exists

Это логично, потому что %package, грубо говоря, используется для подпакетов, а пакет с именем %name уже и так автоматически задан. Пример исправления.

  • в RPM4 в макрос %configure входит:
 find . -name config.guess -o -name config.sub | while read i ; do 
          [ -f /usr/share/libtool/config/"$(basename "$i")" ] && /bin/rm -f "$i" && /bin/cp -fv /usr/share/libtool/config/"$(basename "$i")" "$i" ; 
 done ; 
 if [ -e configure.ac -a -e Makefile.am ]; then 
   find . -name configure.ac |xargs dirname |while read D; do 
     pushd $D; 
     if grep -qE '(LT_INIT|LIBTOOL)' configure.ac >/dev/null; then 
       libtoolize --force ; 
     fi ; 
     aclocal $((find . -name "*.m4" 2>/dev/null |grep -vE 'ac(local|include).m4' | xargs dirname) | grep -v '^.$' |sort |uniq |cut -d/ -f2- |while read R; do [ -e $R/configure.ac ] || echo -n "-I$R "; done) ; 
     automake -a --foreign ; 
     autoconf ; 
     popd ; 
   done ; 
 fi ;

Этого не было и нет в %configure(2_5x) в RPM 5, но представляется полезным действием для актуализации сборочных скриптов тарболлов, что особенно важно при сборке на не-x86. Это может потребовать добавления новых BuildRequires, например, gettext-devel.

Если это пересоздание configure нужно отключить (например, при сборке пакетов libtool и autoconf, где такое действие вызывает как бы циклическую зависимость от самих себя), то:

 %define _disable_rebuild_configure 1
  •  %exclude работает по-разному: в rpm, если в списке файлов (%files) есть %exclude, то он применяется, чтобы какой-то из файлов, попадающий в перечисленные файлы, не включать в этот список, например: есть файлы file.php, file.sh, file.c, а вы пишите:
 %files
 file.*
 %exclude file.php

Тогда в пакет попадут file.c и file.sh, а file.php не попадет. Но, если вы его вручную не удалите и не положите ни в один пакет, rpm5 выдаст ошибку о неупакованном файле, а rpm4 не выдаст и сам удалит этот файл. Изменение поведения rpm4 обсуждается здесь.

  • rpm5 позволял не иметь %description в пакете, rpm4 не позволяет, пример
  • rpm4 в явном виде пытается раскрыть (expand) макросы в закомментирвоанных строках и при необходимости выдает ошибку. Например, была строка:
 # todo - use native %systemd_post

Была выдана ошибка:

 $ rpmspec --parse --trace kdebase4-workspace.spec
 <...>
   1>   %post^-n kdm
   1>   %systemd_post^
   2>     %{expand:%%{?__systemd_someargs_%#}}^
   3>       %#^
   3>       %{?__systemd_someargs_0}^
   4>         %{error:This macro requires some arguments}^
   1>   %{?_color_output}^{!?_color_output:auto}
   1>   %{!?_color_output:auto}^
 error: This macro requires some arguments

Решение: превратить "%systemd_post" в "%%systemd_post"

  • генератор зависимостей и провайдов Perl в RPM 4 "смотрит глубже". Например, в пакете autoconf2.1 на строку
 require "find.pl";

была выставлена зависимость:

 Requires: perl(find.pl)

Но ни один пакет такое не провайдит. RPM 5 такую зависимость не выставлял. Решилось патчем, который заменил "require "find.pl";" на "use File::Find qw(find);".

  • байтовая компиляция в Python: теперь для каждого файла *.py создаются скомпилированные *.pyc и *.pyo. Если их не создавать, то они будут создаваться при первом запуске ПО, пусть лучше поставляются уже скомпилированными в пакете. Для этого в списке файлов "*.py" заменить на "*.py*". При необходимости сборка *.pyc и *.pyo отключается так:
 %define _python_bytecompile_build 0
  • Перевод дополнительных макросов в пакетах на установку через %install_macro:

В RPM 4 и 5 используются разные места для размещения дополнительных макросов, но, что самое главное, отличаются имена файлов с макросами: в RPM 5 это *.macros, а в RPM 4 — macros.*. В связис этим был придуман макрос %install_macro, который создает универсальный метод установки макросов и в rpm4, и в rpm5. Макрос был добавлен в rpm4 и в rpm5. Пример:

 %install_macro ninja %{SOURCE2}

устанавливает файл %{SOURCE2} в папку с макросами, на rpm4 называя файл macros.ninja, а на rpm5 — ninja.macros. В список файлов пакета (%files) пишем:

 %{_rpmmacrodir}/*%{name}*

Под "*%{name}*" попадают и "%{name}.macros", и "macros.%{name}", что позволяет использовать один и тот же спек для сборки и на rpm4, и на rpm5, не делая if/else.

Примеры перевода пакетов на новую схему установки макросов: meson, ninja, python2, python3, qt5-macros, waf, firefox

  • В rpm4 нет %track. Это была такая особая секция спека rpm5, аналог watch-файла в debian, для автоматизации отслеживания новых релизов. Но почти нигде не использовалась. Пример удаления %track из спека.
  • Большинство %*trans* несовместимы в rpm5 и rpm4, в systemd я сделал так:
 %if 0%{?rpm4}
 # rpm4 filetriggers
 %include %{SOURCE23}
 %else
 %if 0%{?rpm5}
 # rpm5 filetriggers
 %include %{SOURCE24}
 %else
 %{error:No file triggers have been included!}
 %endif
 %endif

где %{SOURCE23} и %{SOURCE24} — файлы, которые будут включены в спек, как если бы были его частью.

  • Добавлен генератор OrderWithRequires

Генератор: https://abf.io/import/order-rpm-generators

Патч RPM, добавляющий нужный для его работа функционал: https://github.com/rpm-software-management/rpm/pull/1257

Во все пакеты добавляет: "OrderWithRequires: setup filesystem basesystem-minimal" + systemd при наличии файлов

 '/(usr/lib|lib|etc)/(systemd|sysusers.d|tmpfiles.d)/.*$'

и chkconfig при наличии файлов

'/etc/(rc\..*|init\.d)/.*$'.

OrderWithRequires делает что-то приблизительно эквивалентное Requires(pre) (или без pre?), но только если указанный пакет существует в транзакции иными путями.

Этот генератор позволяет выправить порядок установки пакетов в больших транзакциях типа сборки образа с 3,5к пакетов, где иначе часть пакетов с сервисами или конфигами systemd, systemd-sysusers, systemd-tmpfiles ставятся, когда сам systemd еще не существует, из-за чего образ или чрут получается корявым.