-.TH dpkg\-shlibdeps 1 "2007-07-16" "Debian Project" "dpkg utilities"
+.TH dpkg\-shlibdeps 1 "2008-03-25" "Debian Project" "dpkg utilities"
.SH NAME
dpkg\-shlibdeps \- generate shared library substvar dependencies
.
dependency information (either with shlibs files, or with symbols files)
even if they are not yet used by other packages.
.TP
+.BI \-\-warnings= value
+\fIvalue\fP is a bit field defining the set of warnings that
+can be emitted by \fBdpkg-\-shlibdeps\fP.
+Bit 0 (value=1) enables the warning "symbol \fIsym\fP used by \fIbinary\fP
+found in none of the libraries", bit 1 (value=2) enables the warning
+"dependency on \fIlibrary\fP could be avoided" and bit 2 (value=4)
+enables the warning "\fIbinary\fP shouldn't be linked with \fIlibrary\fP".
+The default \fIvalue\fP is 3: the first two warnings are active by
+default, the last one is not. Set \fIvalue\fP to 7 if you want all
+warnings to be active.
+.TP
.BI \-\-admindir= dir
Change the location of the \fBdpkg\fR database. The default location is
\fI/var/lib/dpkg\fP.
with an additional library during the build process (option \fB-l\fR\fIlibrary\fR
of the linker).
.TP
+.BI "dependency on " library " could be avoided if " binaries " were not uselessly linked against it (they use none of its symbols)."
+None of the \fIbinaries\fP that are linked with \fPlibrary\fP use any of the
+symbols provided by the library. By fixing all the binaries, you would avoid
+the dependency associated to this library (unless the same dependency is
+also generated by another library that is really used).
+.TP
.IB binary " shouldn't be linked with " library " (it uses none of its symbols)."
The \fIbinary\fR is linked to a library that it doesn't need. It's not a
-problem but some small performance improvements in binary load time
-can be obtained by not linking this library to this binary.
-
-Furthermore, in some cases, this will lead to a non-versioned dependency
-on the library that could have been avoided if the binary was only linked
-against libraries that it really uses. The exception to this rule is
-when several binaries are linked against the same set of libraries but
-each binary only uses a subset of those. You will have warnings on
-individual binaries, but the set of libraries needed at the package level
-is the same whether you fix the binaries or not.
+problem but some small performance improvements in binary load time can be
+obtained by not linking this library to this binary. This warning checks
+the same information than the previous one but does it for each binary
+instead of doing the check globally on all binaries analyzed.
.SH ERRORS
.B dpkg\-shlibdeps
will fail if it can't find a public library used by a binary or if this
.br
Copyright (C) 2006 Frank Lichtenheld
.br
-Copyright (C) 2007 Rapha\[:e]l Hertzog
+Copyright (C) 2007-2008 Rapha\[:e]l Hertzog
.sp
This is free software; see the GNU General Public Licence version 2 or later
for copying conditions. There is NO WARRANTY.
use Dpkg::Deps;
use Dpkg::Control;
+use constant {
+ WARN_SYM_NOT_FOUND => 1,
+ WARN_DEP_AVOIDABLE => 2,
+ WARN_NOT_NEEDED => 4,
+};
+
# By increasing importance
my @depfields = qw(Suggests Recommends Depends Pre-Depends);
my $i = 0; my %depstrength = map { $_ => $i++ } @depfields;
my $varlistfile = 'debian/substvars';
my $varnameprefix = 'shlibs';
my $ignore_missing_info = 0;
+my $warnings = 3;
my $debug = 0;
my @exclude = ();
my @pkg_dir_to_search = ();
}
} elsif (m/^--ignore-missing-info$/) {
$ignore_missing_info = 1;
+ } elsif (m/^--warnings=(\d+)$/) {
+ $warnings = $1;
} elsif (m/^-t(.*)$/) {
$packagetype = $1;
} elsif (m/^-v$/) {
my %dependencies;
my %shlibs;
+# Statictics on soname seen in the whole run (with multiple analysis of
+# binaries)
+my %global_soname_notfound;
+my %global_soname_used;
+my %global_soname_needed;
+
my $cur_field;
foreach my $file (keys %exec) {
$cur_field = $exec{$file};
my $lib = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
unless (defined $lib) {
$soname_notfound{$soname} = 1;
+ $global_soname_notfound{$soname} = 1;
my $msg = _g("couldn't find library %s needed by %s (its RPATH is '%s').\n" .
"Note: libraries are not searched in other binary packages " .
"that do not have any shlibs or symbols file.\nTo help dpkg-shlibdeps " .
# Scan all undefined symbols of the binary and resolve to a
# dependency
- my %used_sonames = map { $_ => 0 } @sonames;
+ my %soname_used;
+ foreach (@sonames) {
+ # Initialize statistics
+ $soname_used{$_} = 0;
+ $global_soname_used{$_} = 0 unless exists $global_soname_used{$_};
+ if (exists $global_soname_needed{$_}) {
+ push @{$global_soname_needed{$_}}, $file;
+ } else {
+ $global_soname_needed{$_} = [ $file ];
+ }
+ }
my $nb_warnings = 0;
my $nb_skipped_warnings = 0;
# Disable warnings about missing symbols when we have not been able to
my $symdep = $symfile->lookup_symbol($name, \@sonames);
if (defined($symdep)) {
print " Found in symbols file of $symdep->{soname}\n" if $debug > 1;
- $used_sonames{$symdep->{soname}}++;
+ $soname_used{$symdep->{soname}}++;
+ $global_soname_used{$symdep->{soname}}++;
if (exists $alt_soname{$symdep->{soname}}) {
# Also count usage on alternate soname
- $used_sonames{$alt_soname{$symdep->{soname}}}++;
+ $soname_used{$alt_soname{$symdep->{soname}}}++;
+ $global_soname_used{$alt_soname{$symdep->{soname}}}++;
}
update_dependency_version($symdep->{depends},
$symdep->{minver});
my $syminfo = $dumplibs_wo_symfile->locate_symbol($name);
if (not defined($syminfo)) {
print " Not found\n" if $debug > 1;
+ next unless ($warnings & WARN_SYM_NOT_FOUND);
next if $disable_warnings;
# Complain about missing symbols only for executables
# and public libraries
print " Found in $syminfo->{soname} ($syminfo->{objid})\n" if $debug > 1;
if (exists $alt_soname{$syminfo->{soname}}) {
# Also count usage on alternate soname
- $used_sonames{$alt_soname{$syminfo->{soname}}}++;
+ $soname_used{$alt_soname{$syminfo->{soname}}}++;
+ $global_soname_used{$alt_soname{$syminfo->{soname}}}++;
}
- $used_sonames{$syminfo->{soname}}++;
+ $soname_used{$syminfo->{soname}}++;
+ $global_soname_used{$syminfo->{soname}}++;
}
}
}
}
# Warn about un-NEEDED libraries
- unless ($soname_notfound{$soname} or $used_sonames{$soname}) {
+ unless ($soname_notfound{$soname} or $soname_used{$soname}) {
# Ignore warning for libm.so.6 if also linked against libstdc++
next if ($soname =~ /^libm\.so\.\d+$/ and
scalar grep(/^libstdc\+\+\.so\.\d+/, @sonames));
+ next unless ($warnings & WARN_NOT_NEEDED);
warning(_g("%s shouldn't be linked with %s (it uses none of its " .
"symbols)."), $file, $soname);
}
}
}
+# Warn of unneeded libraries at the "package" level (i.e. over all
+# binaries that we have inspected)
+foreach my $soname (keys %global_soname_needed) {
+ unless ($global_soname_notfound{$soname} or $global_soname_used{$soname}) {
+ next if ($soname =~ /^libm\.so\.\d+$/ and scalar(
+ grep(/^libstdc\+\+\.so\.\d+/, keys %global_soname_needed)));
+ next unless ($warnings & WARN_DEP_AVOIDABLE);
+ warning(_g("dependency on %s could be avoided if \"%s\" were not " .
+ "uselessly linked against it (they use none of its " .
+ "symbols)."), $soname,
+ join(" ", @{$global_soname_needed{$soname}}));
+ }
+}
+
# Open substvars file
my $fh;
if ($stdout) {
-x<package> exclude package from the generated dependencies.
-S<pkgbuilddir> search needed libraries in the given
package build directory first.
+ -v enable verbose mode (can be used multiple times).
+ --ignore-missing-info don't fail if dependency information can't be found.
+ --warnings=<value> define set of active warnings (see manual page).
--admindir=<directory> change the administrative directory.
-h, --help show this help message.
--version show the version.