A few months ago I showed a quick-and-dirty trick to draw a class relationships diagram with graphviz. It was not fully generic, but it did the trick for my situation at hand. And here we go again, this time with Makefile rules. …As it happened the other time, I didn't write a generic script, it just works for the situation I have at hand, namely:
- no multitarget lines
- each target is separated from its prerequisites with a single colon ":"
- no recipe (or a part of it) is in the same line as the target
- each target name starts with a small-caps character, or with a slash
This said, catching all the target lines is easy with egrep:
egrep "^[a-z/]" Makefile
And feeding this to perl is not that difficult; actually, it's easier than the puppet case:
egrep "^[a-z/]" Makefile | perl -lne 'BEGIN { print qq[digraph P {] } ; ($target,$prereqs) = split(/s*:s*/,$_,2) ; @prereq = split(/s+/,$prereqs) ; if (@prereq == 0) { print qq{"$target"} } else { print qq{"$target" -> "$_"} foreach @prereq } ; END { print "}" }' > makefile.dot
or, reformatted:
egrep "^[a-z/]" Makefile | perl -lne ' BEGIN { print qq[digraph P {] } ; ($target,$prereqs) = split(/s*:s*/,$_,2) ; @prereq = split(/s+/,$prereqs) ; if (@prereq == 0) { print qq{"$target"} } else { print qq{"$target" -> "$_"} foreach @prereq } ; END { print "}" }' > makefile.dot
Once the makefile.dot file is ready it's easy to make it a PNG image:
dot -Tpng makefile.dot -o makefile.png
The result made indeed clearer what the relationships between targets are:
If you want to write a generic tool for makefiles, be sure to check the official documentation for the rule syntax.
Have fun! :cheers: