Generate Call Graphs Using Doxygen in Emacs


Doxygen is a nice tool for generating documentations for well-annotated C/C++ projects, the one feature that I like most is generating call graphs and class diagrams, so that I can learn a project quickly by browsing the diagrams from a higher point of view.

I take the following steps to generate call graphs for a project on terminals on Linux:

  1. cd /path/to/a/project/, and generate a template config file by doxygen -s -g doxygen.conf (Omit -s to generate it with detailed comments).

  2. Tweak the file by specifying input and output directories, and set HAVE_DOT and CALL_GRAPH to YES.

    Here is the complete diff:

    --- doxygen.conf.orig
    +++ doxygen.conf
    @@ -8,7 +8,7 @@
     PROJECT_NUMBER         =
     PROJECT_BRIEF          =
     PROJECT_LOGO           =
    -OUTPUT_DIRECTORY       =
    +OUTPUT_DIRECTORY       = /path/to/doxygen-output/
     CREATE_SUBDIRS         = NO
     ALLOW_UNICODE_NAMES    = NO
     OUTPUT_LANGUAGE        = English
    @@ -114,7 +114,7 @@
     #---------------------------------------------------------------------------
     # Configuration options related to the input files
     #---------------------------------------------------------------------------
    -INPUT                  =
    +INPUT                  = /path/to/a/project/ # the directory of the source code
     INPUT_ENCODING         = UTF-8
     FILE_PATTERNS          = *.c \
                              ,*.cc \
    @@ -161,7 +161,7 @@
                              ,*.ucf \
                              ,*.qsf \
                              ,*.ice
    -RECURSIVE              = NO
    +RECURSIVE              = YES
     EXCLUDE                =
     EXCLUDE_SYMLINKS       = NO
     EXCLUDE_PATTERNS       =
    @@ -255,7 +255,7 @@
     #---------------------------------------------------------------------------
     # Configuration options related to the LaTeX output
     #---------------------------------------------------------------------------
    -GENERATE_LATEX         = YES
    +GENERATE_LATEX         = NO
     LATEX_OUTPUT           = latex
     LATEX_CMD_NAME         =
     MAKEINDEX_CMD_NAME     = makeindex
    @@ -345,10 +345,10 @@
     MSCGEN_PATH            =
     DIA_PATH               =
     HIDE_UNDOC_RELATIONS   = YES
    -HAVE_DOT               = NO
    +HAVE_DOT               = YES
     DOT_NUM_THREADS        = 0
     DOT_FONTNAME           = Helvetica
    -DOT_FONTSIZE           = 10
    +DOT_FONTSIZE           = 14
     DOT_FONTPATH           =
     CLASS_GRAPH            = YES
     COLLABORATION_GRAPH    = YES
    @@ -358,7 +358,7 @@
     TEMPLATE_RELATIONS     = NO
     INCLUDE_GRAPH          = YES
     INCLUDED_BY_GRAPH      = YES
    -CALL_GRAPH             = NO
    +CALL_GRAPH             = YES
     CALLER_GRAPH           = NO
     GRAPHICAL_HIERARCHY    = YES
     DIRECTORY_GRAPH        = YES
    
  3. Run doxygen doxygen.conf, that's it.

It's a bit boring to do this for every project, and let's improve the workflow a bit by using yasnippet and making a new Emacs command.

First, make a new config template snippet with 3 placeholders (Set yas-indent-line to avoid reindention by yasnippet):

# -*- mode: snippet -*-
# expand-env: ((yas-indent-line 'never))
# --
# Doxyfile 1.8.15

PROJECT_NAME           = "${1:my-cool-project}"
...
OUTPUT_DIRECTORY       = ${2:`(format "%s/doxygen/" (expand-file-name "~"))`$1}
...
INPUT                  = $3 # XXX must be an absolute path

With this snippet (see the exact file here), I can quickly create a doxygen config for a project by "finding" a new file and insert the snippet by M-x yas-insert-snippet.

Second, make a helper command to run doxygen quickly with a projects buffer as the current buffer of Emacs:

(defun w/run-doxygen ()
  "Run doxygen asynchronously."
  (interactive)
  (let ((conf (locate-dominating-file default-directory "doxygen.conf")))
    (if (not conf)
        (message "No doxygen.conf found!")
      (shell-command (format "doxygen %sdoxygen.conf&" conf)))))

This time, just type M-x w/run-doxygen to generate call graphs in Emacs.

Emacs 

See also

comments powered by Disqus