Re: Debian Installer Stretch Alpha 8 release
Control: tag -1 + patch
Control: severity -1 serious
Hi Guillem,
On Sun, 13 Nov 2016, Guillem Jover wrote:
> > The /usr merge violates core assumptions in dpkg-shlibdeps. The reason
> > that amd64 isn't broken is sheer luck.
> > /etc/ld.so.conf.d/x86_64-linux-gnu.conf lists /lib before /usr/lib, so
> > dpkg-shlibdeps considers that first. Swapping them or simply removing
> > /lib (as seems reasonable on a merged /usr), breaks almost any build on
> > amd64 (e.g. dash). The breakage on amd64 is simply hidden.
>
> Right. I'm happy to assist people who want to fix this to try to find
> a proper solution in dpkg-dev, but I'm not planning on spending time
> on this on my own.
Please find two patches attached.
I checked that the command below was failing with the current dpkg-dev
and it did no longer fail with the updated one.
$ sbuild -d sid --add-depends=usrmerge --chroot-setup-commands="sed -i 's#^/usr##;t;s#^/lib#/usr&#' /etc/ld.so.conf.d/x86_64-linux-gnu.conf" dash
I believe my patch to be correct and clean.
> Err, well exactly because usemerge is a major hack, and I'm actually
> surprised we are deploying systems by default with that. As an
It's easier to push work upon others... to be honest the code (that I
wrote) in dpkg-dev that tries to identifiy the canonical version of the
library is also somewhat hackish.
I think the updated code that I submitted works better in all weird
corner cases that we could think of.
I'm happy to assist you shall any regression be found.
Cheers,
--
Raphaël Hertzog ◈ Debian Developer
Support Debian LTS: http://www.freexian.com/services/debian-lts.html
Learn to master Debian: http://debian-handbook.info/get/
>From d2e19afa0f80a955b66ad133c4ebd5b1458bd8ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= <hertzog@debian.org>
Date: Mon, 14 Nov 2016 11:46:09 +0100
Subject: [PATCH 1/2] Dpkg::Shlibs: add find_library_locations()
This new functions returns all paths/locations where the library has
been found. Where find_library() has some tricks to try to identify the
canonical version of the library, this one is much simpler: it scans all
directories from the library path and returns every place where it has
been found.
---
scripts/Dpkg/Shlibs.pm | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/scripts/Dpkg/Shlibs.pm b/scripts/Dpkg/Shlibs.pm
index c6221c4..dc0276a 100644
--- a/scripts/Dpkg/Shlibs.pm
+++ b/scripts/Dpkg/Shlibs.pm
@@ -1,4 +1,4 @@
-# Copyright © 2007 Raphaël Hertzog <hertzog@debian.org>
+# Copyright © 2007,2016 Raphaël Hertzog <hertzog@debian.org>
# Copyright © 2007-2008, 2012-2015 Guillem Jover <guillem@debian.org>
#
# This program is free software; you can redistribute it and/or modify
@@ -20,13 +20,14 @@ 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
get_library_paths
add_library_dir
find_library
+ find_library_locations
);
use Exporter qw(import);
@@ -174,4 +175,26 @@ sub find_library {
return;
}
+sub find_library_locations {
+ my ($lib, $rpath, $format, $root) = @_;
+
+ setup_library_paths() if not $librarypaths_init;
+
+ my @librarypaths = (@{$rpath}, @custom_librarypaths, @system_librarypaths);
+ my @locations;
+
+ $root //= '';
+ $root =~ s{/+$}{};
+ foreach my $dir (@librarypaths) {
+ my $checkdir = "$root$dir";
+ if (-e "$checkdir/$lib") {
+ my $libformat = Dpkg::Shlibs::Objdump::get_format("$checkdir/$lib");
+ if ($format eq $libformat) {
+ push @locations, canonpath("$checkdir/$lib");
+ }
+ }
+ }
+ return @locations;
+}
+
1;
--
2.10.2
>From 538208594a1af8b5539d83976e8161b46ea0e40c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rapha=C3=ABl=20Hertzog?= <hertzog@debian.org>
Date: Mon, 14 Nov 2016 11:51:50 +0100
Subject: [PATCH 2/2] dpkg-shlibdeps: improve logic to identify package owning
a library
With the introduction of merged-/usr, we have libraries in that are
stored 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
guessing 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.
Closes: #843073
---
scripts/dpkg-shlibdeps.pl | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/scripts/dpkg-shlibdeps.pl b/scripts/dpkg-shlibdeps.pl
index 3204026..f279f58 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@debian.org>
-# Copyright © 2007 Raphaël Hertzog
+# Copyright © 2007,2016 Raphaël Hertzog
#
# 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
@@ -35,7 +35,7 @@ use Dpkg::Util qw(:list);
use Dpkg::Path qw(relative_to_pkg_root guess_pkg_root_dir
check_files_are_the_same get_control_path);
use Dpkg::Version;
-use Dpkg::Shlibs qw(find_library get_library_paths);
+use Dpkg::Shlibs qw(find_library_locations get_library_paths);
use Dpkg::Shlibs::Objdump;
use Dpkg::Shlibs::SymbolFile;
use Dpkg::Substvars;
@@ -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 @locations = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
+ unless (scalar(@locations)) {
$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 (@locations) {
+ $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 @locations = find_library_locations($lib, \@RPATH, $format, $builddir);
+ return @locations if scalar(@locations);
$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_locations($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'"), $_);
}
--
2.10.2
Reply to: