Visualizing relationships between makefile targets using graphviz

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:

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s