[dpkg] 83/200: dpkg-shlibdeps: Improve logic to identify packages owning a library
Ximin Luo
infinity0 at debian.org
Wed Apr 5 15:17:21 UTC 2017
This is an automated email from the git hooks/post-receive script.
infinity0 pushed a commit to branch master
in repository dpkg.
commit a927295c93fb7a17742441aa863aaffcf4a351b5
Author: Raphaël Hertzog <hertzog at debian.org>
Date: Mon Nov 14 11:46:09 2016 +0100
dpkg-shlibdeps: Improve logic to identify packages owning a library
With things like merged-/usr, a system might have libraries that are
stored for example in /usr/lib but that dpkg knows under /lib. This
breaks some of the initial assumptions made in dpkg-shlibdeps.
We now scan all possible paths for a given library (instead of trying
to guess which one is the canonical one) and whenever we find a match
in the dpkg database, we also associate the package for the associated
realpath(). That way when a library is not properly identified, we can
fallback on looking if its realpath is known and be confident that if
the library was packaged, we did identify it correctly.
[guillem at debian.org:
- Fold find_library_locations() into find_library().
- Minor coding style fixes.
- Squash the two separate commits and cleanup the commit message. ]
Closes: #843073
Signed-off-by: Guillem Jover <guillem at debian.org>
---
debian/changelog | 3 +++
scripts/Dpkg/Shlibs.pm | 19 +++++--------------
scripts/dpkg-shlibdeps.pl | 31 ++++++++++++++++---------------
3 files changed, 24 insertions(+), 29 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 6ee9b0e..e85be87 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,9 @@ dpkg (1.18.17) UNRELEASED; urgency=medium
are optional. Regression introduced in dpkg 1.18.16. Closes: #848422
* Validate versions too in dpkg-maintscript-helper symlink_to_dir and
dir_to_symlink commands.
+ * Improve logic to identify packages owning a library in dpkg-shlibdeps,
+ by handling the same library appearing more than once on the filesystem
+ Thanks to Raphaël Hertzog <hertzog at debian.org>. Closes: #843073
* Documentation:
- Clarify that dpkg-buildpackage does not run «dpkg-source --before-build»
when using the -T option. Closes: #649531
diff --git a/scripts/Dpkg/Shlibs.pm b/scripts/Dpkg/Shlibs.pm
index c6221c4..3bb3c7b 100644
--- a/scripts/Dpkg/Shlibs.pm
+++ b/scripts/Dpkg/Shlibs.pm
@@ -1,4 +1,4 @@
-# Copyright © 2007 Raphaël Hertzog <hertzog at debian.org>
+# Copyright © 2007, 2016 Raphaël Hertzog <hertzog at debian.org>
# Copyright © 2007-2008, 2012-2015 Guillem Jover <guillem at debian.org>
#
# This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,7 @@ use strict;
use warnings;
use feature qw(state);
-our $VERSION = '0.02';
+our $VERSION = '0.03';
our @EXPORT_OK = qw(
blank_library_paths
setup_library_paths
@@ -149,29 +149,20 @@ sub find_library {
setup_library_paths() if not $librarypaths_init;
my @librarypaths = (@{$rpath}, @custom_librarypaths, @system_librarypaths);
+ my @libs;
$root //= '';
$root =~ s{/+$}{};
foreach my $dir (@librarypaths) {
my $checkdir = "$root$dir";
- # If the directory checked is a symlink, check if it doesn't
- # resolve to another public directory (which is then the canonical
- # directory to use instead of this one). Typical example
- # is /usr/lib64 -> /usr/lib on amd64.
- if (-l $checkdir) {
- my $newdir = resolve_symlink($checkdir);
- if (any { "$root$_" eq "$newdir" } @librarypaths) {
- $checkdir = $newdir;
- }
- }
if (-e "$checkdir/$lib") {
my $libformat = Dpkg::Shlibs::Objdump::get_format("$checkdir/$lib");
if ($format eq $libformat) {
- return canonpath("$checkdir/$lib");
+ push @libs, canonpath("$checkdir/$lib");
}
}
}
- return;
+ return @libs;
}
1;
diff --git a/scripts/dpkg-shlibdeps.pl b/scripts/dpkg-shlibdeps.pl
index 3204026..e121aae 100755
--- a/scripts/dpkg-shlibdeps.pl
+++ b/scripts/dpkg-shlibdeps.pl
@@ -6,7 +6,7 @@
# Copyright © 2000 Wichert Akkerman
# Copyright © 2006 Frank Lichtenheld
# Copyright © 2006-2010,2012-2015 Guillem Jover <guillem at debian.org>
-# Copyright © 2007 Raphaël Hertzog
+# Copyright © 2007, 2016 Raphaël Hertzog <hertzog at debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -192,8 +192,8 @@ foreach my $file (keys %exec) {
my %soname_notfound;
my %alt_soname;
foreach my $soname (@sonames) {
- my $lib = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
- unless (defined $lib) {
+ my @libs = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
+ unless (scalar @libs) {
$soname_notfound{$soname} = 1;
$global_soname_notfound{$soname} = 1;
my $msg = g_("couldn't find library %s needed by %s (ELF " .
@@ -206,12 +206,14 @@ foreach my $file (keys %exec) {
}
next;
}
- $libfiles{$lib} = $soname;
- my $reallib = realpath($lib);
- if ($reallib ne $lib) {
- $altlibfiles{$reallib} = $soname;
- }
- print "Library $soname found in $lib\n" if $debug;
+ foreach my $lib (@libs) {
+ $libfiles{$lib} = $soname;
+ my $reallib = realpath($lib);
+ if ($reallib ne $lib) {
+ $altlibfiles{$reallib} = $soname;
+ }
+ print "Library $soname found in $lib\n" if $debug;
+ }
}
my $file2pkg = find_packages(keys %libfiles, keys %altlibfiles);
my $symfile = Dpkg::Shlibs::SymbolFile->new();
@@ -830,17 +832,14 @@ sub my_find_library {
foreach my $builddir (@builddirs) {
next if defined($dir_checked{$builddir});
next if ignore_pkgdir($builddir);
- $file = find_library($lib, \@RPATH, $format, $builddir);
- return $file if defined($file);
+ my @libs = find_library($lib, \@RPATH, $format, $builddir);
+ return @libs if scalar @libs;
$dir_checked{$builddir} = 1;
}
# Fallback in the root directory if we have not found what we were
# looking for in the packages
- $file = find_library($lib, \@RPATH, $format, '');
- return $file if defined($file);
-
- return;
+ return find_library($lib, \@RPATH, $format, '');
}
my %cached_pkgmatch = ();
@@ -879,7 +878,9 @@ sub find_packages {
or syserr(g_('write diversion info to stderr'));
} elsif (m/^([-a-z0-9+.:, ]+): (\/.*)$/) {
my ($pkgs, $path) = ($1, $2);
+ my $realpath = realpath($path);
$cached_pkgmatch{$path} = $pkgmatch->{$path} = [ split /, /, $pkgs ];
+ $cached_pkgmatch{$realpath} = $pkgmatch->{$realpath} = [ split /, /, $pkgs ];
} else {
warning(g_("unknown output from dpkg --search: '%s'"), $_);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git
More information about the Reproducible-commits
mailing list