Wednesday, October 13, 2010

Simple dependency graphing for Linux/Solaris


I needed a simple tool that would determine the dependencies between some libraries.
Because I haven't found one (I tried to compile nmdepend but I gave up quickly) I wrote this simple and rudimentary dependency walker that is generating a PDF output.
It takes one argument in the command line and then draws a graph f dependencies for this argument by parsing the output of ldd command. The graph is creating by pushing the list of dependencies to graphviz.

#!/usr/bin/env python
import sys
import popen2
import re
deps = {}
def solve(f):
        if f in deps:
                return deps[f]
        r, w, e = popen2.popen3('ldd '+f)
        e.readlines()
        __deps = []
        for l in r.readlines():
                dep=""
                t=l.split("=>")
                try:
                        left=t[0].strip()
                        right=t[1].strip()
                        if right=="not found":
                                key="./"+left
                        else:
                                key=right              
                except IndexError:
                        key=t[0].strip()
                key=key.split(r" ")[0].strip()
                __deps.append(key)
        deps[f]=__deps
        r.close()
        e.close()
        w.close()
        for dep in __deps: solve(dep)

def export(name):
        r, w, e = popen2.popen3('dot -Tpdf -o/tmp/'+name+".pdf")
        #graphviz output
        w.write('digraph "' + sys.argv[1] + '"{'+"\n")
        w.write('ratio="auto";' + "\n")
        for dep in sorted(deps.keys()):
                for dd in deps[dep]:
                        w.write('"' + dep + '"->"' + dd + '";' + "\n")
        w.write('}' + "\n")
        r.close()
        e.close()
        w.close()
if __name__=="__main__":
        solve(sys.argv[1])
        del deps["statically"]
        export(sys.argv[1])
        #print deps

No comments:

Post a Comment