Quellcode durchsuchen

dpkg-shlibdeps: use the Build-Depends-Package information from symbols files

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.
Raphael Hertzog vor 18 Jahren
Ursprung
Commit
15b03b6fc3
6 geänderte Dateien mit 103 neuen und 18 gelöschten Zeilen
  1. 3 1
      ChangeLog
  2. 4 0
      debian/changelog
  3. 2 0
      man/ChangeLog
  4. 7 0
      man/dpkg-shlibdeps.1
  5. 13 0
      scripts/Dpkg/Shlibs/SymbolFile.pm
  6. 74 17
      scripts/dpkg-shlibdeps.pl

+ 3 - 1
ChangeLog

@@ -44,11 +44,13 @@
 	* 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>
 

+ 4 - 0
debian/changelog

@@ -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)

+ 2 - 0
man/ChangeLog

@@ -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>
 

+ 7 - 0
man/dpkg-shlibdeps.1

@@ -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

+ 13 - 0
scripts/Dpkg/Shlibs/SymbolFile.pm

@@ -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);

+ 74 - 17
scripts/dpkg-shlibdeps.pl

@@ -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;