xref: /llvm-project/llvm/utils/UpdateCMakeLists.pl (revision 68ab5ecd757c6e61593fc73adcd7e7e5e3dbef86)
1722f6508STed Kremenek#!/usr/bin/env perl
2722f6508STed Kremenekuse strict;
3722f6508STed Kremenekuse File::Find;
4722f6508STed Kremenekuse File::Copy;
5722f6508STed Kremenekuse Digest::MD5;
6722f6508STed Kremenek
7722f6508STed Kremenekmy @fileTypes = ("cpp", "c");
8722f6508STed Kremenekmy %dirFiles;
9722f6508STed Kremenekmy %dirCMake;
10722f6508STed Kremenek
11722f6508STed Kremeneksub GetFiles {
12722f6508STed Kremenek  my $dir = shift;
13722f6508STed Kremenek  my $x = $dirFiles{$dir};
14722f6508STed Kremenek  if (!defined $x) {
15722f6508STed Kremenek    $x = [];
16722f6508STed Kremenek    $dirFiles{$dir} = $x;
17722f6508STed Kremenek  }
18722f6508STed Kremenek  return $x;
19722f6508STed Kremenek}
20722f6508STed Kremenek
21722f6508STed Kremeneksub ProcessFile {
22722f6508STed Kremenek  my $file = $_;
23722f6508STed Kremenek  my $dir = $File::Find::dir;
24722f6508STed Kremenek  # Record if a CMake file was found.
25722f6508STed Kremenek  if ($file eq "CMakeLists.txt") {
26722f6508STed Kremenek    $dirCMake{$dir} = $File::Find::name;
27722f6508STed Kremenek    return 0;
28722f6508STed Kremenek  }
29722f6508STed Kremenek  # Grab the extension of the file.
30722f6508STed Kremenek  $file =~ /\.([^.]+)$/;
31722f6508STed Kremenek  my $ext = $1;
32722f6508STed Kremenek  my $files;
33722f6508STed Kremenek  foreach my $x (@fileTypes) {
34722f6508STed Kremenek    if ($ext eq $x) {
35722f6508STed Kremenek      if (!defined $files) {
36722f6508STed Kremenek        $files = GetFiles($dir);
37722f6508STed Kremenek      }
38722f6508STed Kremenek      push @$files, $file;
39722f6508STed Kremenek      return 0;
40722f6508STed Kremenek    }
41722f6508STed Kremenek  }
42722f6508STed Kremenek  return 0;
43722f6508STed Kremenek}
44722f6508STed Kremenek
45722f6508STed Kremeneksub EmitCMakeList {
46722f6508STed Kremenek  my $dir = shift;
47722f6508STed Kremenek  my $files = $dirFiles{$dir};
48722f6508STed Kremenek
49722f6508STed Kremenek  if (!defined $files) {
50722f6508STed Kremenek    return;
51722f6508STed Kremenek  }
52722f6508STed Kremenek
53722f6508STed Kremenek  foreach my $file (sort @$files) {
54722f6508STed Kremenek    print OUT "  ";
55722f6508STed Kremenek    print OUT $file;
56722f6508STed Kremenek    print OUT "\n";
57722f6508STed Kremenek  }
58722f6508STed Kremenek}
59722f6508STed Kremenek
60722f6508STed Kremeneksub UpdateCMake {
61722f6508STed Kremenek  my $cmakeList = shift;
62722f6508STed Kremenek  my $dir = shift;
63722f6508STed Kremenek  my $cmakeListNew = $cmakeList . ".new";
64722f6508STed Kremenek  open(IN, $cmakeList);
65722f6508STed Kremenek  open(OUT, ">", $cmakeListNew);
66722f6508STed Kremenek  my $foundLibrary = 0;
67722f6508STed Kremenek
68722f6508STed Kremenek  while(<IN>) {
69722f6508STed Kremenek    if (!$foundLibrary) {
70722f6508STed Kremenek      print OUT $_;
71*68ab5ecdSTed Kremenek      if (/^add_[^_]+_library\(/ || /^add_llvm_target\(/ || /^add_[^_]+_executable\(/) {
72722f6508STed Kremenek        $foundLibrary = 1;
73722f6508STed Kremenek        EmitCMakeList($dir);
74722f6508STed Kremenek      }
75722f6508STed Kremenek    }
76722f6508STed Kremenek    else {
77722f6508STed Kremenek      if (/\)/) {
78722f6508STed Kremenek        print OUT $_;
79722f6508STed Kremenek        $foundLibrary = 0;
80722f6508STed Kremenek      }
81722f6508STed Kremenek    }
82722f6508STed Kremenek  }
83722f6508STed Kremenek
84722f6508STed Kremenek  close(IN);
85722f6508STed Kremenek  close(OUT);
86722f6508STed Kremenek
87722f6508STed Kremenek  open(FILE, $cmakeList) or
88722f6508STed Kremenek    die("Cannot open $cmakeList when computing digest\n");
89722f6508STed Kremenek  binmode FILE;
90722f6508STed Kremenek  my $digestA = Digest::MD5->new->addfile(*FILE)->hexdigest;
91722f6508STed Kremenek  close(FILE);
92722f6508STed Kremenek
93722f6508STed Kremenek  open(FILE, $cmakeListNew) or
94722f6508STed Kremenek    die("Cannot open $cmakeListNew when computing digest\n");
95722f6508STed Kremenek  binmode FILE;
96722f6508STed Kremenek  my $digestB = Digest::MD5->new->addfile(*FILE)->hexdigest;
97722f6508STed Kremenek  close(FILE);
98722f6508STed Kremenek
994f9b1d03STed Kremenek  if ($digestA ne $digestB) {
100722f6508STed Kremenek    move($cmakeListNew, $cmakeList);
101722f6508STed Kremenek    return 1;
102722f6508STed Kremenek  }
103722f6508STed Kremenek
104722f6508STed Kremenek  unlink($cmakeListNew);
105722f6508STed Kremenek  return 0;
106722f6508STed Kremenek}
107722f6508STed Kremenek
108722f6508STed Kremeneksub UpdateCMakeFiles {
109722f6508STed Kremenek  foreach my $dir (sort keys %dirCMake) {
110722f6508STed Kremenek    if (UpdateCMake($dirCMake{$dir}, $dir)) {
111722f6508STed Kremenek      print "Updated: $dir\n";
112722f6508STed Kremenek    }
113722f6508STed Kremenek  }
114722f6508STed Kremenek}
115722f6508STed Kremenek
116722f6508STed Kremenekfind({ wanted => \&ProcessFile, follow => 1 }, '.');
117722f6508STed KremenekUpdateCMakeFiles();
118722f6508STed Kremenek
119