Source: dpkg-dev
Version: 1.18.1
Severity: wishlist
Tags: patch
User: reproducible-builds@lists.alioth.debian.org
Usertags: toolchain
X-Debbugs-Cc: reproducible-builds@lists.alioth.debian.org
Hi,
While working on the reproducible builds effort [1], we have noticed
that dpkg-dev doesn't sort some dependencies deterministically.
This results in the output ofdpkg-shlibdeps non-reproducible, flapping
between, for example:
- pkga | pkgb, pkga | pkgc
+ pkga | pkgc, pkga | pkgb
This can (currently) be seen in pyopencl:
https://reproducible.debian.net/rb-pkg/unstable/amd64/pyopencl.html
This is caused by deps_compare only comparing the left-most dependency
of a Dpkg::Deps::Multiple. The attached patch ensures that all
dependencies
of such an object are checked, including an addition to the testsuite.
[1]: https://wiki.debian.org/ReproducibleBuilds
Regards,
--
,''`.
: :' : Chris Lamb
`. `'` la...@debian.org / chris-lamb.co.uk
`-
diff --git a/scripts/Dpkg/Deps.pm b/scripts/Dpkg/Deps.pm
index 1823340..4b10a96 100644
--- a/scripts/Dpkg/Deps.pm
+++ b/scripts/Dpkg/Deps.pm
@@ -367,25 +367,22 @@ my %relation_ordering = (
sub deps_compare {
my ($a, $b) = @_;
-return -1 if $a-is_empty();
-return 1 if $b-is_empty();
-while ($a-isa('Dpkg::Deps::Multiple')) {
- return -1 if $a-is_empty();
- my @deps = $a-get_deps();
- $a = $deps[0];
+my (@as, @bs) = (), ();
+deps_iterate($a, sub { push @as, @_ });
+deps_iterate($b, sub { push @bs, @_ });
+while (1) {
+my $a = shift @as // return -1;
+my $b = shift @bs // return 1;
+my $ar = $a-{relation} // 'undef';
+my $br = $b-{relation} // 'undef';
+my $av = $a-{version} // '';
+my $bv = $b-{version} // '';
+my $res = (($a-{package} cmp $b-{package}) ||
+($relation_ordering{$ar} = $relation_ordering{$br}) ||
+($av cmp $bv));
+return $res if $res = 0;
}
-while ($b-isa('Dpkg::Deps::Multiple')) {
- return 1 if $b-is_empty();
- my @deps = $b-get_deps();
- $b = $deps[0];
-}
-my $ar = $a-{relation} // 'undef';
-my $br = $b-{relation} // 'undef';
-my $av = $a-{version} // '';
-my $bv = $a-{version} // '';
-return (($a-{package} cmp $b-{package}) ||
- ($relation_ordering{$ar} = $relation_ordering{$br}) ||
- ($av cmp $bv));
+return 0;
}
diff --git a/scripts/t/Dpkg_Deps.t b/scripts/t/Dpkg_Deps.t
index db4b187..5579e12 100644
--- a/scripts/t/Dpkg_Deps.t
+++ b/scripts/t/Dpkg_Deps.t
@@ -40,9 +40,9 @@ my $dep_multiline = deps_parse($field_multiline);
$dep_multiline-sort();
is($dep_multiline-output(), $field_multiline_sorted, 'Parse, sort and
output');
-my $dep_sorted = deps_parse('pkgz, pkgz | pkga, pkga (= 1.0), pkgz (= 2.0)');
+my $dep_sorted = deps_parse('pkgz, pkgz | pkgb, pkgz | pkga, pkga (= 1.0),
pkgz (= 2.0)');
$dep_sorted-sort();
-is($dep_sorted-output(), 'pkga (= 1.0), pkgz, pkgz | pkga, pkgz (= 2.0)',
'Check sort() algorithm');
+is($dep_sorted-output(), 'pkga (= 1.0), pkgz, pkgz | pkga, pkgz | pkgb, pkgz
(= 2.0)', 'Check sort() algorithm');
my $dep_subset = deps_parse('libatk1.0-0 ( 1.10), libc6, libcairo2');
is($dep_multiline-implies($dep_subset), 1, 'Dep implies subset of itself');
___
Reproducible-builds mailing list
Reproducible-builds@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds