Chromium Code Reviews| Index: src/scripts/check_deps |
| diff --git a/src/scripts/check_deps b/src/scripts/check_deps |
| new file mode 100755 |
| index 0000000000000000000000000000000000000000..a7f244bf9710ac41f8a43dab8dc81a6edfb2663e |
| --- /dev/null |
| +++ b/src/scripts/check_deps |
| @@ -0,0 +1,117 @@ |
| +#!/usr/bin/python |
| + |
| +# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +import os |
| +import re |
| +import sys |
| + |
| +SHARED_RE = re.compile(r"Shared library: \[([^\]]+)\]") |
|
kmixter1
2010/03/01 23:37:33
Usually prefix these with _ if they're internal co
|
| +RPATH_RE = re.compile(r"Library rpath: \[([^\]]+)\]") |
| + |
| + |
| +class CheckDependencies(object): |
| + """Check that dependencies for binaries can be found in the specified dir.""" |
| + |
| + def __init__(self, root, verbose=False): |
| + """Initializer. |
| + |
| + Args: |
| + root: The sysroot (e.g. "/") |
| + verbose: Print helpful messages. |
| + """ |
| + |
| + self.root = root |
|
kmixter1
2010/03/01 23:37:33
prefix these with _ if they're internal class vari
|
| + self.errors = False |
|
kmixter1
2010/03/01 23:37:33
Not used.
|
| + self.system_libcache = set() |
| + self.verbose = verbose |
| + |
| + # Insert some default directories into our library cache. |
| + # The /usr/lib/nss and /usr/lib/nspr directories are |
| + # required for understanding old-style Netscape plugins. |
| + self._ReadLibs([ |
| + "%s/lib" % root, |
| + "%s/usr/lib" % root, |
| + "%s/usr/lib/nss" % root, |
| + "%s/usr/lib/nspr" % root |
| + ], self.system_libcache) |
| + |
| + def _ReadLibs(self, paths, libcache): |
| + for path in paths: |
| + if os.path.exists(path): |
| + for lib in os.listdir(path): |
|
kmixter1
2010/03/01 23:37:33
So you're assuming any file in one of the libcache
|
| + libcache.add(lib) |
| + |
| + def _ReadDependencies(self, binary, libcache): |
|
kmixter1
2010/03/01 23:37:33
So reading the dependencies of a binary also updat
|
| + libs = [] |
| + |
| + # Read list of dynamic libraries, ignoring error messages that occur |
| + # when we look at files that aren't actually libraries |
| + 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?
|
| + |
| + # Grab dependencies |
| + m = SHARED_RE.search(line) |
| + if m: |
| + libs.append(m.group(1)) |
| + |
| + # Add RPATHs in our search path |
| + m = RPATH_RE.search(line) |
| + if m: |
| + paths = [os.path.join(self.root, path[1:]) |
| + for path in m.group(1).split(":")] |
| + |
| + self._ReadLibs(paths, libcache) |
| + |
| + return libs |
| + |
| + def CheckDependencies(self, binary): |
| + """Check whether the libs for BINARY can be found in our sysroot.""" |
| + |
| + good = True |
| + |
| + libcache = self.system_libcache.copy() |
| + for lib in self._ReadDependencies(binary, libcache): |
| + if lib[0] != "/": |
| + if lib in libcache: |
| + if self.verbose: print "Found %s" % lib |
| + else: |
| + print >>sys.stderr, "Problem with %s: Can't find %s" % (binary, lib) |
| + good = False |
| + else: |
| + full_path = os.path.join(self.root, lib[1:]) |
| + if os.path.exists(full_path): |
| + if self.verbose: print "Found %s" % lib |
| + else: |
| + print >>sys.stderr, "Problem with %s: Can't find %s" % (binary, lib) |
| + good = False |
| + |
| + return good |
| + |
| + |
| +def main(): |
| + |
|
kmixter1
2010/03/01 23:37:33
please remove extra line
|
| + if len(sys.argv) < 3: |
| + print "Usage: %s [-v] sysroot binary [ binary ... ]" % sys.argv[0] |
| + sys.exit(1) |
| + |
| + verbose = False |
| + if sys.argv[1] == "-v": |
|
kmixter1
2010/03/01 23:37:33
one more parameter and you'll want to use getopt,
|
| + verbose = True |
| + sys.argv = sys.argv[0:1] + sys.argv[2:] |
| + |
| + checker = CheckDependencies(sys.argv[1], verbose) |
| + errors = False |
| + for binary in sys.argv[2:]: |
| + if verbose: print "Checking %s" % binary |
| + if not checker.CheckDependencies(binary): |
| + errors = True |
| + |
| + if errors: |
| + sys.exit(1) |
| + else: |
| + sys.exit(0) |
| + |
| +if __name__ == "__main__": |
| + main() |