+2007-11-23 Raphael Hertzog <hertzog@debian.org>
+
+ * scripts/dpkg-shlibdeps.pl: Look for libs in the package's build
+ tree even if that package doesn't contain an shlibs file. Then
+ don't complain about missing dependency information if the lib is in
+ the same package than the binary. Also ignore it if the library is
+ not versionned and can't have an shlibs file.
+ * scripts/Dpkg/Path.pm (guess_pkg_root_dir,
+ check_files_are_the_same): Add new helper functions.
+
2007-11-23 Guillem Jover <guillem@debian.org>
* configure.ac: Bump version to 1.14.11~.
use warnings;
use Exporter;
+use Cwd qw(realpath);
our @ISA = qw(Exporter);
-our @EXPORT_OK = qw(get_pkg_root_dir relative_to_pkg_root);
+our @EXPORT_OK = qw(get_pkg_root_dir relative_to_pkg_root
+ guess_pkg_root_dir check_files_are_the_same);
=head1 NAME
return undef;
}
+=item guess_pkg_root_dir($file)
+
+This function tries to guess the root directory of the package build tree.
+It will first use get_pkg_root_dir(), but it will fallback to a more
+imprecise check: namely it will use the parent directory that is a
+sub-directory of the debian directory.
+
+It can still return undef if a file outside of the debian sub-directory is
+provided.
+
+=cut
+sub guess_pkg_root_dir($) {
+ my $file = shift;
+ my $root = get_pkg_root_dir($file);
+ return $root if defined $root;
+
+ $file =~ s{/+$}{};
+ $file =~ s{/+[^/]+$}{} if not -d $file;
+ my $parent = $file;
+ while ($file) {
+ $parent =~ s{/+[^/]+$}{};
+ last if not -d $parent;
+ return $file if check_files_are_the_same("debian", $parent);
+ $file = $parent;
+ last if $file !~ m{/};
+ }
+ return undef;
+}
+
+=item check_files_are_the_same($file1, $file2)
+
+This function verifies that both files are the same by checking that the device
+numbers and the inode numbers returned by lstat() are the same.
+
+=cut
+sub check_files_are_the_same($$) {
+ my ($file1, $file2) = @_;
+ return 0 if ((! -e $file1) || (! -e $file2));
+ my @stat1 = lstat($file1);
+ my @stat2 = lstat($file2);
+ my $result = ($stat1[0] == $stat2[0]) && ($stat1[1] == $stat2[1]);
+ return $result;
+}
+
=back
=head1 AUTHOR
use Dpkg;
use Dpkg::Gettext;
use Dpkg::ErrorHandling qw(warning error failure syserr usageerr);
-use Dpkg::Path qw(relative_to_pkg_root);
+use Dpkg::Path qw(relative_to_pkg_root guess_pkg_root_dir
+ check_files_are_the_same);
use Dpkg::Version qw(vercmp);
use Dpkg::Shlibs qw(find_library);
use Dpkg::Shlibs::Objdump;
my $libobj = $dumplibs_wo_symfile->get_object($id);
# Only try to generate a dependency for libraries with a SONAME
if ($libobj->is_public_library() and not add_shlibs_dep($soname, $pkg)) {
+ # This failure is fairly new, try to be kind by
+ # ignoring as many cases that can be safely ignored
+ my $ignore = 0;
+ # 1/ when the lib and the binary are in the same
+ # package
+ my $root_file = guess_pkg_root_dir($file);
+ my $root_lib = guess_pkg_root_dir($lib);
+ $ignore++ if defined $root_file and defined $root_lib
+ and check_files_are_the_same($root_file, $root_lib);
+ # 2/ when the lib is not versioned and can't be
+ # handled by shlibs
+ $ignore++ unless scalar(split_soname($soname));
+ # 3/ when we have been asked to do so
+ $ignore++ if $ignore_missing_info;
failure(_g("No dependency information found for %s " .
"(used by %s)."), $soname, $file)
- unless $ignore_missing_info;
+ unless $ignore;
}
}
}
return 0;
}
+sub split_soname {
+ my $soname = shift;
+ if ($soname =~ /^(.*)\.so\.(.*)$/) {
+ return wantarray ? ($1, $2) : 1;
+ } elsif ($soname =~ /^(.*)-(\d.*)\.so$/) {
+ return wantarray ? ($1, $2) : 1;
+ } else {
+ return wantarray ? () : 0;
+ }
+}
+
sub extract_from_shlibs {
my ($soname, $shlibfile) = @_;
- my ($libname, $libversion);
# Split soname in name/version
- if ($soname =~ /^(.*)\.so\.(.*)$/) {
- $libname = $1; $libversion = $2;
- } elsif ($soname =~ /^(.*)-(.*)\.so$/) {
- $libname = $1; $libversion = $2;
- } else {
+ my ($libname, $libversion) = split_soname($soname);
+ unless (defined $libname) {
warning(_g("Can't extract name and version from library name \`%s'"),
$soname);
return;
}
# Look into the packages we're currently building (but only those
- # that provides shlibs file...)
+ # that provides shlibs file and the one that contains the binary being
+ # anlyzed...)
# TODO: we should probably replace that by a cleaner way to look into
# the various temporary build directories...
my @copy = (@pkg_shlibs);
+ my $pkg_root = guess_pkg_root_dir($execfile);
+ unshift @copy, $pkg_root if defined $pkg_root;
foreach my $builddir (map { s{/DEBIAN/shlibs$}{}; $_ } @copy) {
$file = find_library($lib, \@RPATH, $format, $builddir);
return $file if defined($file);