Skip to content

Instantly share code, notes, and snippets.

@skyhisi
Created August 6, 2019 12:06
Show Gist options
  • Save skyhisi/bcc26f02eaff97a940ff9073671d06a8 to your computer and use it in GitHub Desktop.
Save skyhisi/bcc26f02eaff97a940ff9073671d06a8 to your computer and use it in GitHub Desktop.
Makefile Graph
#!/usr/bin/python
import argparse
import os.path
from cStringIO import StringIO
import subprocess
import sys
parser = argparse.ArgumentParser(description="Create a graphviz file of a makefile")
parser.add_argument("-C", "--directory", metavar="DIR", help="Change to directory DIR before reading the makefiles")
parser.add_argument("-f", "--file", help="Use FILE as makefile")
parser.add_argument("-o", "--output", default="makefile.gv", help="Output file")
parser.add_argument("-l", "--limit", type=int, help="Limit number of underscores in name")
parser.add_argument("target", nargs=argparse.REMAINDER, help="Make targets")
args = parser.parse_args()
makeargs = ["make", "-pn"]
if args.directory is not None:
makeargs += ["-C", args.directory]
if args.file is not None:
makeargs += ["-f", args.file]
makeargs += args.target
makeout = subprocess.check_output(makeargs)
makeoutfo = StringIO(makeout)
lastfiles = 0
for line in makeoutfo:
if line == "# Files\n":
lastfiles = makeoutfo.tell()
makeoutfo.seek(lastfiles)
with open(args.output, "wb") as outfile:
outfile.write("digraph{splines=true;\n")
for line in makeoutfo:
linestrip = line.strip()
if linestrip == "" or linestrip[0] == '#' or line[0] == '\t' or ":" not in line:
continue
target, depends = line.split(":", 1)
target = target.strip()
if target == "" or target[0] == ".":
continue
if args.limit is not None and target.count("_") >= args.limit:
continue
outfile.write("\"%s\" [label=\"%s\"];\n" % (target, os.path.basename(target)))
deplist = [x.strip() for x in depends.split(" ") if x.strip() != ""]
for dep in deplist:
if dep[0] == ".":
continue
if args.limit is not None and dep.count("_") >= args.limit:
continue
outfile.write("\"%s\" [label=\"%s\"];\n" % (dep, os.path.basename(dep)))
outfile.write("\"%s\" -> \"%s\";\n" % (target, dep))
outfile.write("}\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment