#!/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
import glob

_SHARED_RE = re.compile(r"Shared library: \[([^\]]+)\]")
_RPATH_RE = re.compile(r"Library r(?:un)?path: \[([^\]]+)\]")


class CheckDependencies(object):
  """Check that dependencies for binaries can be found in the specified dir."""

  def _ReadLdSoConf(self, path):
    """Parse ld.so.conf files.

    Starting with the file at PATH (searched relative to self._root), return
    all the valid libdirs found. Include directives are handled recursively.

    Args:
      path: the path to the ld.so.conf file (inside of the root).

    Returns:
      A list of valid libdirs.
    """

    libdirs = []

    ld_so_conf = self._root + path
    if os.path.exists(ld_so_conf):
      f = file(ld_so_conf)

      for line in f:
        line = line.rstrip()

        if line.startswith("/"):
          libpath = self._root + line
          if os.path.exists(libpath):
            libdirs.append(libpath)

        elif line.startswith("include "):
          # Includes are absolute or relative to the file itself.
          line = os.path.join(os.path.dirname(path), line[8:])
          for p in glob.glob(self._root + line):
            libdirs.extend(self._ReadLdSoConf(os.path.relpath(p, self._root)))

      f.close()

    return libdirs

  def __init__(self, root, verbose=False):
    """Initializer.

    Args:
      root: The sysroot (e.g. "/")
      verbose: Print helpful messages.
    """

    self._root = root
    self._libcache = set()
    self._verbose = verbose

    libdirs = []

    # Add the native paths. Get the ELF interpreter from a known file
    # and assume that the path it is in is our native libdir. So here
    # we would get something like "/lib64/ld-linux-x86-64.so.2".
    elf = "/bin/sh"
    f = os.popen("scanelf -qF'%%i#p' %s/%s" % (root, elf))
    native_libdir = os.path.dirname(f.readline().rstrip())
    f.close()
    if len(native_libdir) == 0:
      print >>sys.stderr, "Problem with %s: can't find ELF interp" % elf
      sys.exit(1)
    elif native_libdir != "/lib":
      libdirs.extend([
        "%s/%s" % (root, native_libdir),
        "%s/usr%s" % (root, native_libdir)
      ])

    # Insert some default directories into our library cache.
    libdirs.extend([
      "%s/lib" % root,
      "%s/usr/lib" % root,
      "%s/opt/google/o3d/lib" % root,
      "%s/usr/lib/opengl/xorg-x11/lib" % root,
      "%s/usr/local/lib/icedtea6/jre/lib/i386/client" % root,
      "%s/usr/local/lib/icedtea6/jre/lib/i386/headless" % root
    ])

    # Read more directories from ld.so.conf.
    libdirs.extend(self._ReadLdSoConf("/etc/ld.so.conf"))

    self._ReadLibs(libdirs, self._libcache)

  def _ReadLibs(self, paths, libcache):
    for path in paths:
      if os.path.exists(path):
        for lib in os.listdir(path):
          libcache.add(lib)

  def _ReadDependencies(self, binary):
    """Run readelf -d on BINARY, returning (deps, rpaths)."""

    deps = set()
    rpaths = set()

    # Read list of dynamic libraries, ignoring error messages that occur
    # when we look at files that aren't actually libraries
    f = os.popen("readelf -d '%s' 2>/dev/null" % binary)
    for line in f:

      # Grab dependencies
      m = _SHARED_RE.search(line)
      if m:
        deps.add(m.group(1))

      # Add RPATHs in our search path
      m = _RPATH_RE.search(line)
      if m:
        for path in m.group(1).split(":"):
          if path.startswith("$ORIGIN"):
            rpaths.add(path.replace("$ORIGIN", os.path.dirname(binary)))
          else:
            rpaths.add(os.path.join(self._root, path[1:]))
    f.close()

    return (deps, rpaths)

  def CheckDependencies(self, binary):
    """Check whether the libs for BINARY can be found in our sysroot."""

    good = True

    deps, rpaths = self._ReadDependencies(binary)

    if self._verbose:
      for lib in self._libcache & deps:
        print "Found %s" % lib

    for lib in deps - self._libcache:
      if lib[0] != "/":
        for path in rpaths:
          if os.path.exists(os.path.join(path, lib)):
            if self._verbose:
              print "Found %s" % lib
            break
        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():
  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":
    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()
