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
= [
48 kAllowedLibraryList
= [
49 # Toolchain libraries (gcc/glibc)
60 # Needed for default ozone platforms
78 binary_target
= 'content_shell'
80 def stdmsg(_final
, errors
):
82 for message
in errors
:
85 def bbmsg(final
, errors
):
87 for message
in errors
:
88 print '@@@STEP_TEXT@%s@@@' % message
90 print '\n@@@STEP_%s@@@' % final
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()
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
),
125 if options
.build_dir
!= None:
126 build_dir
= os
.path
.abspath(options
.build_dir
)
128 build_dir
= os
.getcwd()
130 target
= os
.path
.join(build_dir
, binary_target
)
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
),
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
))
154 p
= subprocess
.Popen(['ldd', target
], stdout
=subprocess
.PIPE
,
155 stderr
=subprocess
.PIPE
)
156 out
, err
= p
.communicate()
160 'Failed to execute ldd to analyze dependencies for ' + target
+ ':',
167 'No output to scan for forbidden dependencies.'
172 deps
= string
.split(out
, '\n')
174 libmatch
= mapping_regexp
.match(d
)
176 lib
= libmatch
.group(1)
177 source
= libmatch
.group(2)
178 if forbidden_regexp
.search(lib
):
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
])
187 output
['message'](['Unexpected library: ' + lib
])
199 if __name__
== "__main__":
200 # handle arguments...
201 # do something reasonable if not run with one...