Source: dpkg-dev
Version: 1.18.1
Severity: wishlist
Tags: patch
User: [email protected]
Usertags: toolchain
X-Debbugs-Cc: [email protected]
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
`. `'` [email protected] / 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
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds