#!/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()