1#!/usr/bin/env perl 2use strict; 3use File::Find; 4use File::Copy; 5use Digest::MD5; 6 7my @fileTypes = ("cpp", "c"); 8my %dirFiles; 9my %dirCMake; 10 11sub 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 21sub 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 45sub 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 60sub 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 109sub UpdateCMakeFiles { 110 foreach my $dir (sort keys %dirCMake) { 111 if (UpdateCMake($dirCMake{$dir}, $dir)) { 112 print "Updated: $dir\n"; 113 } 114 } 115} 116 117find({ wanted => \&ProcessFile, follow => 1 }, '.'); 118UpdateCMakeFiles(); 119 120