blob: 01711badb2cbfd146f9d15b5f56b6cae810d0e1c [file] [log] [blame]
[email protected]227b0672010-11-19 22:55:001#!/usr/bin/python
2
3# Copyright (c) 2010 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# This script should be run manually on occasion to make sure the gyp file and
8# 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
[email protected]1ad2a1db2010-12-13 20:04:3113# - Generates tests/test_cpp_includes.cc
[email protected]227b0672010-11-19 22:55:0014# These tests are checked in to SVN.
15# TODO(dmichael): Make this script execute as a gyp action, move the include
16# tests to some 'generated' area, and remove them from version
17# control.
18
19import re
20import os
21import sys
22import posixpath
23
24# A simple regular expression that should match source files for C++ and C.
25SOURCE_FILE_RE = re.compile('.+\.(cc|c|h)$')
26
27# IGNORE_RE is a regular expression that matches directories which contain
28# source that we don't (currently) expect to be in ppapi.gyp. This script will
29# not check whether source files under these directories are in the gyp file.
30# TODO(dmichael): Put examples back in the build.
31# TODO(brettw): Put proxy in the build when it's ready.
[email protected]1ad2a1db2010-12-13 20:04:3132IGNORE_RE = re.compile('^(examples|GLES2|proxy|tests\/clang).*')
[email protected]227b0672010-11-19 22:55:0033
34GYP_TARGETS_KEY = 'targets'
35GYP_SOURCES_KEY = 'sources'
36GYP_TARGET_NAME_KEY = 'target_name'
37
38
39# Return a set containing all source files found given an object read from a gyp
40# file.
41def GetAllGypSources(gyp_file_data):
42 sources = set([])
43 for target in gyp_file_data[GYP_TARGETS_KEY]:
44 # Get a list of sources in the target that are not ignored, and 'normalize'
45 # them. The main reason for this is to turn the forward slashes in the gyp
46 # file in to backslashes when the script is run on Windows.
47 source_list = [posixpath.normpath(src) for src in target[GYP_SOURCES_KEY]
48 if not IGNORE_RE.match(src)]
49 sources |= set(source_list)
50 return sources
51
52
53# Search the directory named start_root and all its subdirectories for source
54# files.
55# Return a set containing the string names of all the source files found,
56# relative to start_root.
57def GetFileSources(start_root):
58 file_set = set([])
59 for root, dirs, files in os.walk(start_root):
60 relative_root = os.path.relpath(root, start_root)
61 if not IGNORE_RE.match(relative_root):
62 for source in files:
63 if SOURCE_FILE_RE.match(source):
64 file_set |= set([os.path.join(relative_root, source)])
65 return file_set
66
67
68# Make sure all source files are in the given gyp object (evaluated from a gyp
69# file), and that all source files listed in the gyp object exist in the
70# directory.
71def VerifyGypFile(gyp_file_data):
72 gyp_sources = GetAllGypSources(gyp_file_data)
73 file_sources = GetFileSources('.')
74 in_gyp_not_file = gyp_sources - file_sources
75 in_file_not_gyp = file_sources - gyp_sources
76 if len(in_gyp_not_file):
77 print 'Found source file(s) in ppapi.gyp but not in the directory:', \
78 in_gyp_not_file
79 if len(in_file_not_gyp):
80 print 'Found source file(s) in the directory but not in ppapi.gyp:', \
81 in_file_not_gyp
82 error_count = len(in_gyp_not_file) + len(in_file_not_gyp)
83 if error_count:
84 sys.exit(error_count)
85
86
87def WriteLines(filename, lines):
88 outfile = open(filename, 'w')
89 for line in lines:
90 outfile.write(line)
91 outfile.write('\n')
92
93
94COPYRIGHT_STRING_C = \
[email protected]1ad2a1db2010-12-13 20:04:3195"""/* Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]227b0672010-11-19 22:55:0096 * Use of this source code is governed by a BSD-style license that can be
97 * found in the LICENSE file.
98 *
99 * This test simply includes all the C headers to ensure they compile with a C
100 * compiler. If it compiles, it passes.
101 */
102"""
103
104COPYRIGHT_STRING_CC = \
[email protected]1ad2a1db2010-12-13 20:04:31105"""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]227b0672010-11-19 22:55:00106// Use of this source code is governed by a BSD-style license that can be
107// found in the LICENSE file.
108//
109// This test simply includes all the C++ headers to ensure they compile with a
110// C++ compiler. If it compiles, it passes.
111//
112"""
113
114
115# Get the source file names out of the given gyp file data object (as evaluated
116# from a gyp file) for the given target name. Return the string names in
117# sorted order.
118def GetSourcesForTarget(target_name, gyp_file_data):
119 for target in gyp_file_data[GYP_TARGETS_KEY]:
120 if target[GYP_TARGET_NAME_KEY] == target_name:
121 sources = target[GYP_SOURCES_KEY]
122 sources.sort()
123 return sources
124 print 'Warning: no target named ', target, ' found.'
125 return []
126
127
[email protected]1ad2a1db2010-12-13 20:04:31128# Generate all_c_includes.h, which includes all C headers. This is part of
129# tests/test_c_sizes.c, which includes all C API files to ensure that all
130# the headers in ppapi/c can be compiled with a C compiler, and also asserts
131# (with compile-time assertions) that all structs and enums are a particular
132# size.
[email protected]227b0672010-11-19 22:55:00133def GenerateCIncludeTest(gyp_file_data):
134 c_sources = GetSourcesForTarget('ppapi_c', gyp_file_data)
135 lines = [COPYRIGHT_STRING_C]
[email protected]1ad2a1db2010-12-13 20:04:31136 lines.append('#ifndef PPAPI_TESTS_ALL_C_INCLUDES_H_\n')
137 lines.append('#define PPAPI_TESTS_ALL_C_INCLUDES_H_\n\n')
[email protected]227b0672010-11-19 22:55:00138 for source in c_sources:
139 lines.append('#include "ppapi/' + source + '"\n')
[email protected]1ad2a1db2010-12-13 20:04:31140 lines.append('\n#endif /* PPAPI_TESTS_ALL_C_INCLUDES_H_ */\n')
141 WriteLines('tests/all_c_includes.h', lines)
[email protected]227b0672010-11-19 22:55:00142
143
[email protected]1ad2a1db2010-12-13 20:04:31144# Generate all_cpp_includes.h, which is used by test_cpp_includes.cc to ensure
145# that all the headers in ppapi/cpp can be compiled with a C++ compiler.
[email protected]227b0672010-11-19 22:55:00146def GenerateCCIncludeTest(gyp_file_data):
147 cc_sources = GetSourcesForTarget('ppapi_cpp_objects', gyp_file_data)
148 header_re = re.compile('.+\.h$')
149 lines = [COPYRIGHT_STRING_CC]
[email protected]1ad2a1db2010-12-13 20:04:31150 lines.append('#ifndef PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
151 lines.append('#define PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n\n')
[email protected]227b0672010-11-19 22:55:00152 for source in cc_sources:
153 if header_re.match(source):
154 lines.append('#include "ppapi/' + source + '"\n')
[email protected]1ad2a1db2010-12-13 20:04:31155 lines.append('\n#endif // PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
156 WriteLines('tests/all_cpp_includes.h', lines)
[email protected]227b0672010-11-19 22:55:00157
158
159def main():
160 ppapi_gyp_file_name = 'ppapi.gyp'
161 gyp_file_contents = open(ppapi_gyp_file_name).read()
162 gyp_file_data = eval(gyp_file_contents)
163 VerifyGypFile(gyp_file_data)
164 GenerateCIncludeTest(gyp_file_data)
165 GenerateCCIncludeTest(gyp_file_data)
166 return 0
167
168
169if __name__ == '__main__':
170 sys.exit(main())
171