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.
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
13 # - Generates tests/test_cpp_includes.cc
14 # 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
24 # A simple regular expression that should match source files for C++ and C.
25 SOURCE_FILE_RE
= re
.compile('.+\.(cc|c|h)$')
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.
32 IGNORE_RE
= re
.compile('^(examples|GLES2|proxy|tests\/clang).*')
34 GYP_TARGETS_KEY
= 'targets'
35 GYP_SOURCES_KEY
= 'sources'
36 GYP_TARGET_NAME_KEY
= 'target_name'
39 # Return a set containing all source files found given an object read from a gyp
41 def GetAllGypSources(gyp_file_data
):
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
)
53 # Search the directory named start_root and all its subdirectories for source
55 # Return a set containing the string names of all the source files found,
56 # relative to start_root.
57 def GetFileSources(start_root
):
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
):
63 if SOURCE_FILE_RE
.match(source
):
64 file_set |
= set([os
.path
.join(relative_root
, source
)])
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
71 def 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:', \
79 if len(in_file_not_gyp
):
80 print 'Found source file(s) in the directory but not in ppapi.gyp:', \
82 error_count
= len(in_gyp_not_file
) + len(in_file_not_gyp
)
87 def WriteLines(filename
, lines
):
88 outfile
= open(filename
, 'w')
94 COPYRIGHT_STRING_C
= \
95 """/* Copyright (c) 2010 The Chromium Authors. All rights reserved.
96 * Use of this source code is governed by a BSD-style license that can be
97 * found in the LICENSE file.
99 * This test simply includes all the C headers to ensure they compile with a C
100 * compiler. If it compiles, it passes.
104 COPYRIGHT_STRING_CC
= \
105 """// Copyright (c) 2010 The Chromium Authors. All rights reserved.
106 // Use of this source code is governed by a BSD-style license that can be
107 // found in the LICENSE file.
109 // This test simply includes all the C++ headers to ensure they compile with a
110 // C++ compiler. If it compiles, it passes.
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
118 def 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
]
124 print 'Warning: no target named ', target
, ' found.'
128 # 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
133 def GenerateCIncludeTest(gyp_file_data
):
134 c_sources
= GetSourcesForTarget('ppapi_c', gyp_file_data
)
135 lines
= [COPYRIGHT_STRING_C
]
136 lines
.append('#ifndef PPAPI_TESTS_ALL_C_INCLUDES_H_\n')
137 lines
.append('#define PPAPI_TESTS_ALL_C_INCLUDES_H_\n\n')
138 for source
in c_sources
:
139 lines
.append('#include "ppapi/' + source
+ '"\n')
140 lines
.append('\n#endif /* PPAPI_TESTS_ALL_C_INCLUDES_H_ */\n')
141 WriteLines('tests/all_c_includes.h', lines
)
144 # 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.
146 def 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
]
150 lines
.append('#ifndef PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
151 lines
.append('#define PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n\n')
152 for source
in cc_sources
:
153 if header_re
.match(source
):
154 lines
.append('#include "ppapi/' + source
+ '"\n')
155 lines
.append('\n#endif // PPAPI_TESTS_ALL_CPP_INCLUDES_H_\n')
156 WriteLines('tests/all_cpp_includes.h', lines
)
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
)
169 if __name__
== '__main__':