[devel] оптимизация сборочных зависимостей

Alexey Tourbin =?iso-8859-1?q?at_=CE=C1_altlinux=2Eru?=
Ср Авг 30 22:30:20 MSD 2006


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.
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя     : =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Тип     : application/pgp-signature
Размер  : 189 байтов
Описание: =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Url     : <http://lists.altlinux.org/pipermail/devel/attachments/20060830/b9e13200/attachment-0001.bin>


Подробная информация о списке рассылки Devel