Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / tools / check_ecs_deps / check_ecs_deps.py
blobf6760d65b5f0af134cd62c69719c239ced6d3ca1
1 #!/usr/bin/env python
2 # Copyright 2013 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 ''' Verifies that builds of the embedded content_shell do not included
7 unnecessary dependencies.'''
9 import os
10 import re
11 import string
12 import subprocess
13 import sys
14 import optparse
16 kUndesiredLibraryList = [
17 'libX11',
18 'libXau',
19 'libXcomposite',
20 'libXcursor',
21 'libXdamage',
22 'libXdmcp',
23 'libXext',
24 'libXfixes',
25 'libXi',
26 'libXrandr',
27 'libXrender',
28 'libXtst',
29 'libasound',
30 'libcairo',
31 'libdbus',
32 'libffi',
33 'libgconf',
34 'libgio',
35 'libglib',
36 'libgmodule',
37 'libgobject',
38 'libpango',
39 'libpcre',
40 'libpixman',
41 'libpng',
42 'libresolv',
43 'libselinux',
44 'libudev',
45 'libxcb',
48 kAllowedLibraryList = [
49 # Toolchain libraries (gcc/glibc)
50 'ld-linux',
51 'libc',
52 'libdl',
53 'libgcc_s',
54 'libm',
55 'libpthread',
56 'librt',
57 'libstdc++',
58 'linux-vdso',
60 # Needed for default ozone platforms
61 'libdrm',
63 # NSS & NSPR
64 'libnss3',
65 'libnssutil3',
66 'libnspr4',
67 'libplc4',
68 'libplds4',
69 'libsmime3',
71 # Miscellaneous
72 'libcap',
73 'libexpat',
74 'libfontconfig',
75 'libz',
78 binary_target = 'content_shell'
80 def stdmsg(_final, errors):
81 if errors:
82 for message in errors:
83 print message
85 def bbmsg(final, errors):
86 if errors:
87 for message in errors:
88 print '@@@STEP_TEXT@%s@@@' % message
89 if final:
90 print '\n@@@STEP_%s@@@' % final
93 def _main():
94 output = {
95 'message': lambda x: stdmsg(None, x),
96 'fail': lambda x: stdmsg('FAILED', x),
97 'warn': lambda x: stdmsg('WARNING', x),
98 'abend': lambda x: stdmsg('FAILED', x),
99 'ok': lambda x: stdmsg('SUCCESS', x),
100 'verbose': lambda x: None,
103 parser = optparse.OptionParser(
104 "usage: %prog -b <dir> --target <Debug|Release>")
105 parser.add_option("", "--annotate", dest='annotate', action='store_true',
106 default=False, help="include buildbot annotations in output")
107 parser.add_option("", "--noannotate", dest='annotate', action='store_false')
108 parser.add_option("-b", "--build-dir",
109 help="the location of the compiler output")
110 parser.add_option("--target", help="Debug or Release")
111 parser.add_option('-v', '--verbose', default=False, action='store_true')
113 options, args = parser.parse_args()
114 if args:
115 parser.usage()
116 return -1
118 # Bake target into build_dir.
119 if options.target and options.build_dir:
120 assert (options.target !=
121 os.path.basename(os.path.dirname(options.build_dir)))
122 options.build_dir = os.path.join(os.path.abspath(options.build_dir),
123 options.target)
125 if options.build_dir != None:
126 build_dir = os.path.abspath(options.build_dir)
127 else:
128 build_dir = os.getcwd()
130 target = os.path.join(build_dir, binary_target)
132 if options.annotate:
133 output.update({
134 'message': lambda x: bbmsg(None, x),
135 'fail': lambda x: bbmsg('FAILURE', x),
136 'warn': lambda x: bbmsg('WARNINGS', x),
137 'abend': lambda x: bbmsg('EXCEPTIONS', x),
138 'ok': lambda x: bbmsg(None, x),
141 if options.verbose:
142 output['verbose'] = lambda x: stdmsg(None, x)
144 forbidden_regexp = re.compile(string.join(map(re.escape,
145 kUndesiredLibraryList), '|'))
146 mapping_regexp = re.compile(r"\s*([^/]*) => (.*)")
147 blessed_regexp = re.compile(r"(%s)[-0-9.]*\.so" % string.join(map(re.escape,
148 kAllowedLibraryList), '|'))
149 built_regexp = re.compile(re.escape(build_dir + os.sep))
151 success = 0
152 warning = 0
154 p = subprocess.Popen(['ldd', target], stdout=subprocess.PIPE,
155 stderr=subprocess.PIPE)
156 out, err = p.communicate()
158 if err != '':
159 output['abend']([
160 'Failed to execute ldd to analyze dependencies for ' + target + ':',
161 ' ' + err,
163 return 1
165 if out == '':
166 output['abend']([
167 'No output to scan for forbidden dependencies.'
169 return 1
171 success = 1
172 deps = string.split(out, '\n')
173 for d in deps:
174 libmatch = mapping_regexp.match(d)
175 if libmatch:
176 lib = libmatch.group(1)
177 source = libmatch.group(2)
178 if forbidden_regexp.search(lib):
179 success = 0
180 output['message'](['Forbidden library: ' + lib])
181 elif built_regexp.match(source):
182 output['verbose'](['Built library: ' + lib])
183 elif blessed_regexp.match(lib):
184 output['verbose'](['Blessed library: ' + lib])
185 else:
186 warning = 1
187 output['message'](['Unexpected library: ' + lib])
189 if success == 1:
190 if warning == 1:
191 output['warn'](None)
192 else:
193 output['ok'](None)
194 return 0
195 else:
196 output['fail'](None)
197 return 1
199 if __name__ == "__main__":
200 # handle arguments...
201 # do something reasonable if not run with one...
202 sys.exit(_main())