blob: f690f3eacc00106732d7c1890d888f82d161e99e [file] [log] [blame]
[email protected]2ec654a2012-01-10 17:47:001#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]227b0672010-11-19 22:55:003# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
[email protected]2ec654a2012-01-10 17:47:006"""This script should be run manually on occasion to make sure the gyp file and
7the includes tests are up to date.
8
9It 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
14These tests are checked in to SVN.
15"""
[email protected]227b0672010-11-19 22:55:0016# 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.
19
Raul Tambrea4895d82019-04-08 19:18:2620from __future__ import print_function
21
[email protected]227b0672010-11-19 22:55:0022import re
23import os
24import sys
25import posixpath
26
27# A simple regular expression that should match source files for C++ and C.
28SOURCE_FILE_RE = re.compile('.+\.(cc|c|h)$')
29
30# IGNORE_RE is a regular expression that matches directories which contain
31# source that we don't (currently) expect to be in ppapi.gyp. This script will
32# not check whether source files under these directories are in the gyp file.
33# TODO(dmichael): Put examples back in the build.
34# TODO(brettw): Put proxy in the build when it's ready.
[email protected]1ad2a1db2010-12-13 20:04:3135IGNORE_RE = re.compile('^(examples|GLES2|proxy|tests\/clang).*')
[email protected]227b0672010-11-19 22:55:0036
37GYP_TARGETS_KEY = 'targets'
38GYP_SOURCES_KEY = 'sources'
39GYP_TARGET_NAME_KEY = 'target_name'
40
41
42# Return a set containing all source files found given an object read from a gyp
43# file.
44def GetAllGypSources(gyp_file_data):
45 sources = set([])
46 for target in gyp_file_data[GYP_TARGETS_KEY]:
47 # Get a list of sources in the target that are not ignored, and 'normalize'
48 # them. The main reason for this is to turn the forward slashes in the gyp
49 # file in to backslashes when the script is run on Windows.
50 source_list = [posixpath.normpath(src) for src in target[GYP_SOURCES_KEY]
51 if not IGNORE_RE.match(src)]
52 sources |= set(source_list)
53 return sources
54
55
56# Search the directory named start_root and all its subdirectories for source
57# files.
58# Return a set containing the string names of all the source files found,
59# relative to start_root.
60def GetFileSources(start_root):
61 file_set = set([])
62 for root, dirs, files in os.walk(start_root):
63 relative_root = os.path.relpath(root, start_root)
64 if not IGNORE_RE.match(relative_root):
65 for source in files:
66 if SOURCE_FILE_RE.match(source):
67 file_set |= set([os.path.join(relative_root, source)])
68 return file_set
69
70
71# Make sure all source files are in the given gyp object (evaluated from a gyp
72# file), and that all source files listed in the gyp object exist in the
73# directory.
74def VerifyGypFile(gyp_file_data):
75 gyp_sources = GetAllGypSources(gyp_file_data)
76 file_sources = GetFileSources('.')
77 in_gyp_not_file = gyp_sources - file_sources
78 in_file_not_gyp = file_sources - gyp_sources
79 if len(in_gyp_not_file):
Raul Tambrea4895d82019-04-08 19:18:2680 print('Found source file(s) in ppapi.gyp but not in the directory:', \
81 in_gyp_not_file)
[email protected]227b0672010-11-19 22:55:0082 if len(in_file_not_gyp):
Raul Tambrea4895d82019-04-08 19:18:2683 print('Found source file(s) in the directory but not in ppapi.gyp:', \
84 in_file_not_gyp)
[email protected]227b0672010-11-19 22:55:0085 error_count = len(in_gyp_not_file) + len(in_file_not_gyp)
86 if error_count:
87 sys.exit(error_count)
88
89
90def WriteLines(filename, lines):
91 outfile = open(filename, 'w')
92 for line in lines:
93 outfile.write(line)
94 outfile.write('\n')
95
96
97COPYRIGHT_STRING_C = \
[email protected]1ad2a1db2010-12-13 20:04:3198"""/* Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]227b0672010-11-19 22:55:0099 * Use of this source code is governed by a BSD-style license that can be
100 * found in the LICENSE file.
101 *
102 * This test simply includes all the C headers to ensure they compile with a C
103 * compiler. If it compiles, it passes.
104 */
105"""
106
107COPYRIGHT_STRING_CC = \
[email protected]1ad2a1db2010-12-13 20:04:31108"""// Copyright (c) 2010 The Chromium Authors. All rights reserved.
[email protected]227b0672010-11-19 22:55:00109// Use of this source code is governed by a BSD-style license that can be
110// found in the LICENSE file.
111//
112// This test simply includes all the C++ headers to ensure they compile with a
113// C++ compiler. If it compiles, it passes.
114//
115"""
116
117
118# Get the source file names out of the given gyp file data object (as evaluated
119# from a gyp file) for the given target name. Return the string names in
120# sorted order.
121def GetSourcesForTarget(target_name, gyp_file_data):
122 for target in gyp_file_data[GYP_TARGETS_KEY]:
123 if target[GYP_TARGET_NAME_KEY] == target_name:
124 sources = target[GYP_SOURCES_KEY]
125 sources.sort()
126 return sources
Raul Tambrea4895d82019-04-08 19:18:26127 print('Warning: no target named ', target, ' found.')
[email protected]227b0672010-11-19 22:55:00128 return []
129
130
[email protected]1ad2a1db2010-12-13 20:04:31131# Generate all_c_includes.h, which includes all C headers. This is part of
132# tests/test_c_sizes.c, which includes all C API files to ensure that all
133# the headers in ppapi/c can be compiled with a C compiler, and also asserts
134# (with compile-time assertions) that all structs and enums are a particular
135# size.
[email protected]227b0672010-11-19 22:55:00136def GenerateCIncludeTest(gyp_file_data):
137 c_sources = GetSourcesForTarget('ppapi_c', gyp_file_data)
138 lines = [COPYRIGHT_STRING_C]
[email protected]1ad2a1db2010-12-13 20:04:31139 lines.append('#ifndef PPAPI_TESTS_ALL_C_INCLUDES_H_\n')
140 lines.append('#define PPAPI_TESTS_ALL_C_INCLUDES_H_\n\n')
[email protected]227b0672010-11-19 22:55:00141 for source in c_sources:
142 lines.append('#include "ppapi/' + source + '"\n')
[email protected]1ad2a1db2010-12-13 20:04:31143 lines.append('\n#endif /* PPAPI_TESTS_ALL_C_INCLUDES_H_ */\n')
144 WriteLines('tests/all_c_includes.h', lines)
[email protected]227b0672010-11-19 22:55:00145
146
[email protected]1ad2a1db2010-12-13 20:04:31147# Generate all_cpp_includes.h, which is used by test_cpp_includes.cc to ensure
148# that all the headers in ppapi/cpp can be compiled with a C++ compiler.
[email protected]227b0672010-11-19 22:55:00149def GenerateCCIncludeTest(gyp_file_data):
150 cc_sources = GetSourcesForTarget('ppapi_cpp_objects', gyp_file_data)
151 header_re = re.compile('.+\.h$')
152 lines = [COPYRIGHT_STRING_CC]
[email protected]1ad2a1db2010-12-13 20:04:31153 lines.append('#ifndef PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
154 lines.append('#define PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n\n')
[email protected]227b0672010-11-19 22:55:00155 for source in cc_sources:
156 if header_re.match(source):
157 lines.append('#include "ppapi/' + source + '"\n')
[email protected]1ad2a1db2010-12-13 20:04:31158 lines.append('\n#endif // PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
159 WriteLines('tests/all_cpp_includes.h', lines)
[email protected]227b0672010-11-19 22:55:00160
161
162def main():
163 ppapi_gyp_file_name = 'ppapi.gyp'
164 gyp_file_contents = open(ppapi_gyp_file_name).read()
165 gyp_file_data = eval(gyp_file_contents)
166 VerifyGypFile(gyp_file_data)
167 GenerateCIncludeTest(gyp_file_data)
168 GenerateCCIncludeTest(gyp_file_data)
169 return 0
170
171
172if __name__ == '__main__':
Raul Tambrea4895d82019-04-08 19:18:26173 sys.exit(main())