diff --git a/utils/UpdateCMakeLists.pl b/utils/UpdateCMakeLists.pl new file mode 100755 index 00000000000..94e69ce2556 --- /dev/null +++ b/utils/UpdateCMakeLists.pl @@ -0,0 +1,118 @@ +#!/usr/bin/env perl +use strict; +use File::Find; +use File::Copy; +use Digest::MD5; + +my @fileTypes = ("cpp", "c"); +my %dirFiles; +my %dirCMake; + +sub GetFiles { + my $dir = shift; + my $x = $dirFiles{$dir}; + if (!defined $x) { + $x = []; + $dirFiles{$dir} = $x; + } + return $x; +} + +sub ProcessFile { + my $file = $_; + my $dir = $File::Find::dir; + # Record if a CMake file was found. + if ($file eq "CMakeLists.txt") { + $dirCMake{$dir} = $File::Find::name; + return 0; + } + # Grab the extension of the file. + $file =~ /\.([^.]+)$/; + my $ext = $1; + my $files; + foreach my $x (@fileTypes) { + if ($ext eq $x) { + if (!defined $files) { + $files = GetFiles($dir); + } + push @$files, $file; + return 0; + } + } + return 0; +} + +sub EmitCMakeList { + my $dir = shift; + my $files = $dirFiles{$dir}; + + if (!defined $files) { + return; + } + + foreach my $file (sort @$files) { + print OUT " "; + print OUT $file; + print OUT "\n"; + } +} + +sub UpdateCMake { + my $cmakeList = shift; + my $dir = shift; + my $cmakeListNew = $cmakeList . ".new"; + open(IN, $cmakeList); + open(OUT, ">", $cmakeListNew); + my $foundLibrary = 0; + + while() { + if (!$foundLibrary) { + print OUT $_; + if (/^add_clang_library\(/ || /^add_llvm_library\(/) { + $foundLibrary = 1; + EmitCMakeList($dir); + } + } + else { + if (/\)/) { + print OUT $_; + $foundLibrary = 0; + } + } + } + + close(IN); + close(OUT); + + open(FILE, $cmakeList) or + die("Cannot open $cmakeList when computing digest\n"); + binmode FILE; + my $digestA = Digest::MD5->new->addfile(*FILE)->hexdigest; + close(FILE); + + open(FILE, $cmakeListNew) or + die("Cannot open $cmakeListNew when computing digest\n"); + binmode FILE; + my $digestB = Digest::MD5->new->addfile(*FILE)->hexdigest; + close(FILE); + + if ($digestA != $digestB) { + move($cmakeListNew, $cmakeList); + return 1; + } + + unlink($cmakeListNew); + return 0; +} + +sub UpdateCMakeFiles { + foreach my $dir (sort keys %dirCMake) { + if (UpdateCMake($dirCMake{$dir}, $dir)) { + print "Updated: $dir\n"; + } + } +} + +find({ wanted => \&ProcessFile, follow => 1 }, '.'); +UpdateCMakeFiles(); +