Source code for scipion.install.find_deps

#!/usr/bin/env python

# **************************************************************************
# *
# * Authors:     J. Burguet Castell     (jburguet@cnb.csic.es)
# *
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia, CSIC
# *
# * This program is free software; you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation; either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program; if not, write to the Free Software
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
# * 02111-1307  USA
# *
# *  All comments concerning this program package may be sent to the
# *  e-mail address 'scipion@cnb.csic.es'
# *
# **************************************************************************

"""
Show all the system packages on which scipion depends.
"""

import os
from subprocess import check_output, CalledProcessError
import argparse


[docs]def main(): parser = argparse.ArgumentParser(description=__doc__) add = parser.add_argument # short notation add('dirs', metavar='DIR', nargs='+', help="directories with binaries") add('--packages', action='store_true', help="show system packages") add('--pkg-command', default='dpkg -S', help="command used to find which package a file belongs to") args = parser.parse_args() # Get all the library dependencies. neededLibs = set() for subdir in args.dirs: for dirpath, dirnames, filenames in os.walk(subdir): for fname in filenames: fpath = os.path.join(dirpath, fname) if isElf(fpath): neededLibs.update(libDeps(fpath)) # Show where they are in the system. existingLibs = {path: os.listdir(path) for path in searchPaths() if os.path.exists(path)} shown = set() for lib in neededLibs: for libPath in existingLibs: if lib not in existingLibs[libPath]: continue if not args.packages: libFull = '%s/%s' % (libPath, lib) if libFull not in shown: print(libFull) shown.add(libFull) elif 'software/lib' not in libPath: command = '%s %s/%s' % (args.pkg_command, libPath, lib) try: pkg = check_output(command.split()).split(':')[0].strip() if pkg not in shown: print(pkg) shown.add(pkg) except CalledProcessError: print('%s/%s -> no package found' % (libPath, lib)) break else: print('%s -> not found in any path' % lib)
[docs]def libDeps(fpath): """Return set of libraries that the file at fpath links to""" libs = set() for line in check_output(['objdump', '-p', fpath]).splitlines(): fields = line.split() if fields and fields[0] == 'NEEDED': libs.add(fields[-1]) return libs
[docs]def isElf(fname): """Is fname a file in elf format?""" return os.path.isfile(fname) and open(fname).read(4) == '\x7fELF'
[docs]def searchPaths(): """Return the list of paths were the libraries are searched in the system""" paths = [] if 'LD_LIBRARY_PATH' in os.environ: paths += os.environ.get('LD_LIBRARY_PATH', '').split(':') for fname in os.listdir('/etc/ld.so.conf.d'): if fname.endswith('.conf'): for line in open('/etc/ld.so.conf.d/%s' % fname): if not line.startswith('#'): paths.append(line.strip()) paths = [x for x in paths if 'i386' not in x] # FIXME: something nicer return paths
if __name__ == '__main__': main()