]> err.no Git - dpkg/commitdiff
dpkg-shlibdeps: use the Build-Depends-Package information from symbols files
authorRaphael Hertzog <hertzog@debian.org>
Sun, 9 Dec 2007 14:42:40 +0000 (15:42 +0100)
committerRaphael Hertzog <hertzog@debian.org>
Thu, 13 Dec 2007 19:52:07 +0000 (20:52 +0100)
Use this new field to identify the version requirement possibly encoded in
the Build-Depends field and make sure that the generated dependency is at
least as strict as this one. Updated dpkg-shlibdeps's manual page.

ChangeLog
debian/changelog
man/ChangeLog
man/dpkg-shlibdeps.1
scripts/Dpkg/Shlibs/SymbolFile.pm
scripts/dpkg-shlibdeps.pl

index 1dc85f13211119a0fe8dcc62eb463ebb4154cd91..e8ea1bd40ac9252e74c076836117983734c8fe3d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * scripts/Dpkg/Shlibs/SymbolFile.pm: Parse and dump properly
        new meta-information fields (on lines starting with an asterisk).
        Bugfix with alternate dependency handling that were not properly
-       dumped.
+       dumped. New functions get_dependencies() and get_field().
        * scripts/t/200_Dpkg_Shlibs.t,
        scripts/t/200_Dpkg_Shlibs/symbols.fake-2: Add a test case to
        verify that meta-information fields and alternate dependencies are
        properly parsed and dumped.
+       * scripts/dpkg-shlibdeps.pl: Take into account the new
+       Build-Depends-Package field in symbols files.
 
 2007-12-09  Raphael Hertzog  <hertzog@debian.org>
 
index c8c9dfc73800c45efecd25850bf1d320de9ea451..e3be2adda7f4616fa884b11300d0630441807d75 100644 (file)
@@ -29,6 +29,10 @@ dpkg (1.14.13) UNRELEASED; urgency=low
   * Tweak the sort algorithm between dependencies so that intervals
     are displayed as "a (>= 1), a (<< 2)" instead of the opposite.
     Closes: #455520
+  * Extend format of symbols files to support arbitrary fields of
+    meta-information. First field is Build-Depends-Package used to extract the
+    version requirement possibly encoded in the Build-Depends field and make
+    sure that the generated dependency is at least as strict as this one.
 
   [ Updated man pages translations ]
   * Swedish (Peter Karlsson)
index 177d0272b2126087c7d0f32cedbb5f697e691b1e..214d101f78fc45db0b8d255b2e52a565bdf15cb2 100644 (file)
@@ -6,6 +6,8 @@
 
        * deb-symbols.5: Describe syntax of meta-information
        fields and document the Build-Depends-Package field.
+       * dpkg-shlibdeps.1: Describe how the Build-Depends-Package field
+       of symbols file is used.
 
 2007-12-09  Raphael Hertzog  <hertzog@debian.org>
 
index f02d203dcf5536a10cc341f257d8a4907a859c30..d7ea373f90b5fe0fdb7e3930a573e34e8d8aec63 100644 (file)
@@ -68,6 +68,13 @@ remembers the (biggest) minimal version needed for each library. At the end
 of the process, it is able to write out the minimal dependency for every
 library used (provided that the information of the \fIsymbols\fR files are
 accurate).
+.P
+As a safe-guard measure, a symbols file can provide a
+\fIBuild-Depends-Package\fR meta-information field and
+.B dpkg-shlibdeps
+will extract the minimal version required by the corresponding package in
+the Build-Depends field and use this version if it's higher than the
+minimal version computed by scanning symbols.
 .SS Shlibs files
 Shlibs files associate directly a library to a dependency (without looking
 at the symbols). It's thus often stronger than really needed but very safe
index 8f3dfe5837a9d6c4a070cfb08757a1dac60fad70..e3eb483d08803cfe68d35aaf695f59207810270c 100644 (file)
@@ -273,6 +273,19 @@ sub get_dependency {
     return $self->{objects}{$soname}{deps}[$dep_id];
 }
 
+sub get_dependencies {
+    my ($self, $soname) = @_;
+    return @{$self->{objects}{$soname}{deps}};
+}
+
+sub get_field {
+    my ($self, $soname, $name) = @_;
+    if (exists $self->{objects}{$soname}{fields}{$name}) {
+       return $self->{objects}{$soname}{fields}{$name};
+    }
+    return undef;
+}
+
 sub lookup_symbol {
     my ($self, $name, $sonames, $inc_deprecated) = @_;
     $inc_deprecated = 0 unless defined($inc_deprecated);
index c26b7a3b325c741173f8816b738d000e12f97454..72b34ae2c47f78502306851ef3cea6fd7ef33bc9 100755 (executable)
@@ -11,12 +11,16 @@ use Dpkg::Gettext;
 use Dpkg::ErrorHandling qw(warning error failure syserr usageerr);
 use Dpkg::Path qw(relative_to_pkg_root guess_pkg_root_dir
                  check_files_are_the_same);
-use Dpkg::Version qw(vercmp);
+use Dpkg::Version qw(compare_versions);
 use Dpkg::Shlibs qw(find_library);
 use Dpkg::Shlibs::Objdump;
 use Dpkg::Shlibs::SymbolFile;
 use Dpkg::Arch qw(get_host_arch);
 use Dpkg::Fields qw(capit);
+use Dpkg::Deps;
+
+push(@INC,$dpkglibdir);
+require 'controllib.pl';
 
 # By increasing importance
 my @depfields = qw(Suggests Recommends Depends Pre-Depends);
@@ -83,6 +87,12 @@ foreach (@ARGV) {
 
 scalar keys %exec || usageerr(_g("need at least one executable"));
 
+our %fi;
+parsecontrolfile("debian/control");
+my $build_depends = defined($fi{"C Build-Depends"}) ?
+                   $fi{"C Build-Depends"} : "";
+my $build_deps = Dpkg::Deps::parse($build_depends, reduce_arch => 1);
+
 my %dependencies;
 my %shlibs;
 
@@ -210,21 +220,9 @@ foreach my $file (keys %exec) {
        }
        my $symdep = $symfile->lookup_symbol($name, \@sonames);
        if (defined($symdep)) {
-           my ($d, $m) = ($symdep->{depends}, $symdep->{minver});
            $used_sonames{$symdep->{soname}}++;
-           foreach my $subdep (split /\s*,\s*/, $d) {
-               if (exists $dependencies{$cur_field}{$subdep} and
-                   defined($dependencies{$cur_field}{$subdep}))
-               {
-                   if ($dependencies{$cur_field}{$subdep} eq '' or
-                       vercmp($m, $dependencies{$cur_field}{$subdep}) > 0)
-                   {
-                       $dependencies{$cur_field}{$subdep} = $m;
-                   }
-               } else {
-                   $dependencies{$cur_field}{$subdep} = $m;
-               }
-           }
+           update_dependency_version($symdep->{depends},
+                                     $symdep->{minver});
        } else {
            my $syminfo = $dumplibs_wo_symfile->locate_symbol($name);
            if (not defined($syminfo)) {
@@ -252,8 +250,20 @@ foreach my $file (keys %exec) {
     }
     warning(_g("%d other similar warnings have been skipped (use -v to see " .
            "them all)."), $nb_skipped_warnings) if $nb_skipped_warnings;
-    # Warn about un-NEEDED libraries
     foreach my $soname (@sonames) {
+       # Adjust minimal version of dependencies with information
+       # extracted from build-dependencies
+       my $dev_pkg = $symfile->get_field($soname, 'Build-Depends-Package');
+       if (defined $dev_pkg) {
+           my $minver = get_min_version_from_deps($build_deps, $dev_pkg);
+           if (defined $minver) {
+               foreach my $dep ($symfile->get_dependencies($soname)) {
+                   update_dependency_version($dep, $minver);
+               }
+           }
+       }
+
+       # Warn about un-NEEDED libraries
        unless ($soname_notfound{$soname} or $used_sonames{$soname}) {
            # Ignore warning for libm.so.6 if also linked against libstdc++
            next if ($soname =~ /^libm\.so\.\d+$/ and
@@ -302,7 +312,7 @@ sub filter_deps {
        # Since dependencies can be versionned, we have to
        # verify if the dependency is stronger than the
        # previously seen one
-       if (vercmp($depseen{$dep}, $dependencies{$field}{$dep}) > 0) {
+       if (compare_versions($depseen{$dep}, '>>', $dependencies{$field}{$dep})) {
            return 0;
        } else {
            $depseen{$dep} = $dependencies{$field}{$dep};
@@ -384,6 +394,53 @@ Dependency fields recognised are:
 "), $progname, join("/",@depfields);
 }
 
+sub get_min_version_from_deps {
+    my ($dep, $pkg) = @_;
+    if ($dep->isa('Dpkg::Deps::Simple')) {
+       if (($dep->{package} eq $pkg) &&
+           defined($dep->{relation}) &&
+           (($dep->{relation} eq ">=") ||
+            ($dep->{relation} eq ">>")))
+       {
+           return $dep->{version};
+       }
+       return undef;
+    } else {
+       my $res;
+       foreach my $subdep ($dep->get_deps()) {
+           my $minver = get_min_version_from_deps($subdep, $pkg);
+           next if not defined $minver;
+           if (defined $res) {
+               if (compare_versions($minver, '>>', $res)) {
+                   $res = $minver;
+               }
+           } else {
+               $res = $minver;
+           }
+       }
+       return $res;
+    }
+}
+
+sub update_dependency_version {
+    my ($dep, $minver) = @_;
+    return if not defined($minver);
+    foreach my $subdep (split /\s*,\s*/, $dep) {
+       if (exists $dependencies{$cur_field}{$subdep} and
+           defined($dependencies{$cur_field}{$subdep}))
+       {
+           if ($dependencies{$cur_field}{$subdep} eq '' or
+               compare_versions($minver, '>>',
+                                $dependencies{$cur_field}{$subdep}))
+           {
+               $dependencies{$cur_field}{$subdep} = $minver;
+           }
+       } else {
+           $dependencies{$cur_field}{$subdep} = $minver;
+       }
+    }
+}
+
 sub add_shlibs_dep {
     my ($soname, $pkg) = @_;
     print "Looking up shlibs dependency of $soname provided by '$pkg'\n" if $debug;