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.'''
16 kUndesiredLibraryList
= [
47 kAllowedLibraryList
= [
48 # Toolchain libraries (gcc/glibc)
60 # Needed for default ozone platforms
81 binary_target
= 'content_shell'
83 def stdmsg(_final
, errors
):
85 for message
in errors
:
88 def bbmsg(final
, errors
):
90 for message
in errors
:
91 print '@@@STEP_TEXT@%s@@@' % message
93 print '\n@@@STEP_%s@@@' % final
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()
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
),
128 if options
.build_dir
!= None:
129 build_dir
= os
.path
.abspath(options
.build_dir
)
131 build_dir
= os
.getcwd()
133 target
= os
.path
.join(build_dir
, binary_target
)
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
),
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
))
157 p
= subprocess
.Popen(['ldd', target
], stdout
=subprocess
.PIPE
,
158 stderr
=subprocess
.PIPE
)
159 out
, err
= p
.communicate()
163 'Failed to execute ldd to analyze dependencies for ' + target
+ ':',
170 'No output to scan for forbidden dependencies.'
175 deps
= string
.split(out
, '\n')
177 libmatch
= mapping_regexp
.match(d
)
179 lib
= libmatch
.group(1)
180 source
= libmatch
.group(2)
181 if forbidden_regexp
.search(lib
):
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
])
190 output
['message'](['Unexpected library: ' + lib
])
202 if __name__
== "__main__":
203 # handle arguments...
204 # do something reasonable if not run with one...