dtneededsize: +duplicate commons size
[massrebuild.git] / dtneededsize
index b9cdb5c..1caeb10 100755 (executable)
@@ -47,11 +47,36 @@ chdir "dtneeded.out" or die "dtneeded.out: $!";
 my %F;
 my %SONAME;
 my @DEBUG;
+my %SYMLINK;
 find {
   "no_chdir"=>1,
   "wanted"=>sub {
     die $File::Find::dir if $File::Find::dir=~m{/$};
     my $binfn=$File::Find::name;
+    if (-l $binfn) {
+      my $target=readlink $binfn or die $binfn;
+      $binfn=~s{^[.]}{};
+      my $final;
+      if ($target=~m{^/}) {
+       $final=$target;
+#warn "$binfn,target=rel=$$ref\n";
+      } else {
+       my $base=dirname(".$binfn");
+       my $abs=File::Spec->rel2abs($target,$base);
+       $final="/".File::Spec->abs2rel($abs);
+#warn "$binfn,base=$base,target=$target,abs=$abs,rel=$$ref\n";
+      }
+      1 while $final=~s{/[^/]+/[.][.]/}{/};
+      1 while $final=~s{/[^/]+/[.][.]$}{};
+      if ($final=~m{/[.][.]}) {
+       warn "$binfn,target=$target,final=$final\n";
+       return;
+      }
+      my $ref=\$SYMLINK{$binfn};
+      die if $$ref;
+      $$ref=$final;
+      return;
+    }
     return if !-f $binfn;
     die $binfn if $binfn!~m{^[.]/};
     my $bin=readfile $binfn;
@@ -69,6 +94,7 @@ find {
     };
     $h->{"rpath"}=$rpath if $rpath;
     $F{$binfn}=$h;
+#warn "$binfn=".Dumper($h)."\n" if $binfn=~/libc.so.6/;
 #    my $total=keys %F; warn "$total...\n" if 0==$total%1000;
     if ($soname) {
       my $sonamefn=$File::Find::dir."/".$soname;
@@ -81,10 +107,17 @@ find {
   },
 },".";
 
+#while (my($src,$target)=each %SYMLINK) {
+#  die "$src->$target" if exists $SYMLINK{$target};
+#}
+
 my $dwzsizeall=0;
+my $dwzsizeduplall=0;
 my $dtsizeall=0;
+my $computed=0;
 BINFN: for my $binfn (@DEBUG) {
 #  warn "$binfn...\n".Dumper([sort @{$F{$binfn}{"needed"}}]);
+  die $binfn if exists $SYMLINK{$binfn};
   my @l=$binfn;
   my %l=($binfn=>1);
   while (@l) {
@@ -93,6 +126,7 @@ BINFN: for my $binfn (@DEBUG) {
     for my $needed (@{$h->{"needed"}}) {
       my $found;
       if ($needed=~m{^/}) {
+       $needed=$SYMLINK{$needed} while exists $SYMLINK{$needed};
        $found=$needed;
       } else {
 #      die "$binfn: $l: $needed" if $needed=~m{/};
@@ -106,6 +140,7 @@ BINFN: for my $binfn (@DEBUG) {
            next;
          }
          my $fn="$rpath/$needed";
+         $fn=$SYMLINK{$fn} while exists $SYMLINK{$fn};
          next if !$SONAME{$fn};
          $found=$fn;
          last;
@@ -117,12 +152,13 @@ BINFN: for my $binfn (@DEBUG) {
   }
 #warn Dumper $binfn,\%l;
   my $dwzsizetot=0;
+  my $dwzsizedupltot=0;
   my $dtsizetot=0;
   my %dwzcommons;
   for my $l (keys(%l)) {
     my $ref=$D{$l};
     if (!defined $ref) {
-#      warn "$binfn: $l: missing\n";
+      warn "$binfn: $l: missing\n";
       next BINFN;
     }
     if (0==@$ref) {
@@ -135,21 +171,27 @@ BINFN: for my $binfn (@DEBUG) {
     my $dwzsize=$ref->[1];
     die if !defined $dwzsize;
     $dwzsizetot+=$dwzsize;
+    $dwzsizedupltot+=$dwzsize;
+    $computed++;
     my $dwzcommon=$ref->[0];
     next if $dwzcommon eq "nodwzcommon";
     die if $dwzcommon eq "isdwzcommon";
-    next if $dwzcommons{$dwzcommon}++;
+    my $duplicate=$dwzcommons{$dwzcommon}++;
     my $dwzcommonref=$D{$dwzcommon};
     die if !$dwzcommonref;
     die if $dwzcommonref->[0] ne "isdwzcommon";
     die if $dwzcommonref->[2] ne "NA";
     my $dwzcommonsize=$dwzcommonref->[1];
-    $dwzsizetot+=$dwzcommonsize;
+    $dwzsizetot+=$dwzcommonsize if !$duplicate;
+    $dwzsizedupltot+=$dwzcommonsize;
   }
   print "$binfn: dwzsizetot=$dwzsizetot dtsizetot=$dtsizetot\n";
 warn "$binfn: ".Dumper(\%dwzcommons);
   $dwzsizeall+=$dwzsizetot;
+  $dwzsizeduplall+=$dwzsizedupltot;
   $dtsizeall+=$dtsizetot;
 #  warn "$binfn done\n".Dumper([sort keys(%l)]);
 }
-print "dwzsizeall=$dwzsizeall dtsizeall=$dtsizeall\n";
+print "dwzsizeall    =$dwzsizeall"    ." dtsizeall=$dtsizeall =".$dwzsizeall    /$dtsizeall."\n";
+print "dwzsizeduplall=$dwzsizeduplall"." dtsizeall=$dtsizeall =".$dwzsizeduplall/$dtsizeall."\n";
+print "computed=$computed of DEBUG=".(0+@DEBUG)." =".$computed/@DEBUG."\n";