overloop

dependencies.v2.pl

Jul 3rd, 2015
563
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.10 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use File::Basename;
  5. use File::Path qw/make_path/;
  6. use File::Copy;
  7. use Data::Dumper;
  8.  
  9. #my $qt_plugins_root = '/c/Qt/4.7.4/plugins';
  10.  
  11. my %qt_plugins = (
  12.   'home' => '/c/Qt/4.7.4/plugins',
  13.   'dirs' => {
  14.     '--imageformats' => 'imageformats',
  15.     '--sqldrivers' => 'sqldrivers'
  16.   },
  17.   'files' => {
  18.   },
  19.   'assoc' => {
  20.   }
  21. );
  22.  
  23. for my $arg (keys %{$qt_plugins{'dirs'}}) {
  24.   my $dir = $qt_plugins{'dirs'}{$arg};
  25.   my $dir_ = $qt_plugins{'home'} . '/' . $dir;
  26.   if ( -d $dir_) {
  27.     opendir(my $dh, $dir_);
  28.     my @files = grep { !/d4\.dll/ && /\.dll/ } readdir($dh);
  29.     closedir($dh);
  30.     for my $file (@files) {
  31.       my $key = '--' . $file;
  32.       $key =~ s/4?\.dll//g;
  33.       my $file_ = $dir_ . '/' . $file;
  34.       $qt_plugins{'files'}{$key} = $file_;
  35.       push(@{$qt_plugins{'assoc'}{$arg}},$file_);
  36.     }
  37.   } else {
  38.     print STDERR $dir_ . ' not exists, set $qt_plugins{"home"} please' . "\n";
  39.   }
  40. }
  41.  
  42. $qt_plugins{'files'}{'--qmysql'} = $qt_plugins{'files'}{'--qsqlmysql'};
  43. $qt_plugins{'files'}{'--qodbc'} = $qt_plugins{'files'}{'--qsqlodbc'};
  44. $qt_plugins{'files'}{'--qpsql'} = $qt_plugins{'files'}{'--qsqlpsql'};
  45.  
  46. sub my_wrap {
  47.   my @parts = @_;
  48.   my @result = ();
  49.  
  50.   my $l = 0;
  51.   my @line = ();
  52.   for my $part (@parts) {
  53.     if ($l + length($part) < 80) {
  54.       $l += length($part);
  55.       push(@line,$part);
  56.     } else {
  57.       push(@result,join('',@line));
  58.       $l = 0;
  59.       @line = ();
  60.       $l += length($part);
  61.       push(@line,$part);
  62.     }
  63.   }
  64.   push(@result,join('',@line));
  65.   return @result;
  66. }
  67.  
  68. sub usage {
  69.     print STDERR "Usage: " . $0 . " [-f] [-n] [-s] [-c] app.exe [foo.dll] [bar.dll] \n";
  70.     print STDERR "  -f print found dlls\n";
  71.     print STDERR "  -n print not found dlls\n";
  72.     print STDERR "  -s print system dlls\n";
  73.     print STDERR "  -c copy dependecies to 'distribution' directory\n";
  74.    
  75.     print STDERR "Include Qt plugins:  \n";
  76.     print STDERR "  " . join("\n  ",my_wrap(split("#",join(",#",keys %{$qt_plugins{'files'}})))) . "\n";
  77.     print STDERR "  " . join(",",keys %{$qt_plugins{'dirs'}}) . "\n";
  78.    
  79.     print STDERR "Example:\n  " . $0 . " -c myapp.exe --qmysql options.ini\n";
  80. }
  81.  
  82. sub dlls {
  83.   my ($path) = @_;
  84.   #print STDERR $path . "\n";
  85.   my %result = ();
  86.   my @deps = split("\n",`objdump -p "$path" | grep "DLL Name:"`);
  87.   for my $dep (@deps) {
  88.     if ($dep =~ /DLL Name: (.*)/) {
  89.       my $n = $1;
  90.       my $p = `which "$n"`;
  91.       $p =~ s/\n//;
  92.       $result{$n} = $p;
  93.     }
  94.   }
  95.   return %result;
  96. }
  97.  
  98. # -f found -n not found -s system
  99. #ls /c/Qt/4.7.4/plugins/sqldrivers/ | grep '.*[^d]\.dll' | sed 's,4.dll,,'
  100.  
  101. my $print_found = 0;
  102. my $print_notfound = 0;
  103. my $print_system = 0;
  104. my $copy_dependencies = 0;
  105.  
  106. my @bins = ();
  107. my %deps = ();
  108.  
  109. if (scalar(@ARGV)<1) {
  110.   usage();
  111.   exit(0);
  112. }
  113.  
  114. for my $arg (@ARGV) {
  115.   if ($arg eq '-f') {
  116.     $print_found = 1;
  117.   } elsif ($arg eq '-n') {
  118.     $print_notfound = 1;
  119.   } elsif ($arg eq '-s') {
  120.     $print_system = 1;
  121.   } elsif ($arg eq '-c') {
  122.     $copy_dependencies = 1;
  123.   } elsif ($arg eq "-h" || $arg eq "--help") {
  124.     usage();
  125.     exit(0);
  126.   } elsif ( exists $qt_plugins{'files'}{$arg} ) {
  127.     push(@bins,$qt_plugins{'files'}{$arg});
  128.   } elsif ( exists $qt_plugins{'dirs'}{$arg} ) {
  129.     push(@bins,$_) foreach @{$qt_plugins{'assoc'}{$arg}};
  130.   } elsif ( $arg =~ '^--' ) {
  131.     print STDERR 'error: undefined option ' . $arg . "\n";
  132.   } else {
  133.     push(@bins,$arg);
  134.   }
  135. }
  136.  
  137. #print join("\n",@bins) . "\n"; exit(0); #debug
  138. #print Dumper(@bins); exit(0);
  139.  
  140. if ($print_found+$print_notfound+$print_system == 0) {
  141.   $print_found = 1;
  142.   $print_notfound = 1;
  143.   $print_system = 1;
  144. }
  145.  
  146. if (scalar(@bins)==0) {
  147.   print STDERR "Error: pass executable[s] path[es].\n";
  148.   usage();
  149.   exit(-1);
  150. }
  151.  
  152. for my $bin (@bins) {
  153.   %deps = (%deps, dlls($bin));
  154. }
  155.  
  156. #my @deps_ = keys(%deps);
  157. #print join("\n",values(%deps)) . "\n";
  158.  
  159. my %complete = ();
  160. my $iscomplete = 0;
  161. while (!$iscomplete) {
  162.   $iscomplete = 1;
  163.   for my $dep (keys %deps) {
  164.     #print STDERR "dep $dep\n";
  165.     #print STDERR "exists\n" if exists $complete{$dep};
  166.     #print STDERR "matches\n" if $deps{$dep} =~ /Windows.system32/;
  167.     if (!exists $complete{$dep} && !($deps{$dep} =~ /Windows.system32/)) {
  168.       $iscomplete = 0;
  169.       my %deps_ = dlls($deps{$dep});
  170.       #print STDERR "deps for " . $deps{$dep} . ":\n" . join("\n",values(%deps_)) . "\n";
  171.       %deps = (%deps, %deps_);
  172.       $complete{$dep} = 1;
  173.     }
  174.   }
  175. }
  176.  
  177. my @found = sort map { $deps{$_} } grep { length($deps{$_}) > 0 && !($deps{$_} =~ /Windows.system32/) } keys %deps;
  178. my @notfound = sort grep { length($deps{$_}) == 0 } keys %deps;
  179. my @system = sort map { $deps{$_} } grep { $deps{$_} =~ /Windows.system32/ } keys %deps;
  180.  
  181. my $print_header = 0;
  182. if ($print_found+$print_notfound+$print_system > 1) {
  183.   $print_header = 1;
  184. }
  185. if ($print_found) {
  186.   print "FOUND DLLS:\n" if $print_header;
  187.   print join("\n",@found) . "\n" if scalar(@found)>0;
  188. }
  189. if ($print_notfound) {
  190.   print "NOT FOUND DLLS:\n" if $print_header;
  191.   print join("\n",@notfound) . "\n" if scalar(@notfound)>0;
  192. }
  193. if ($print_system) {
  194.   print "SYSTEM DLLS:\n" if $print_header;
  195.   print join("\n",@system) . "\n" if scalar(@system)>0;
  196. }
  197.  
  198. my $qt_conf = 0;
  199.  
  200. my $dest = './distribution';
  201.  
  202. if ($copy_dependencies) {
  203.   if ( ! -d $dest ) {
  204.     mkdir($dest);
  205.   }
  206.   for my $dep (@found) {
  207.     #print "cp $dep $dest\n";
  208.     copy($dep,$dest);
  209.   }
  210.   for my $bin (@bins) {
  211.     if (index($bin,$qt_plugins{'home'})>-1) {
  212.       if ($bin =~ m,.*/(plugins/.*),) {
  213.         my $dest_ = dirname($dest . '/' . $1);
  214.         #print $bin . ' dest: ' . $dest_ . "\n"; #debug
  215.         if (! -d $dest_) {
  216.           make_path($dest_);
  217.         }
  218.         copy($bin,$dest_); # @todo overwrite only if newer
  219.         $qt_conf = 1;
  220.       }
  221.     } else {
  222.       #print 'cp ' . $bin . ' ' . $dest . "\n"; #debug
  223.       copy($bin,$dest); # @todo overwrite only if newer
  224.     }
  225.   }
  226. }
  227.  
  228. if ($qt_conf) {
  229.   my $dest_ = $dest . '/qt.conf';
  230.   if ( ! -f $dest_) {
  231.     open OUTPUT,'>', $dest_;
  232.     print OUTPUT "[Paths]\nPlugins = ./plugins\n";
  233.     close OUTPUT;
  234.   }
  235. }
Advertisement
Add Comment
Please, Sign In to add comment