dtneededsizerpmsone: Fix.
[massrebuild.git] / dtneededsize
1 #! /usr/bin/perl
2 use strict;
3 use warnings;
4 use File::Basename qw(&dirname);
5 use File::Find;
6 use Data::Dumper;
7
8 $|=1;
9 sub readfile {
10   my($fname)=@_;
11   local *F;
12   open F,"$fname" or die $fname;
13   local $/=undef();
14   defined(my $r=<F>) or die $fname;
15   close F or die $fname;
16   return $r;
17 }
18
19 chdir "dtneeded.out" or die "dtneeded.out: $!";
20
21 my %F;
22 my %SONAME;
23 my @DEBUG;
24 find {
25   "no_chdir"=>1,
26   "wanted"=>sub {
27     die $File::Find::dir if $File::Find::dir=~m{/$};
28     my $binfn=$File::Find::name;
29     return if !-f $binfn;
30     die $binfn if $binfn!~m{^[.]/};
31     my $bin=readfile $binfn;
32     my $rpath=($bin=~m{^.*\Q(R\E(?:UN)?\QPATH)\E\s*Library r(?:un)?path: \Q[\E(.*)\Q]\E$}m)[0];
33     if ($rpath) {
34       my $dirname=$File::Find::dir;
35       die if $dirname!~s{^[.]/}{/};
36       $rpath=~s{\$ORIGIN}{$dirname}g;
37     }
38     my $soname=($bin=~m{^.*\Q(SONAME)\E\s*Library soname: \Q[\E(.*)\Q]\E$}m)[0];
39     my $h={
40       "binfn"=>$binfn,
41       "needed"=>[$bin=~m{^\s*0x0000000000000001\s*\Q(NEEDED)\E\s*\QShared library: [\E(.*)\Q]\E$}gm],
42     };
43     $h->{"rpath"}=$rpath if $rpath;
44     $F{$binfn}=$h;
45 #    my $total=keys %F; warn "$total...\n" if 0==$total%1000;
46     if ($soname) {
47       my $ref=\$SONAME{$File::Find::dir."/".$soname};
48 #      warn "soname=<$soname> <$binfn> vs. <".$$ref->{"binfn"}.">\n" if $$ref;
49       $$ref=$h;
50     }
51     push @DEBUG,$binfn if $bin=~m{ \Q(DEBUG) \E };
52   },
53 },".";
54
55 for my $binfn (@DEBUG) {
56 #  warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]);
57   my @l=$binfn;
58   my %l=($binfn=>1);
59   while (@l) {
60     my $l=shift @l;
61     my $h=$F{$l};
62     for my $needed (@{$h->{"needed"}}) {
63       my $found;
64       if ($needed=~m{^/}) {
65         $found=$needed;
66       } else {
67 #       die "$binfn: $l: $needed" if $needed=~m{/};
68         my @rpath;
69         my $rpath=$h->{"rpath"};
70         push @rpath,split /:/,$rpath if $rpath;
71         push @rpath,qw(/lib64 /usr/lib64);
72         for my $rpath (@rpath) {
73           if ($rpath!~m{^/}) {
74             warn "$binfn: $l: $rpath";
75             next;
76           }
77           my $fn=".$rpath/$needed";
78           next if !$SONAME{$fn};
79           $found=$fn;
80           last;
81         }
82         warn "$binfn: $l: $needed not found; rpath=".join(":",@rpath)."\n" if !$found;
83       }
84       push @l,$found if $found&&!$l{$found}++;
85     }
86   }
87 #  warn "$binfn done\n".Dumper([sort keys(%l)]);
88 }