Skip to content

Instantly share code, notes, and snippets.

@eruffaldi
Last active March 3, 2017 09:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eruffaldi/e369299212100e4befcbd66a33b8fb8d to your computer and use it in GitHub Desktop.
Save eruffaldi/e369299212100e4befcbd66a33b8fb8d to your computer and use it in GitHub Desktop.
Dependency Collector
#
# Emanuele Ruffaldi
# Recursive Dependency lister and collector (2017)
#
#
# Tested on OSX crosscompiling Windows using peldd (https://github.com/gsauthof/pe-util)
#
# Example:
# python listlibs.py --peldd ~/bin/peldd --path ~/Documents/work/xcoco/cocolibs/prefixwin64/bin ~/Documents/work/xcoco/cocolibs/prefixwin64/lib ~/Documents/work/xcoco/cocomr/buildmxe/bin /usr/local/mxe/usr/x86_64-w64-mingw32.shared.posix/bin --target ~/Documents/work/xcoco/cocomr/buildmxe/bin ~/Documents/work/xcoco/cocomr/buildmxe/bin/*.dll
#
# Future: test on OSX and Linux
# Future: hide known Windows sytem DLL
import argparse
import os
import subprocess
import shutil
windowsknownlibs = "OPENGL32,IPHLAPI,MSVFW32,WSOCK32,AVIFIL32,COMCTL32,MSVCR100"
def depends_win32(x,args):
try:
return [x for x in subprocess.check_output([args.peldd,x]).split("\n") if x.strip() != ""]
except:
if args.verbose:
print "depends error for",x
return []
def depends_linux(x,args):
try:
return [x for x in subprocess.check_output(["ldd",x]).split("\n") if x.strip() != ""]
except:
if args.verbose:
print "depends error for",x
return []
def depends_osx(x,args):
try:
return [x for x in subprocess.check_output(["otool","-L",x]).split("\n") if x.strip() != ""]
except:
if args.verbose:
print "depends error for",x
return []
def lookup(x,args):
if os.path.isfile(x):
return x
for y in args.path:
fp = os.path.join(y,x)
if os.path.isfile(fp):
if args.verbose:
print "found",fp,"for",x
return fp
return None
def main():
parser = argparse.ArgumentParser(description='Scan Dependencies')
parser.add_argument('--peldd',default="peldd")
parser.add_argument('input',nargs="+")
parser.add_argument('--path',nargs="+")
parser.add_argument('--target')
parser.add_argument('--copy',action="store_true")
parser.add_argument('--deps',action="store_true")
parser.add_argument('--verbose',action="store_true")
depends = depends_win32
args = parser.parse_args()
todo = set()
for x in args.input:
todo.add((os.path.split(x)[1],lookup(x,args.path)))
done = set()
notfound = set()
donefull = dict()
deps = dict()
while len(todo) != 0:
one,onefull = todo.pop()
if onefull is None:
if args.verbose:
print "notfound",one
notfound.add(one)
continue
else:
if args.verbose:
print "found",one
donefull[one] = onefull
done.add(one)
ll = depends(onefull,args)
deps[one] = [] if ll is None else ll
for x in ll:
if x not in done and x != "":
todo.add((x,lookup(x,args)))
print "**Not Found:\n","\n".join(notfound)
if args.deps:
print "**Dependencies:"
for k in sorted(deps.keys()):
print k
for x in sorted(deps[k]):
print "\t",x
else:
if args.target is not None:
print "**Listing Need to Copy:"
else:
print "**Listing Mapping"
for k,v in donefull.iteritems():
if args.target is not None:
bn = os.path.split(v)[1]
fp = os.path.join(args.target,bn)
if not os.path.isfile(fp):
if args.copy:
print ">>",k,v
shutil.copyfile(v,fp)
else:
print "! %s: %s -> %s" % (k,v,fp)
else:
print k,v
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment