При сборке git-1.5.1 с kernel.org с моим rpm-build (бранч mod) у пакета git-core появился unmet на /usr/bin/emacs. Выяснилось, что новый скрипт /usr/bin/git-mergetool вытаскивает много лишних зависимостей на всякие утилиты типа vimdiff, kdiff3 и до кучи emacs. Наиболее правильным решением тут будет просто отключить поиск зависимостей в /usr/bin/git-mergetool, но образование unmet'а на /usr/bin/emacs требует отедльного рассмотрения. Дело в том, что /usr/bin/emacs никто не предоставляет как зависимость, и файл /usr/bin/emacs тоже не принадлежт ни одному пакету, а висит на альтернативах. В связи с этим новый rpm-build проставляет голую зависимость на /usr/bin/emacs, и я считаю, что это правильно. Проблема тут в том, что maintainer пакета emacs22 забыл добавить в некоторые пакеты Provides: /usr/bin/emacs. Не он один забывает это сделать, напр. /usr/bin/javac тоже висит на альтернативах и никем не прдоставляется. Полагаю, что этим список потенциальных анметов не исчерпывается. Чтобы решить эту проблему, я решил добавить специальный provides метод в пакет alternatives. Он добавляет в provides все альтернативы которые начинаются с /usr/bin/ и /usr/sbin/. Ниже приведены некоторые подробности. Есть ли недостатки у этого подхода? Может образоваться некоторое (небольшое) количество "мусорных" provides, типа /usr/bin/autoconf-default или /usr/bin/i586-alt-linux-gcc. С другой стороны, в принципе предусмотрено отключение любого prov метода. commit 28c294aeb30f638727477724b1f3cf3328855d7e Author: Alexey Tourbin Date: Wed Mar 28 14:58:54 2007 +0400 alternatives.prov: check that alternative target is acutally available $ rpm -qf /etc/alternatives/packages.d/xemacs xemacsen-0.4-alt1 $ cat /etc/alternatives/packages.d/xemacs /usr/bin/xemacs /usr/bin/xemacs-x11 80 /usr/bin/xemacs /usr/bin/xemacs-nox 70 /usr/bin/xemacs /usr/bin/xemacs-mule 60 /usr/bin/xemacs /usr/bin/xemacs-mule-nextaw 50 /usr/bin/xemacs /usr/bin/xemacs-nomule 40 /usr/bin/xemacs /usr/bin/xemacs-nomule-nextaw 30 /usr/bin/xemacs /usr/bin/xemacs-nox-mule 20 /usr/bin/xemacs /usr/bin/xemacs-nox-nomule 10 $ ls /usr/bin/xemacs* zsh: no matches found: /usr/bin/xemacs* $ In this case, we should NOT provide /usr/bin/xemacs. diff --git a/alternatives/alternatives.prov b/alternatives/alternatives.prov index e7e7e58..ccba5d5 100755 --- a/alternatives/alternatives.prov +++ b/alternatives/alternatives.prov @@ -5,7 +5,18 @@ AlternativesProv() { local f="$1"; shift - awk '$1 ~ /^\/usr\/s?bin\// {print $1}' "$f" + local link bin rest + while read -r link bin rest; do + case "${link-}" in + /usr/bin/*|/usr/sbin/*) + ;; + *) + continue ;; + esac + if [ -x "${RPM_BUILD_ROOT-}$bin" ]; then + echo "$link" + fi + done <"$f" } ArgvFileAction AlternativesProv "$@" commit e51b5a69a2f3a2bc92abc16462e3137366ce995e Author: Alexey Tourbin Date: Wed Mar 28 14:23:42 2007 +0400 added alternatives.prov and alternatives.prov.files, for new rpm-build /usr/bin/emacs is not provided by any package: $ rpm -q --whatprovides /usr/bin/emacs warning: no package provides /usr/bin/emacs $ Now consider shell script which invokes emacs. Depending on /usr/lib/rpm/find-package peculiarities, there are two possible outcomes: 1) dependency on emacs is lost; 2) /usr/bin/emacs unmet dependency is generated. I think that both variants are not quite acceptable. Note that the root of the problem is that /usr/bin/emacs is not provided by any package. Also note that /usr/bin/emacs is really an alternative: $ ls -l /usr/bin/emacs lrwxrwxrwx 1 root root 38 Jul 5 2006 /usr/bin/emacs -> /etc/alternatives/links/|usr|bin|emacs $ The idea is that we can process the alternatives/packages.d/ file and automatically provide paths under /usr/bin and /usr/sbin. $ grep /usr/bin/ /etc/alternatives/packages.d/emacs22-nox /usr/bin/emacs22 /usr/bin/emacs22-nox 10 /usr/bin/emacs /usr/bin/emacs22-nox 10 $ alternatives/alternatives.prov /etc/alternatives/packages.d/emacs22-nox /usr/bin/emacs22 /usr/bin/emacs $ Also note that there are a few other similar cases: $ rpm -q --whatprovides /usr/bin/javac warning: no package provides /usr/bin/javac $ rpm -q --whatprovides `realpath /usr/bin/javac` j2se1.5-sun-devel-1.5.0_11-alt1 $ diff --git a/alternatives.spec b/alternatives.spec index ef2f759..327de0d 100644 --- a/alternatives.spec +++ b/alternatives.spec @@ -62,6 +62,9 @@ cat >$RPM_BUILD_ROOT%_sysconfdir/rpm/macros.d/%name</dev/null ||: %_sbindir/* %_datadir/%name %_man1dir/* +%_rpmlibdir/alternatives.prov +%_rpmlibdir/alternatives.prov.files %changelog * Thu Feb 01 2007 Stanislav Ievlev 0.3-alt1 diff --git a/alternatives/alternatives.prov b/alternatives/alternatives.prov new file mode 100755 index 0000000..e7e7e58 --- /dev/null +++ b/alternatives/alternatives.prov @@ -0,0 +1,11 @@ +#!/bin/sh -efu + +. /usr/lib/rpm/functions + +AlternativesProv() +{ + local f="$1"; shift + awk '$1 ~ /^\/usr\/s?bin\// {print $1}' "$f" +} + +ArgvFileAction AlternativesProv "$@" diff --git a/alternatives/alternatives.prov.files b/alternatives/alternatives.prov.files new file mode 100755 index 0000000..7b98b83 --- /dev/null +++ b/alternatives/alternatives.prov.files @@ -0,0 +1,5 @@ +#!/bin/sh -efu +while IFS=$'\t' read -r f t; do + [ -z "${f##${RPM_BUILD_ROOT-}/etc/alternatives/packages.d/*}" ] && + [ -z "${t##* text*}" ] && echo "$f" ||: +done