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_clang_library\(/ || /^add_llvm_library\(/ || /^add_llvm_target\(/
     72           || /^add_executable\(/) {
     73         $foundLibrary = 1;
     74         EmitCMakeList($dir);
     75       }
     76     }
     77     else {
     78       if (/\)/) {
     79         print OUT $_;
     80         $foundLibrary = 0;
     81       }
     82     }
     83   }
     84 
     85   close(IN);
     86   close(OUT);
     87 
     88   open(FILE, $cmakeList) or
     89     die("Cannot open $cmakeList when computing digest\n");
     90   binmode FILE;
     91   my $digestA = Digest::MD5->new->addfile(*FILE)->hexdigest;
     92   close(FILE);
     93     
     94   open(FILE, $cmakeListNew) or
     95     die("Cannot open $cmakeListNew when computing digest\n");
     96   binmode FILE;
     97   my $digestB = Digest::MD5->new->addfile(*FILE)->hexdigest;
     98   close(FILE);
     99   
    100   if ($digestA ne $digestB) {
    101     move($cmakeListNew, $cmakeList);
    102     return 1;    
    103   }
    104   
    105   unlink($cmakeListNew);
    106   return 0;
    107 }
    108 
    109 sub UpdateCMakeFiles {
    110   foreach my $dir (sort keys %dirCMake) {
    111     if (UpdateCMake($dirCMake{$dir}, $dir)) {
    112       print "Updated: $dir\n";
    113     }
    114   }
    115 }
    116 
    117 find({ wanted => \&ProcessFile, follow => 1 }, '.');
    118 UpdateCMakeFiles();
    119 
    120