119 lines · plain
1#!/usr/bin/env perl2use 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_[^_]+_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) or88 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) or94 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 108sub UpdateCMakeFiles {109 foreach my $dir (sort keys %dirCMake) {110 if (UpdateCMake($dirCMake{$dir}, $dir)) {111 print "Updated: $dir\n";112 }113 }114}115 116find({ wanted => \&ProcessFile, follow => 1 }, '.');117UpdateCMakeFiles();118 119