Home | History | Annotate | Download | only in utils
      1 #!/usr/bin/env perl
      2 use strict;
      3 use File::Find;
      4 use File::Copy;
      5 use Digest::MD5;
      6 
      7 my @fileTypes = ("cpp", "c");
      8 my %dirFiles;
      9 my %dirCMake;
     10 
     11 sub GetFiles {
     12   my $dir = shift;
     13   my $x = $dirFiles{$dir};  
     14   if (!defined $x) {
     15     $x = [];
     16     $dirFiles{$dir} = $x;
     17   }  
     18   return $x;
     19 }
     20 
     21 sub ProcessFile {
     22   my $file = $_;
     23   my $dir = $File::Find::dir;
     24   # Record if a CMake file was found.
     25   if ($file eq "CMakeLists.txt") {
     26     $dirCMake{$dir} = $File::Find::name;
     27     return 0;
     28   }
     29   # Grab the extension of the file.
     30   $file =~ /\.([^.]+)$/;
     31   my $ext = $1;
     32   my $files;
     33   foreach my $x (@fileTypes) {
     34     if ($ext eq $x) {
     35       if (!defined $files) {
     36         $files = GetFiles($dir);
     37       }
     38       push @$files, $file;
     39       return 0;
     40     }
     41   }
     42   return 0;
     43 }
     44 
     45 sub EmitCMakeList {
     46   my $dir = shift;
     47   my $files = $dirFiles{$dir};
     48   
     49   if (!defined $files) {
     50     return;
     51   }
     52   
     53   foreach my $file (sort @$files) {
     54     print OUT "  ";
     55     print OUT $file;
     56     print OUT "\n";
     57   }  
     58 }
     59 
     60 sub UpdateCMake {
     61   my $cmakeList = shift;
     62   my $dir = shift;
     63   my $cmakeListNew = $cmakeList . ".new";
     64   open(IN, $cmakeList);
     65   open(OUT, ">", $cmakeListNew);
     66   my $foundLibrary = 0;
     67   
     68   while(<IN>) {
     69     if (!$foundLibrary) {
     70       print OUT $_;
     71       if (/^add_[^_]+_library\(/ || /^add_llvm_target\(/ || /^add_[^_]+_executable\(/) {
     72         $foundLibrary = 1;
     73         EmitCMakeList($dir);
     74       }
     75     }
     76     else {
     77       if (/\)/) {
     78         print OUT $_;
     79         $foundLibrary = 0;
     80       }
     81     }
     82   }
     83 
     84   close(IN);
     85   close(OUT);
     86 
     87   open(FILE, $cmakeList) or
     88     die("Cannot open $cmakeList when computing digest\n");
     89   binmode FILE;
     90   my $digestA = Digest::MD5->new->addfile(*FILE)->hexdigest;
     91   close(FILE);
     92     
     93   open(FILE, $cmakeListNew) or
     94     die("Cannot open $cmakeListNew when computing digest\n");
     95   binmode FILE;
     96   my $digestB = Digest::MD5->new->addfile(*FILE)->hexdigest;
     97   close(FILE);
     98   
     99   if ($digestA ne $digestB) {
    100     move($cmakeListNew, $cmakeList);
    101     return 1;    
    102   }
    103   
    104   unlink($cmakeListNew);
    105   return 0;
    106 }
    107 
    108 sub UpdateCMakeFiles {
    109   foreach my $dir (sort keys %dirCMake) {
    110     if (UpdateCMake($dirCMake{$dir}, $dir)) {
    111       print "Updated: $dir\n";
    112     }
    113   }
    114 }
    115 
    116 find({ wanted => \&ProcessFile, follow => 1 }, '.');
    117 UpdateCMakeFiles();
    118 
    119