Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ppapi / generate_ppapi_include_tests.py
blob97daf246c5e9a84ee12488ca58bf5c9308d99f2e
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """This script should be run manually on occasion to make sure the gyp file and
7 the includes tests are up to date.
9 It does the following:
10 - Verifies that all source code is in ppapi.gyp
11 - Verifies that all sources in ppapi.gyp really do exist
12 - Generates tests/test_c_includes.c
13 - Generates tests/test_cpp_includes.cc
14 These tests are checked in to SVN.
15 """
16 # TODO(dmichael): Make this script execute as a gyp action, move the include
17 # tests to some 'generated' area, and remove them from version
18 # control.
20 import re
21 import os
22 import sys
23 import posixpath
25 # A simple regular expression that should match source files for C++ and C.
26 SOURCE_FILE_RE = re.compile('.+\.(cc|c|h)$')
28 # IGNORE_RE is a regular expression that matches directories which contain
29 # source that we don't (currently) expect to be in ppapi.gyp. This script will
30 # not check whether source files under these directories are in the gyp file.
31 # TODO(dmichael): Put examples back in the build.
32 # TODO(brettw): Put proxy in the build when it's ready.
33 IGNORE_RE = re.compile('^(examples|GLES2|proxy|tests\/clang).*')
35 GYP_TARGETS_KEY = 'targets'
36 GYP_SOURCES_KEY = 'sources'
37 GYP_TARGET_NAME_KEY = 'target_name'
40 # Return a set containing all source files found given an object read from a gyp
41 # file.
42 def GetAllGypSources(gyp_file_data):
43 sources = set([])
44 for target in gyp_file_data[GYP_TARGETS_KEY]:
45 # Get a list of sources in the target that are not ignored, and 'normalize'
46 # them. The main reason for this is to turn the forward slashes in the gyp
47 # file in to backslashes when the script is run on Windows.
48 source_list = [posixpath.normpath(src) for src in target[GYP_SOURCES_KEY]
49 if not IGNORE_RE.match(src)]
50 sources |= set(source_list)
51 return sources
54 # Search the directory named start_root and all its subdirectories for source
55 # files.
56 # Return a set containing the string names of all the source files found,
57 # relative to start_root.
58 def GetFileSources(start_root):
59 file_set = set([])
60 for root, dirs, files in os.walk(start_root):
61 relative_root = os.path.relpath(root, start_root)
62 if not IGNORE_RE.match(relative_root):
63 for source in files:
64 if SOURCE_FILE_RE.match(source):
65 file_set |= set([os.path.join(relative_root, source)])
66 return file_set
69 # Make sure all source files are in the given gyp object (evaluated from a gyp
70 # file), and that all source files listed in the gyp object exist in the
71 # directory.
72 def VerifyGypFile(gyp_file_data):
73 gyp_sources = GetAllGypSources(gyp_file_data)
74 file_sources = GetFileSources('.')
75 in_gyp_not_file = gyp_sources - file_sources
76 in_file_not_gyp = file_sources - gyp_sources
77 if len(in_gyp_not_file):
78 print 'Found source file(s) in ppapi.gyp but not in the directory:', \
79 in_gyp_not_file
80 if len(in_file_not_gyp):
81 print 'Found source file(s) in the directory but not in ppapi.gyp:', \
82 in_file_not_gyp
83 error_count = len(in_gyp_not_file) + len(in_file_not_gyp)
84 if error_count:
85 sys.exit(error_count)
88 def WriteLines(filename, lines):
89 outfile = open(filename, 'w')
90 for line in lines:
91 outfile.write(line)
92 outfile.write('\n')
95 COPYRIGHT_STRING_C = \
96 """/* Copyright (c) 2010 The Chromium Authors. All rights reserved.
97 * Use of this source code is governed by a BSD-style license that can be
98 * found in the LICENSE file.
100 * This test simply includes all the C headers to ensure they compile with a C
101 * compiler. If it compiles, it passes.
105 COPYRIGHT_STRING_CC = \
106 """// Copyright (c) 2010 The Chromium Authors. All rights reserved.
107 // Use of this source code is governed by a BSD-style license that can be
108 // found in the LICENSE file.
110 // This test simply includes all the C++ headers to ensure they compile with a
111 // C++ compiler. If it compiles, it passes.
116 # Get the source file names out of the given gyp file data object (as evaluated
117 # from a gyp file) for the given target name. Return the string names in
118 # sorted order.
119 def GetSourcesForTarget(target_name, gyp_file_data):
120 for target in gyp_file_data[GYP_TARGETS_KEY]:
121 if target[GYP_TARGET_NAME_KEY] == target_name:
122 sources = target[GYP_SOURCES_KEY]
123 sources.sort()
124 return sources
125 print 'Warning: no target named ', target, ' found.'
126 return []
129 # Generate all_c_includes.h, which includes all C headers. This is part of
130 # tests/test_c_sizes.c, which includes all C API files to ensure that all
131 # the headers in ppapi/c can be compiled with a C compiler, and also asserts
132 # (with compile-time assertions) that all structs and enums are a particular
133 # size.
134 def GenerateCIncludeTest(gyp_file_data):
135 c_sources = GetSourcesForTarget('ppapi_c', gyp_file_data)
136 lines = [COPYRIGHT_STRING_C]
137 lines.append('#ifndef PPAPI_TESTS_ALL_C_INCLUDES_H_\n')
138 lines.append('#define PPAPI_TESTS_ALL_C_INCLUDES_H_\n\n')
139 for source in c_sources:
140 lines.append('#include "ppapi/' + source + '"\n')
141 lines.append('\n#endif /* PPAPI_TESTS_ALL_C_INCLUDES_H_ */\n')
142 WriteLines('tests/all_c_includes.h', lines)
145 # Generate all_cpp_includes.h, which is used by test_cpp_includes.cc to ensure
146 # that all the headers in ppapi/cpp can be compiled with a C++ compiler.
147 def GenerateCCIncludeTest(gyp_file_data):
148 cc_sources = GetSourcesForTarget('ppapi_cpp_objects', gyp_file_data)
149 header_re = re.compile('.+\.h$')
150 lines = [COPYRIGHT_STRING_CC]
151 lines.append('#ifndef PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
152 lines.append('#define PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n\n')
153 for source in cc_sources:
154 if header_re.match(source):
155 lines.append('#include "ppapi/' + source + '"\n')
156 lines.append('\n#endif // PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
157 WriteLines('tests/all_cpp_includes.h', lines)
160 def main():
161 ppapi_gyp_file_name = 'ppapi.gyp'
162 gyp_file_contents = open(ppapi_gyp_file_name).read()
163 gyp_file_data = eval(gyp_file_contents)
164 VerifyGypFile(gyp_file_data)
165 GenerateCIncludeTest(gyp_file_data)
166 GenerateCCIncludeTest(gyp_file_data)
167 return 0
170 if __name__ == '__main__':
171 sys.exit(main())