Prepare MD downloads for Canary/Chromium
[chromium-blink-merge.git] / tools / check_ecs_deps / check_ecs_deps.py
blob4ac06bb298908f11b16970e2599286d08824c1ec
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 'libselinux',
43 'libudev',
44 'libxcb',
47 kAllowedLibraryList = [
48 # Toolchain libraries (gcc/glibc)
49 'ld-linux',
50 'libc',
51 'libdl',
52 'libgcc_s',
53 'libm',
54 'libpthread',
55 'libresolv',
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 # OpenSSL
72 'libcrypto',
74 # Miscellaneous
75 'libcap',
76 'libexpat',
77 'libfontconfig',
78 'libz',
81 binary_target = 'content_shell'
83 def stdmsg(_final, errors):
84 if errors:
85 for message in errors:
86 print message
88 def bbmsg(final, errors):
89 if errors:
90 for message in errors:
91 print '@@@STEP_TEXT@%s@@@' % message
92 if final:
93 print '\n@@@STEP_%s@@@' % final
96 def _main():
97 output = {
98 'message': lambda x: stdmsg(None, x),
99 'fail': lambda x: stdmsg('FAILED', x),
100 'warn': lambda x: stdmsg('WARNING', x),
101 'abend': lambda x: stdmsg('FAILED', x),
102 'ok': lambda x: stdmsg('SUCCESS', x),
103 'verbose': lambda x: None,
106 parser = optparse.OptionParser(
107 "usage: %prog -b <dir> --target <Debug|Release>")
108 parser.add_option("", "--annotate", dest='annotate', action='store_true',
109 default=False, help="include buildbot annotations in output")
110 parser.add_option("", "--noannotate", dest='annotate', action='store_false')
111 parser.add_option("-b", "--build-dir",
112 help="the location of the compiler output")
113 parser.add_option("--target", help="Debug or Release")
114 parser.add_option('-v', '--verbose', default=False, action='store_true')
116 options, args = parser.parse_args()
117 if args:
118 parser.usage()
119 return -1
121 # Bake target into build_dir.
122 if options.target and options.build_dir:
123 assert (options.target !=
124 os.path.basename(os.path.dirname(options.build_dir)))
125 options.build_dir = os.path.join(os.path.abspath(options.build_dir),
126 options.target)
128 if options.build_dir != None:
129 build_dir = os.path.abspath(options.build_dir)
130 else:
131 build_dir = os.getcwd()
133 target = os.path.join(build_dir, binary_target)
135 if options.annotate:
136 output.update({
137 'message': lambda x: bbmsg(None, x),
138 'fail': lambda x: bbmsg('FAILURE', x),
139 'warn': lambda x: bbmsg('WARNINGS', x),
140 'abend': lambda x: bbmsg('EXCEPTIONS', x),
141 'ok': lambda x: bbmsg(None, x),
144 if options.verbose:
145 output['verbose'] = lambda x: stdmsg(None, x)
147 forbidden_regexp = re.compile(string.join(map(re.escape,
148 kUndesiredLibraryList), '|'))
149 mapping_regexp = re.compile(r"\s*([^/]*) => (.*)")
150 blessed_regexp = re.compile(r"(%s)[-0-9.]*\.so" % string.join(map(re.escape,
151 kAllowedLibraryList), '|'))
152 built_regexp = re.compile(re.escape(build_dir + os.sep))
154 success = 0
155 warning = 0
157 p = subprocess.Popen(['ldd', target], stdout=subprocess.PIPE,
158 stderr=subprocess.PIPE)
159 out, err = p.communicate()
161 if err != '':
162 output['abend']([
163 'Failed to execute ldd to analyze dependencies for ' + target + ':',
164 ' ' + err,
166 return 1
168 if out == '':
169 output['abend']([
170 'No output to scan for forbidden dependencies.'
172 return 1
174 success = 1
175 deps = string.split(out, '\n')
176 for d in deps:
177 libmatch = mapping_regexp.match(d)
178 if libmatch:
179 lib = libmatch.group(1)
180 source = libmatch.group(2)
181 if forbidden_regexp.search(lib):
182 success = 0
183 output['message'](['Forbidden library: ' + lib])
184 elif built_regexp.match(source):
185 output['verbose'](['Built library: ' + lib])
186 elif blessed_regexp.match(lib):
187 output['verbose'](['Blessed library: ' + lib])
188 else:
189 warning = 1
190 output['message'](['Unexpected library: ' + lib])
192 if success == 1:
193 if warning == 1:
194 output['warn'](None)
195 else:
196 output['ok'](None)
197 return 0
198 else:
199 output['fail'](None)
200 return 1
202 if __name__ == "__main__":
203 # handle arguments...
204 # do something reasonable if not run with one...
205 sys.exit(_main())