[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / utils / gn / build / sync_source_lists_from_cmake.py
blobfd1e695468a8f7d9b841aa9bfed633775b77846b
1 #!/usr/bin/env python
3 """Helps to keep BUILD.gn files in sync with the corresponding CMakeLists.txt.
5 For each BUILD.gn file in the tree, checks if the list of cpp files in
6 it is identical to the list of cpp files in the corresponding CMakeLists.txt
7 file, and prints the difference if not.
9 Also checks that each CMakeLists.txt file below unittests/ folders that define
10 binaries have corresponding BUILD.gn files.
11 """
13 from __future__ import print_function
15 import os
16 import re
17 import subprocess
18 import sys
21 def sync_source_lists():
22 # Use shell=True on Windows in case git is a bat file.
23 gn_files = subprocess.check_output(['git', 'ls-files', '*BUILD.gn'],
24 shell=os.name == 'nt').splitlines()
26 # Matches e.g. | "foo.cpp",|, captures |foo| in group 1.
27 gn_cpp_re = re.compile(r'^\s*"([^"]+\.(?:cpp|c|h|S))",$', re.MULTILINE)
28 # Matches e.g. | foo.cpp|, captures |foo| in group 1.
29 cmake_cpp_re = re.compile(r'^\s*([A-Za-z_0-9./-]+\.(?:cpp|c|h|S))$',
30 re.MULTILINE)
32 changed = False
33 for gn_file in gn_files:
34 # The CMakeLists.txt for llvm/utils/gn/secondary/foo/BUILD.gn is
35 # directly at foo/CMakeLists.txt.
36 strip_prefix = 'llvm/utils/gn/secondary/'
37 if not gn_file.startswith(strip_prefix):
38 continue
39 cmake_file = os.path.join(
40 os.path.dirname(gn_file[len(strip_prefix):]), 'CMakeLists.txt')
41 if not os.path.exists(cmake_file):
42 continue
44 def get_sources(source_re, text):
45 return set([m.group(1) for m in source_re.finditer(text)])
46 gn_cpp = get_sources(gn_cpp_re, open(gn_file).read())
47 cmake_cpp = get_sources(cmake_cpp_re, open(cmake_file).read())
49 if gn_cpp == cmake_cpp:
50 continue
52 changed = True
53 print(gn_file)
54 add = sorted(cmake_cpp - gn_cpp)
55 if add:
56 print('add:\n' + '\n'.join(' "%s",' % a for a in add))
57 remove = sorted(gn_cpp - cmake_cpp)
58 if remove:
59 print('remove:\n' + '\n'.join(remove))
60 print()
61 return changed
64 def sync_unittests():
65 # Matches e.g. |add_llvm_unittest_with_input_files|.
66 unittest_re = re.compile(r'^add_\S+_unittest', re.MULTILINE)
68 checked = [ 'clang', 'clang-tools-extra', 'lld', 'llvm' ]
69 changed = False
70 for c in checked:
71 for root, _, _ in os.walk(os.path.join(c, 'unittests')):
72 cmake_file = os.path.join(root, 'CMakeLists.txt')
73 if not os.path.exists(cmake_file):
74 continue
75 if not unittest_re.search(open(cmake_file).read()):
76 continue # Skip CMake files that just add subdirectories.
77 gn_file = os.path.join('llvm/utils/gn/secondary', root, 'BUILD.gn')
78 if not os.path.exists(gn_file):
79 changed = True
80 print('missing GN file %s for unittest CMake file %s' %
81 (gn_file, cmake_file))
82 return changed
85 def main():
86 src = sync_source_lists()
87 tests = sync_unittests()
88 if src or tests:
89 sys.exit(1)
93 if __name__ == '__main__':
94 main()