OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 ''' Verifies that builds of the embedded content_shell do not included | 6 ''' Verifies that builds of the embedded content_shell do not included |
7 unnecessary dependencies.''' | 7 unnecessary dependencies.''' |
8 | 8 |
9 import getopt | |
10 import os | 9 import os |
11 import re | 10 import re |
12 import string | 11 import string |
13 import subprocess | 12 import subprocess |
14 import sys | 13 import sys |
15 import optparse | 14 import optparse |
16 | 15 |
17 kUndesiredLibraryList = [ | 16 kUndesiredLibraryList = [ |
18 # 'libasound', # ALSA sound - needs to go eventually | 17 # 'libasound', # ALSA sound - needs to go eventually |
19 'libcairo', | 18 'libcairo', |
(...skipping 23 matching lines...) Expand all Loading... |
43 'libpthread', | 42 'libpthread', |
44 'librt', | 43 'librt', |
45 'libsmime3', | 44 'libsmime3', |
46 'libstdc++', | 45 'libstdc++', |
47 'libz', | 46 'libz', |
48 'linux-vdso', | 47 'linux-vdso', |
49 ] | 48 ] |
50 | 49 |
51 binary_target = 'content_shell' | 50 binary_target = 'content_shell' |
52 | 51 |
53 def stdmsg(final, errors): | 52 def stdmsg(_final, errors): |
54 if errors: | 53 if errors: |
55 for message in errors: | 54 for message in errors: |
56 print message | 55 print message |
57 | 56 |
58 def bbmsg(final, errors): | 57 def bbmsg(final, errors): |
59 if errors: | 58 if errors: |
60 for message in errors: | 59 for message in errors: |
61 print '@@@STEP_TEXT@%s@@@' % message | 60 print '@@@STEP_TEXT@%s@@@' % message |
62 if final: | 61 if final: |
63 print '\n@@@STEP_%s@@@' % final | 62 print '\n@@@STEP_%s@@@' % final |
64 | 63 |
65 | 64 |
66 def _main(): | 65 def _main(): |
67 output = { | 66 output = { |
68 'message': lambda x: stdmsg(None, x), | 67 'message': lambda x: stdmsg(None, x), |
69 'fail': lambda x: stdmsg('FAILED', x), | 68 'fail': lambda x: stdmsg('FAILED', x), |
70 'warn': lambda x: stdmsg('WARNING', x), | 69 'warn': lambda x: stdmsg('WARNING', x), |
71 'abend': lambda x: stdmsg('FAILED', x), | 70 'abend': lambda x: stdmsg('FAILED', x), |
72 'ok': lambda x: stdmsg('SUCCESS', x), | 71 'ok': lambda x: stdmsg('SUCCESS', x), |
| 72 'verbose': lambda x: None, |
73 } | 73 } |
74 | 74 |
75 parser = optparse.OptionParser( | 75 parser = optparse.OptionParser( |
76 "usage: %prog -b <dir> --target <Debug|Release>") | 76 "usage: %prog -b <dir> --target <Debug|Release>") |
77 parser.add_option("", "--annotate", dest='annotate', action='store_true', | 77 parser.add_option("", "--annotate", dest='annotate', action='store_true', |
78 default=False, help="include buildbot annotations in output") | 78 default=False, help="include buildbot annotations in output") |
79 parser.add_option("", "--noannotate", dest='annotate', action='store_false') | 79 parser.add_option("", "--noannotate", dest='annotate', action='store_false') |
80 parser.add_option("-b", "--build-dir", | 80 parser.add_option("-b", "--build-dir", |
81 help="the location of the compiler output") | 81 help="the location of the compiler output") |
82 parser.add_option("--target", help="Debug or Release") | 82 parser.add_option("--target", help="Debug or Release") |
| 83 parser.add_option('-v', '--verbose', default=False, action='store_true') |
83 | 84 |
84 options, args = parser.parse_args() | 85 options, args = parser.parse_args() |
| 86 if args: |
| 87 parser.usage() |
| 88 return -1 |
| 89 |
85 # Bake target into build_dir. | 90 # Bake target into build_dir. |
86 if options.target and options.build_dir: | 91 if options.target and options.build_dir: |
87 assert (options.target != | 92 assert (options.target != |
88 os.path.basename(os.path.dirname(options.build_dir))) | 93 os.path.basename(os.path.dirname(options.build_dir))) |
89 options.build_dir = os.path.join(os.path.abspath(options.build_dir), | 94 options.build_dir = os.path.join(os.path.abspath(options.build_dir), |
90 options.target) | 95 options.target) |
91 | 96 |
92 if options.build_dir != None: | 97 if options.build_dir != None: |
93 target = os.path.join(options.build_dir, binary_target) | 98 target = os.path.join(options.build_dir, binary_target) |
94 else: | 99 else: |
95 target = binary_target | 100 target = binary_target |
96 | 101 |
97 if options.annotate: | 102 if options.annotate: |
98 output = { | 103 output.update({ |
99 'message': lambda x: bbmsg(None, x), | 104 'message': lambda x: bbmsg(None, x), |
100 'fail': lambda x: bbmsg('FAILURE', x), | 105 'fail': lambda x: bbmsg('FAILURE', x), |
101 'warn': lambda x: bbmsg('WARNINGS', x), | 106 'warn': lambda x: bbmsg('WARNINGS', x), |
102 'abend': lambda x: bbmsg('EXCEPTIONS', x), | 107 'abend': lambda x: bbmsg('EXCEPTIONS', x), |
103 'ok': lambda x: bbmsg(None, x), | 108 'ok': lambda x: bbmsg(None, x), |
104 } | 109 }) |
| 110 |
| 111 if options.verbose: |
| 112 output['verbose'] = lambda x: stdmsg(None, x) |
105 | 113 |
106 forbidden_regexp = re.compile(string.join(map(re.escape, | 114 forbidden_regexp = re.compile(string.join(map(re.escape, |
107 kUndesiredLibraryList), '|')) | 115 kUndesiredLibraryList), '|')) |
108 mapping_regexp = re.compile(r"\s*([^/]*) => ") | 116 mapping_regexp = re.compile(r"\s*([^/]*) => (.*)") |
109 blessed_regexp = re.compile(r"(%s)[-0-9.]*\.so" % string.join(map(re.escape, | 117 blessed_regexp = re.compile(r"(%s)[-0-9.]*\.so" % string.join(map(re.escape, |
110 kAllowedLibraryList), '|')) | 118 kAllowedLibraryList), '|')) |
| 119 if options.build_dir != None: |
| 120 built_regexp = re.compile(re.escape(options.build_dir)) |
| 121 else: |
| 122 built_regexp = re.compile(re.escape('lib')) |
| 123 |
111 success = 0 | 124 success = 0 |
112 warning = 0 | 125 warning = 0 |
113 | 126 |
114 p = subprocess.Popen(['ldd', target], stdout=subprocess.PIPE, | 127 p = subprocess.Popen(['ldd', target], stdout=subprocess.PIPE, |
115 stderr=subprocess.PIPE) | 128 stderr=subprocess.PIPE) |
116 out, err = p.communicate() | 129 out, err = p.communicate() |
117 | 130 |
118 if err != '': | 131 if err != '': |
119 output['abend']([ | 132 output['abend']([ |
120 'Failed to execute ldd to analyze dependencies for ' + target + ':', | 133 'Failed to execute ldd to analyze dependencies for ' + target + ':', |
121 ' ' + err, | 134 ' ' + err, |
122 ]) | 135 ]) |
123 return 1 | 136 return 1 |
124 | 137 |
125 if out == '': | 138 if out == '': |
126 output['abend']([ | 139 output['abend']([ |
127 'No output to scan for forbidden dependencies.' | 140 'No output to scan for forbidden dependencies.' |
128 ]) | 141 ]) |
129 return 1 | 142 return 1 |
130 | 143 |
131 success = 1 | 144 success = 1 |
132 deps = string.split(out, '\n') | 145 deps = string.split(out, '\n') |
133 for d in deps: | 146 for d in deps: |
134 libmatch = mapping_regexp.match(d) | 147 libmatch = mapping_regexp.match(d) |
135 if libmatch: | 148 if libmatch: |
136 lib = libmatch.group(1) | 149 lib = libmatch.group(1) |
137 if forbidden_regexp.search(lib): | 150 source = libmatch.group(2) |
138 success = 0 | 151 if forbidden_regexp.search(lib): |
139 output['message'](['Forbidden library: ' + lib]) | 152 success = 0 |
140 if not blessed_regexp.match(lib): | 153 output['message'](['Forbidden library: ' + lib]) |
141 warning = 1 | 154 elif built_regexp.match(source): |
142 output['message'](['Unexpected library: ' + lib]) | 155 output['verbose'](['Built library: ' + lib]) |
| 156 elif blessed_regexp.match(lib): |
| 157 output['verbose'](['Blessed library: ' + lib]) |
| 158 else: |
| 159 warning = 1 |
| 160 output['message'](['Unexpected library: ' + lib]) |
143 | 161 |
144 if success == 1: | 162 if success == 1: |
145 if warning == 1: | 163 if warning == 1: |
146 output['warn'](None) | 164 output['warn'](None) |
147 else: | 165 else: |
148 output['ok'](None) | 166 output['ok'](None) |
149 return 0 | 167 return 0 |
150 else: | 168 else: |
151 output['fail'](None) | 169 output['fail'](None) |
152 return 1 | 170 return 1 |
153 | 171 |
154 if __name__ == "__main__": | 172 if __name__ == "__main__": |
155 # handle arguments... | 173 # handle arguments... |
156 # do something reasonable if not run with one... | 174 # do something reasonable if not run with one... |
157 sys.exit(_main()) | 175 sys.exit(_main()) |
OLD | NEW |