Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 | |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
| 4 # Use of this source code is governed by a BSD-style license that can be | |
| 5 # found in the LICENSE file. | |
| 6 | |
| 7 import os | |
| 8 import re | |
| 9 import sys | |
| 10 | |
| 11 SHARED_RE = re.compile(r"Shared library: \[([^\]]+)\]") | |
|
kmixter1
2010/03/01 23:37:33
Usually prefix these with _ if they're internal co
| |
| 12 RPATH_RE = re.compile(r"Library rpath: \[([^\]]+)\]") | |
| 13 | |
| 14 | |
| 15 class CheckDependencies(object): | |
| 16 """Check that dependencies for binaries can be found in the specified dir.""" | |
| 17 | |
| 18 def __init__(self, root, verbose=False): | |
| 19 """Initializer. | |
| 20 | |
| 21 Args: | |
| 22 root: The sysroot (e.g. "/") | |
| 23 verbose: Print helpful messages. | |
| 24 """ | |
| 25 | |
| 26 self.root = root | |
|
kmixter1
2010/03/01 23:37:33
prefix these with _ if they're internal class vari
| |
| 27 self.errors = False | |
|
kmixter1
2010/03/01 23:37:33
Not used.
| |
| 28 self.system_libcache = set() | |
| 29 self.verbose = verbose | |
| 30 | |
| 31 # Insert some default directories into our library cache. | |
| 32 # The /usr/lib/nss and /usr/lib/nspr directories are | |
| 33 # required for understanding old-style Netscape plugins. | |
| 34 self._ReadLibs([ | |
| 35 "%s/lib" % root, | |
| 36 "%s/usr/lib" % root, | |
| 37 "%s/usr/lib/nss" % root, | |
| 38 "%s/usr/lib/nspr" % root | |
| 39 ], self.system_libcache) | |
| 40 | |
| 41 def _ReadLibs(self, paths, libcache): | |
| 42 for path in paths: | |
| 43 if os.path.exists(path): | |
| 44 for lib in os.listdir(path): | |
|
kmixter1
2010/03/01 23:37:33
So you're assuming any file in one of the libcache
| |
| 45 libcache.add(lib) | |
| 46 | |
| 47 def _ReadDependencies(self, binary, libcache): | |
|
kmixter1
2010/03/01 23:37:33
So reading the dependencies of a binary also updat
| |
| 48 libs = [] | |
| 49 | |
| 50 # Read list of dynamic libraries, ignoring error messages that occur | |
| 51 # when we look at files that aren't actually libraries | |
| 52 for line in os.popen("readelf -d '%s' 2>/dev/null" % binary): | |
|
kmixter1
2010/03/01 23:37:33
Do you need to explicitly close the os.popen pipe?
| |
| 53 | |
| 54 # Grab dependencies | |
| 55 m = SHARED_RE.search(line) | |
| 56 if m: | |
| 57 libs.append(m.group(1)) | |
| 58 | |
| 59 # Add RPATHs in our search path | |
| 60 m = RPATH_RE.search(line) | |
| 61 if m: | |
| 62 paths = [os.path.join(self.root, path[1:]) | |
| 63 for path in m.group(1).split(":")] | |
| 64 | |
| 65 self._ReadLibs(paths, libcache) | |
| 66 | |
| 67 return libs | |
| 68 | |
| 69 def CheckDependencies(self, binary): | |
| 70 """Check whether the libs for BINARY can be found in our sysroot.""" | |
| 71 | |
| 72 good = True | |
| 73 | |
| 74 libcache = self.system_libcache.copy() | |
| 75 for lib in self._ReadDependencies(binary, libcache): | |
| 76 if lib[0] != "/": | |
| 77 if lib in libcache: | |
| 78 if self.verbose: print "Found %s" % lib | |
| 79 else: | |
| 80 print >>sys.stderr, "Problem with %s: Can't find %s" % (binary, lib) | |
| 81 good = False | |
| 82 else: | |
| 83 full_path = os.path.join(self.root, lib[1:]) | |
| 84 if os.path.exists(full_path): | |
| 85 if self.verbose: print "Found %s" % lib | |
| 86 else: | |
| 87 print >>sys.stderr, "Problem with %s: Can't find %s" % (binary, lib) | |
| 88 good = False | |
| 89 | |
| 90 return good | |
| 91 | |
| 92 | |
| 93 def main(): | |
| 94 | |
|
kmixter1
2010/03/01 23:37:33
please remove extra line
| |
| 95 if len(sys.argv) < 3: | |
| 96 print "Usage: %s [-v] sysroot binary [ binary ... ]" % sys.argv[0] | |
| 97 sys.exit(1) | |
| 98 | |
| 99 verbose = False | |
| 100 if sys.argv[1] == "-v": | |
|
kmixter1
2010/03/01 23:37:33
one more parameter and you'll want to use getopt,
| |
| 101 verbose = True | |
| 102 sys.argv = sys.argv[0:1] + sys.argv[2:] | |
| 103 | |
| 104 checker = CheckDependencies(sys.argv[1], verbose) | |
| 105 errors = False | |
| 106 for binary in sys.argv[2:]: | |
| 107 if verbose: print "Checking %s" % binary | |
| 108 if not checker.CheckDependencies(binary): | |
| 109 errors = True | |
| 110 | |
| 111 if errors: | |
| 112 sys.exit(1) | |
| 113 else: | |
| 114 sys.exit(0) | |
| 115 | |
| 116 if __name__ == "__main__": | |
| 117 main() | |
| OLD | NEW |