From: Alexey Tourbin <at@altlinux.ru> To: devel@altlinux.ru Subject: [devel] packagereq/buildreq proposal Date: Sun, 16 Nov 2003 17:58:30 +0300 Message-ID: <20031116145830.GC1863@julia.office.altlinux.ru> (raw) [-- Attachment #1.1: Type: text/plain, Size: 4551 bytes --] Greetings! Дано: имеется список пакетов, полученный packagereq, БЕЗ учета текущей оптимизации. Список пакетов вычисляется на основе вывода strace и получается очень большим. Некоторая часть этого списка не содержит полезной информации. Задача: оптимизировать список пакетов. Анализ текущего алгоритма оптимизации: если в списке есть пакеты с названиями %name и %name-foo, то пакет %name удаляется из списка. Если в списке есть пакеты с названиями lib%name и %name, то пакет lib%name удаляется из списка. Удаляются также все пакеты из списка essential. Недостатки текущего алгоритма: алгоритм не учитывает зависимости между пакетами. В результате 1) список пакетов остается перегруженным; 2) алгоритм делает ошибки, если структура зависимостей не соответствует описанным допущениям. Примеры, которые демонстрируют недостатоки алгоритма: $ packagereq -o /dev/stdout -- sh -c 'cat `rpm -ql perl-DBD-mysql libMySQL` &>/dev/null ||:' packagereq: building requires list: libMySQL perl-DBD-mysql libMySQL perl-DBD-mysql $ Сейчас в сизифе есть два пакета с libmysqlclient.so. perl-DBD-mysql собран с одной из этих библиотек. Впоследствии он может быть пересобран с другой. Зависимость в третьем пакете на libMySQL не нужна. $ packagereq -o /dev/stdout -- sh -c 'cat `rpm -ql libpcre-devel libpcre` &>/dev/null ||:' packagereq: building requires list: libpcre-devel libpcre-devel $ Пакеты libpcre-devel и libpcre, увы, между собой не связаны. Пример с пакетам ruby, который приводит к тому, что в минимальной сборочной среде ruby отсутствует, я уже приводил. Определения. Прямая зависимость между пакетами: пакет A напрямую зависит от пакета B, если на уровне RPM существует зависимость следующего типа: %package -n A Requires: B Пример прямой зависимости: $ rpm -q --requires libpcre-devel | grep pcre libpcre3 = 4.4-alt1 $ Пакет pcre-devel напрямую зависит от libpcre3. Прямая зависимость через виртуальный пакет: пакет A зависит от пакета B через виртуальный пакет, если на уровне RPM существует зависимость следующего типа: %package -n A Requires: package_B %package -n B Provides: package_B Пример зависимости через виртуальный пакет: $ rpm -q --requires perl-DBD-mysql | grep mysqlclient libmysqlclient.so.12 $ rpm -q --whatprovides libmysqlclient.so.12 libMySQL-4.0.15-alt2 $ Пакет perl-DBD-mysql зависит от пакета libMySQL через виртуальный пакет libmysqlclient.so.12. Косвенная зависимость: любые зависимости с более сложной структурой не рассматриваются. Алгоритм оптимизации: из списка по очереди выбирается пакет-кандидат на удаление. Если какой-либо пакет из оставшейся части списка зависит от кандидата напрямую или через виртуальный пакет, кандидат удаляется. Выполнение алгоритма продолжается на оставшемся списке. Преимущества алгоритма: алгоритм лишен недостатков текущего алгоритма. Недостаток алгоритма: результат зависит от порядка пакетов в списке. Пример: BuildRequires: XFree86-libs XFree86-devel XFree86-devel-static ^-------------' ^----------------' Пакеты XFree86-libs и XFree86-devel будут по очереди удалены. BuildRequires: XFree86-devel XFree86-devel-static XFree86-libs `----------------------------^ ^---------------------' Первым будет удален пакет XFree86-devel; информация о том, что он непосредственно зависит от XFree86-libs, будет потеряна. Над решением этой проблемы в общем виде я не думал. В данном частном случае, как и в некоторых других, достаточно отсортировать список по возрастанию длины названия пакета. Недостаток алгоритма: алгоритм не работает с виртуальными пакетами (которые packagereq подставляет в соответствии с правилами /etc/buildreqs/packages/substitute.d). Обсуждение на канале привело меня к мысли, что семантика виртуальных пакетов, которые предоставляются несколькими другими пакетами, определена недостаточно хорошо. Нужно сформулировать правила использования виртуальных пакетов. Прототип реализации прилагается. Примеры работы прототипа: $ perl rpm.pl libMySQL perl-DBD-mysql perl-DBD-mysql requires libMySQL through libmysqlclient.so.12 libMySQL optimized out perl-DBD-mysql $ perl rpm.pl libpcre3 libpcre libpcre-devel libpcre-devel requires libpcre3 libpcre3 optimized out libpcre libpcre-devel $ perl rpm.pl XFree86-libs XFree86-devel XFree86-devel-static XFree86-devel requires XFree86-libs through libX11.so.6 XFree86-libs optimized out XFree86-devel-static requires XFree86-devel XFree86-devel optimized out XFree86-devel-static [-- Attachment #1.2: rpm.pl --] [-- Type: text/plain, Size: 1364 bytes --] #!/usr/bin/perl use RPM::Database; use strict; my $db = RPM::Database->new; my %DB; # load Requires: and Provides: from RPM database for the given packages foreach my $pkg (@ARGV) { my $hdr = $$db{$pkg}; unless ($hdr) { warn "package $pkg not found\n"; next; } my $requires = $$hdr{REQUIRENAME}; if ($requires) { $DB{$pkg}{req} = $requires; } else { warn "package $pkg requires nothing\n"; $DB{$pkg}{req} = []; } my $provides = $$hdr{PROVIDES}; if ($provides) { $DB{$pkg}{prov} = $provides; } else { warn "package $pkg provides nothing\n"; $DB{$pkg}{prov} = []; } } use sort 'stable'; # try to optimize out packages with shortest names first # alphabetical order is also in effect my @packages = sort { length($a) <=> length($b) } sort keys %DB; try: while (1) { foreach my $pkg (@packages) { my @rest = grep { $_ ne $pkg } @packages; if (my ($who, $what) = implies($pkg, @rest)) { warn "\t$who requires $pkg" . ($what eq $pkg ? "\n" : " through $what\n"); warn "\t\t$pkg optimized out\n"; @packages = @rest; next try; } } last; } @packages = sort @packages; print "@packages\n"; sub implies { my ($pkg, @others) = @_; foreach my $prov (@{$DB{$pkg}{prov}}) { foreach my $who (@others) { foreach my $req (@{$DB{$who}{req}}) { return ($who, $req) if ($req eq $prov); } } } return; } [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2003-11-16 14:58 UTC|newest] Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top 2003-11-16 14:58 Alexey Tourbin [this message] 2003-11-16 15:06 ` [devel] " Alexey Tourbin 2003-11-16 15:54 ` [devel] " Dmitry V. Levin 2003-11-16 17:10 ` [devel] " Alexey Tourbin 2003-11-17 8:46 ` Michael Shigorin 2003-11-17 11:42 ` Alexey Tourbin 2003-11-17 12:09 ` vserge 2003-11-17 12:12 ` Alexey Tourbin 2003-11-17 12:18 ` Sergey Bolshakov 2003-11-17 12:38 ` Marat Khairullin 2003-12-15 19:37 ` Alexey Tourbin 2003-12-15 21:05 ` Michael Shigorin 2003-12-16 10:09 ` Dmitry V. Levin 2003-12-16 12:18 ` Alexey Tourbin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20031116145830.GC1863@julia.office.altlinux.ru \ --to=at@altlinux.ru \ --cc=devel@altlinux.ru \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
ALT Linux Team development discussions This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \ devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru public-inbox-index devel Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.devel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git