This patch does two things, one more successfully/completely than the
other:
- Use objdump instead of ldd, producing fewer bogus warnings/errors.
This part works fine, and shows no regressions that I could find.
- Handle shared libraries which are in a package produced by this
source which are not yet installed. I haven't quite got it working
in all cases yet.
Comments?
Dan
/\ /\
| Daniel Jacobowitz|__| CMU, CS class of 2002 |
| Debian GNU/Linux Developer__ Part-Time Systems Programmer |
| [EMAIL PROTECTED] | |[EMAIL PROTECTED] |
\/ \/
--- /usr/src/dpkg/dpkg-1.4.1/scripts/dpkg-shlibdeps.pl Sun Nov 1 11:07:43 1998
+++ /usr/bin/dpkg-shlibdeps Sun Dec 6 19:24:59 1998
@@ -1,7 +1,7 @@
#!/usr/bin/perl
-$dpkglibdir= ".";
-$version= '1.3.6'; # This line modified by Makefile
+$dpkglibdir= "/usr/lib/dpkg";
+$version= '1.4.1'; # This line modified by Makefile
use POSIX;
use POSIX qw(:errno_h :signal_h);
@@ -88,40 +88,79 @@
for ($i=0;$i<=$#exec;$i++) {
if (!isbin ($exec[$i])) { next; }
-defined($c= open(P,"-|")) || syserr("cannot fork for ldd");
-if (!$c) { exec("ldd","--",$exec[$i]); syserr("cannot exec ldd"); }
-$nthisldd=0;
+defined($c= open(P,"-|")) || syserr("cannot fork for objdump");
+if (!$c) { exec("objdump","-p","--",$exec[$i]); syserr("cannot exec
objdump"); }
while () {
- chomp;
- if (m,^\s+(\S+)\s+\=\>\s+\1$,) {
- # shared libraries depend on themselves (unsure why)
- # Only under old ld.so
- $nthisldd++;
- } elsif (m,\s+statically linked(\s+\(ELF\))?$,) {
- $nthisldd++;
- } elsif (m,^\s+(\S+)\.so\.(\S+)\s+=>\s+(/\S+)(\s+\(0x.+\))?$,) {
- push(@libname,$1); push(@libsoname,$2); push(@libpath,$3);
- push(@libf,$execf[$i]);
- push(@libpaths,$3) if !$libpathadded{$3}++;
- $nthisldd++;
- } else {
- &warn("unknown output from ldd on \`$exec[$i]': \`$_'");
- }
+chomp;
+if (m,^\s*NEEDED\s+(\S+)\.so\.(\S+)$,) {
+push(@libname,$1); push(@libsoname,$2);
+push(@libf,$execf[$i]);
+push(@libfiles,"$1.so.$2");
+}
+}
+close(P); $? && subprocerr("objdump on \`$exec[$i]'");
+}
+
+# Now: See if it is in this package. See if it is in any other package.
+sub searchdir {
+my $dir = shift;
+if(opendir(DIR, $dir)) {
+my @dirents = readdir(DIR);
+closedir(DIR);
+for (@dirents) {
+if ( -f "$dir/$_/DEBIAN/shlibs" ) {
+push(@curshlibs, "$dir/$_/DEBIAN/shlibs");
+last;
+} elsif ( $_ !~ /^\./ && -d "$dir/$_" ) {
+&searchdir("$dir/$_");
+}
+}
+}
+}
+
+$searchdir = $exec[0];
+$curpackdir = "debian/tmp";
+do { $searchdir =~ s,/[^/]*$,,; } while($searchdir =~ m,/, && ! -d
"$searchdir/DEBIAN");
+if ($searchdir =~ m,/,) {
+$curpackdir = $searchdir;
+$searchdir =~ s,/[^/]*,,;
+&searchdir($searchdir);
+}
+
+if ($#curshlibs >= 0) {
+PRELIB: for ($i=0;$i<=$#libname;$i++) {
+for my $shlibsfile (@curshlibs) {
+if(scanshlibsfile($shlibsfile, $libname[$i], $libsoname[$i],
$libf[$i])) {
+splice(@libname, $i, 1);
+splice(@libsoname, $i, 1);
+splice(@libf, $i, 1);
+splice(@libfiles, $i, 1);
+$i--;
+next PRELIB;
+}
+}
+if(scanshlibsfile($shlibslocal,$libname[$i],$libsoname[$i],$libf[$i])
+ ||
scanshlibsfile($shlibsoverride,$libname[$i],$libsoname[$i],$libf[$i])) {
+splice(@libname, $i, 1);
+splice(@libsoname, $i, 1);
+splice(@libf, $i, 1);
+splice(@libfiles, $i, 1);
+$i--;
+next PRELIB;
+}
}
-close(P); $? && subprocerr("ldd on \`$exec[$i]'");
-$nthisldd || &warn("ldd on \`$exec[$i]' gave nothing on standard output");
}
-if ($#libpaths >= 0) {
-grep(s/\[\?\*/\\$&/g, @libpaths);
+if ($#libfiles >= 0) {
+grep(s/\[\?\*/\\$&/g, @libname);
defined($c= open(P,"-|")) || syserr("cannot fork for dpkg --search");
-if (!$c) { exec("dpkg","--search","--",@libpaths); syserr("cannot exec
dpkg"); }
+if (!$c) { exec("dpkg","--search","--",map {"*/$_"} @libfiles);
syserr("cannot exec dpkg"); }
while () {
s/\n$//;
if (m/^local diversion |^diversion by/) {
&warn("diversions involved - output may be incorrect");
print(STDERR " $_\n") || syserr("write diversion info to stderr");
- } elsif (m=^(\S+(, \S+)*): (/.+)$=) {
+ } elsif (m=^(\S+(, \S+)*): /.+/([^/]+)$=) {
$pathpackages{$+}= $1;
} else {
&warn("unknown output from dpkg