120 lines
2.2 KiB
Perl
120 lines
2.2 KiB
Perl
|
#!/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(<IN>) {
|
||
|
if (!$foundLibrary) {
|
||
|
print OUT $_;
|
||
|
if (/^add_clang_library\(/ || /^add_llvm_library\(/ || /^add_llvm_target\(/
|
||
|
|| /^add_executable\(/) {
|
||
|
$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 ne $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();
|
||
|
|