Переход ROSA с RPM 5 на RPM 4

Материал из Rosalab Wiki
Версия от 10:31, 12 октября 2021; Mikhailnov (обсуждение | вклад)

Это снимок страницы. Он включает старые, но не удалённые версии шаблонов и изображений.
Перейти к: навигация, поиск
Начиная с 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) пакетная система не меняется.

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

  • ни 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 еще не существует, из-за чего образ или чрут получается корявым.