On Wed, Aug 30, 2006 at 08:43:52PM +0400, Dmitry V. Levin wrote: > > Тогда повторю вопрос. > > > > 145 "$PACKAGEOF" -f "$WORKDIR/files" >"$WORKDIR/packages" > > 146 sort -u -o "$WORKDIR/packages" "$WORKDIR/packages" > > packages - это список имён пакетов, которые использовались для сборки > посредством files. > > > 148 cat "$WORKDIR/packages" | > > 149 xargs -r rpmquery --qf '[%{REQUIRENAME}\n]' -- | > > 150 sort -u >"$WORKDIR/reqs" > > reqs - это все requires пакетов packages. > > > 152 cat "$WORKDIR/packages" | > > 153 xargs -r rpmquery --qf '[%{PROVIDENAME}\t%{NAME}\n]' -- | > > 154 sort -k2,2 -k1,1 -u >"$WORKDIR/provs" > > provs - это всё provides пакетов packages в виде пар > "ProvideName PackageName". > > > 156 comm -23 "$WORKDIR/packages" "$WORKDIR/reqs" >"$WORKDIR/package-reqs" > > package-reqs - это пакеты packages за вычетом тех, имена которых совпали с > requires пакетов packages. В частности, эта операция выкидывает простые > циклы целиком. > > > 158 join -1 1 -2 2 -o 1.1 "$WORKDIR/reqs" "$WORKDIR/provs" | > > 159 sort -u >"$WORKDIR/reqs_provs" > > reqs_provs - это те requires пакетов packages, которые есть среди provides > пакетов packages. Здесь было бы логичнее соединять по первому полю provs и на выходе получать второе поле provs. Тогда reqs_provs -- это те из пакетов packages, в которые удается разрешить какие-либо зависимости пакетов packages. При этом более осмысленной становится следующая операция. > > 160 comm -23 "$WORKDIR/package-reqs" "$WORKDIR/reqs_provs" \ > > 161 >"$WORKDIR/package-reqs-provs" > > package-reqs-provs - это пакеты package-reqs за вычетом тех, имена которых > совпали с requires, перечисленными в reqs_provs. В частности, эта > операция выкидывает все циклы полностью. Из списка пакетов packages-reqs логичнее вычитать не виртуальные зависимости по первой колонке provs, а названия пакетов по второй колонке provs. Тогда package-reqs-provs -- это пакеты package-reqs за вычетом тех, которые предоставляют какие-либо зависимости для пакетов packages. Разве так не логичнее? Это либо очевидная ошибка, либо осторожный в каком-то смысле алгоритм (в каком именно я пока не понимаю). > > join в строке 158 делает нечто отличное: ты соединяешь > > reqs<ВиртуальнаяЗависимость> на provs<ИмяПакета>, а на выходе хочешь > > получить provs<ВиртуальнаяЗависимость>. Это выглядит подозрительно, > > потому что происходит соединение по полям разных типов. > > Почему разных? Имя пакета - это частный случай виртуальной provides. Однако в requires и provides находятся преимущественно виртуальные зависимости (сгенерированные автоматически и не соответствующие названиям реальных пакетов). Поэтому алгоритм в текущем виде не сможет оптимизировать зависимость через soname (что я попытался продемонстрировать на примере glibc-core и sh). Мне кажется, что этот алгоритм работает только в случае, когда в requires содержится имя (невиртуального) пакета. При этом используется тот факт, что provides любого пакета содержит сам себя по имени. Рассмотрим оптимизацию списка {glib2-devel,libgtk+2-devel}. Релевантная часть reqs у libgtk+2-devel выглядит так: reqs<Зависимость> glib2-devel -- проставлено вручную libglib-2.0.so.0 -- сгенерировано автоматически Релевантная часть provs у glib2-devel выглядит так: provs<Зависимость,ИмяПакета> glib2-devel glib2-devel -- любой пакет предоставляет сам себя Тогда мы соединяем reqs<Зависимость>(glib2-devel) \Join provs<ИмяПакета>(glib2-devel) = provs<Зависимость>(glib2-devel). В дальнейшем glib2-devel подлежит вычитанию из списка package-reqs, и вычитание действительно происходит. Это наводит на мысль, что алгоритм в текущем виде оптимизирует только такие пакеты, у которых в requires одного пакета явно прописано имя другого пакета. Тогда возможно соединение фактически по имени пакета с последующим вычитанием опять же по имени пакета, за счет совпадения двух полей в provs. Но в таком случае вовсе не обязательно было использовать %{PROVIDENAME}! Можно было просто соединять зависимости пакетов на сами пакеты. > > Какой в этом смысл? > Минимизация мощности множества зависимостей. Это общее место. :) > Алгоритм нечестный в том > смысле, что он выкидывает циклы. Циклы выкидывать нельзя ни в коем случае. Это ведь оптимизация, а некорректная оптимизация зачастую хуже отсутствия оптимизации вообще. Think of gcc.