如何使用graphviz的函数库使用说明

Access denied | www.graphviz.org used Cloudflare to restrict access
Please enable cookies.
What happened?
The owner of this website (www.graphviz.org) has banned your access based on your browser's signature (3ea9a87fb59c6e14-ua98).> graphviz python
热门文章热门标签
10月12日 |
10月12日 |
10月12日 |
10月12日 |
10月12日 |
10月12日 |
10月12日 |
10月12日 |一、Graphviz + CodeViz简单介绍
CodeViz是《Understanding The Linux Virtual Memory Manager》的作者&Mel Gorman&写的一款分析C/C++源代码中函数调用关系的open source工具(类似的open source软件有&、)。其基本原理是给 GCC 打个补丁(如果你的gcc版本不符合它的要求还得先下载正确的gcc版本),让它在编译每个源文件时 dump 出其中函数的 call graph,然后用 Perl 脚本收集并整理调用关系,转交给绘制图形(属于后端,CodeViz属于前端)。
CodeViz 原本是作者用来分析 Linux virtual memory 的源码时写的一个小工具,现在已经基本支持 C++ 语言,最新的 1.0.9 版能在 Windows + Cygwin 下顺利地编译使用。
基本介绍就到这儿,如果你对其原理比较感兴趣,可以参考这篇文章:分析函数调用关系图(call graph)的几种方法
二、Graphviz + CodeViz编译安装
1. 安装 GraphViz
调用图的生成依赖于 GraphViz,所以首先要安装 GraphViz。可以下载源码包编译、安装(下载主页:)。
如果是Ubuntu系统可以直接apt安装: sudo apt-get install graphviz
2. 安装 CodeViz
下载CodeVize源码包:
解压:tar xvf codeviz-1.0.12.tar.gz (目前最新版是1.0.12)
进入解压后的目录:cd codeviz-1.0.12/
CodeViz 使用了一个 patch 版本的 GCC 编译器,而且不同的 CodeViz 版本使用的GCC 版本也不同,可以下载 CodeViz 的源码包后查看 Makefile 文件来确定要使用的 GCC 版
本,codeviz-1.0.12 使用 GCC-4.6.2。实际上安装 CodeViz
时安装脚本make会检查当前的GCC版本如果不符合则会自动下载对应的 GCC并打
patch,但由于GCC较大如果网速不好且在虚拟机中的话容易下载失败或系统错误什么的,因此这里我们还是分步安装比较好,先安装gcc再回来安装
(1)安装 GCC
下载gcc-4.6.2.tar.gz到 cd codeviz-1.0.12目录下的compilers里。
下载地址:ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.6.2/gcc-4.6.2.tar.gz
CodeViz 的安装脚本 compilers/install_gcc-4.6.2.sh 会自动检测 compilers 目录下是否有
gcc 的源码包,若没有则自动下载并打
patch。这里前面已经下载,直接移到该目录即可,则剩下的就是解压安装了。install_gcc-3.4.6.sh 会解压缩 gcc打
patch,并将其安装到指定目录,若是没有指定目录,则缺省使用$HOME/gcc-graph,通常指定安装在/usr/
local/gcc-graph(这时需要 root 权限)。
安装: ./install_gcc-4.6.2.sh
注意:这里可能安装时有些错误,具体错误及解决方案见后面。
(2)安装 CodeViz
./configure && make install-codeviz
注1:不需要 make ,因为make的作用就是检测是否有gcc若没有则下载源码包,所以这里只要安装 codeviz 即可。具体查看 Makefile 文件。
注意:这里为什么不是通常用的make install,因为这里make
install的作用是先安装gcc再安装codeviz,而前面已经安装了 gcc,所以这里只需要安装 codeviz ,即make
install-codeviz脚本,该脚本也就是将genfull 和 gengraph 复制到/usr/local/bin 目录下。
目前为止,CodeViz 安装完成了。
三、基本使用方法
GraphViz 支持生成不同风格的调用图,但是一些需要安装额外的支持工具或者库程序,有兴趣的朋友可以到上查找相关资料。这里重点讲述 CodeViz 的使用方法,具体的图像风格控制不再详述。
CodeViz 使用两个脚本来生成调用图,一个是
genfull,该脚本可以生成项目的完整调用图,因此调用图可能很大很复杂,缺省使用 cdepn
文件来创建调用图;另一个是gengraph,该脚本可以对给定一组函数生成一个小的调用图,还可以生成对应的postscript
文件。安装时这两个脚本被复制到/usr/local/bin 目录下,所以可以直接使用而不需要指定路径。其基本步骤如下:
下面以编译一个简单的test.c文件为例进行说明:
1. 使用刚刚安装的gcc-4.6.2来编译当前目录下所有.c文件,gcc/g++为编译的每个 C/C++文件生成.cdepn 文件。只要编译(参数&-c)就行,无需链接。
即为:$ ~/gcc-graph/bin/gcc test.c
2.调用genful会在当前目录生成一个full.graph文件,该脚本可以生成项目的完整调用图信息文件,记录了所有函数在源码中的位置和它们之间的调用关系。 因此调用图信息文件可能很大很复杂,,缺省使用 cdepn 文件来创建调用图信息文件。
即为:$ genfull
3. 使用gengraph可以对给定一组函数生成一个小的调用图,显示函数调用关系。
即为:$ gengraph
四、简单示例演示
自己编写个简单的程序,看下效果再说~~~
#include &stdio.h&
void test1();
void test2();
void test3();
int main()
void test1()
void test2()
void test3()
按照上面的三个步骤依次进行如下图所示:
打开main.ps看到效果如下,一目了然:
五、进阶使用
当然大家使用CodeViz都不是用来玩的,而是用于真正的项目中,四中简单的使用根本不够,下面来点稍微高深点的。
1. 先来分析下上面的执行流程
首先使用刚刚安装的gcc编译我们的.c文件(PS:这里一定要指定刚刚安装gcc的
地方,否则用的是系统gcc而非我们安装的gcc),然后genfull创建full.graph文件,可以使用genfull
--help或者genfull
--man来查看如何使用。最简单的方式是在项目的顶级目录以无参数方式运行。由于项目的完全调用信息非常庞大,所以通常只是简单的生成项目的
full.graph,然后在后面使用genfull获取需要的调用信息。若是需要完整信息则将full.graph由dot处理然后查看来生成的
postscript文件。(dot是GraphViz中的一个工具,具体使用没有深究过,感兴趣的读者可以自行查阅~~~)。到test.c所在目录运
行genfull看到生成了full.graph文件,大家可以用cat查看下。接下来使用gengraph生成函数调用图,可以使用gengraph
--help或gengraph --man来查看如何使用。对于我而言,目前只关注下面几个选项就够了,即:
-f:指定顶级函数,即入口函数,如main等(当然不限定是main了);
-o:指定输出的postfile文件名,不指定的话就是函数名了,如上面的main;
--output-type:指定输出类型,例如png、gif、html和ps,缺省是ps,如上面的main.ps;
-d:指定最大调用层数;
-s:仅仅显示指定的函数,而不对其调用进行展开;
-i:忽略指定的函数
-t:忽略Linux特有的内核函数集;
-k:保留由-s忽略的内部细节形成的中间文件,为sub.graph
2. 使用gengraph时的选项参数值要使用""括起来,例如:
gengraph --output-type "png" -f main
3. 命名冲突问题
在一个复杂的项目中,full.graph并不十分完美。例如,kernel中的模块
有许多同名函数,这时genfull不能区分它们,有两种方法可以解决,其中第一种方法太复杂易错不推荐使用,这里就介绍下第二种方法,即使用
genfull的-s选项,-s指定了检测哪些子目录。例如kernel中在mm目录和drivers/char/drm目录下都定义了
alloc_pages函数,那么可以以下列方式调用genfull:
genfull -s "mm include/linux drivers/block arch/i386"
实际的使用中,-s非常方便,请大家记住这个选项。
4. 使用Daemon/Client模式
当full.graph很大时,大量的时间花费到读取输入文件上了,例如kernel的full.graph是很大的,前面生成的大约有15M,这还不是全部内核的函数调用分析信息。为了节省时间,可以讲gengraph以daemon方式运行,这药使用-p选项:
gengraph -p -g linux-2.6.25/full.graph
该命令返回时gengraph以daemon方式运行,同时在/tmp目录下生成了codeviz.pipe文件。要生成函数调用图,可以使用-q选项:
gengraph -q -t -d 2 -f alloc_pages
要终止gengraph的运行,使用如下命令:
echo QUIT & /tmpcodeviz.pipe
六、进阶演示
以分析《嵌入式实时操作系统 uC/OS-II (第二版)》中的第一个范例程序为例,是什么程序不要紧,这里主要看的是如何使用及使用后的效果。
首先分析main():
1. gengraph --output-type gif -f main
分析main()的call graph,得到的图如下,看不出要领:
2. gengraph --output-type gif -f main -s OSInit
暂时不关心OSInit()的内部实现细节(参数 -s),让它显示为一个节点。得到的图如下,有点乱,不过好多了:
3. gengraph --output-type gif -f main -s OSInit -i "OSCPUSaveSR;OSCPURestoreSR"
基本上每个函数都会有进入/退出临界区的代码,忽略之(参数 -i)。得到的图如下,基本清楚了:
4. gengraph --output-type gif -f main -s "OSIOSSemCreate" -i "OSCPUSaveSR;OSCPURestoreSR" -k
OSSemCreate()的内部细节似乎也不用关心,不过保留中间文件sub.graph(参数 -k),得到的图如下,
5. dot -Tgif -o main.gif sub.graph
修改sub.graph,使图形符合函数调用顺序,最后得到的图如下,有了这个都不用看代码了:)
接着分析OSTimeDly()的被调用关系:
gengraph --output-type gif -r -f OSTimeDly
看看哪些函数调用了OSTimeDly(),参数 -r ,Task()和TaskStart()都是用户编写的函数:
最后看看Task()直接调用了哪些函数:
gengraph --output-type gif -d 1 -f Task
只看从Task出发的第一层调用(参数 -d 1):
七、安装过程出现的错误及解决方案
1. 在运行./install_gcc-4.6.2.sh时出现下面错误:
gcc configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+
从错误中可以看出:GCC编译需要GMP, MPFR, MPC这三个库(有的系统已经安装了就没有这个提示,我的没有安装),有两种安装方法(建议第二种):
(1)二进制源码安装(强烈不推荐)
我使用的版本为gmp-4.3.2,mpfr-2.4.2和mpc-0.8.1,在&"
下载,根据提示的顺序分别安装GMP,MPFR和MPC(mpfr依赖gmp,mpc依赖gmp和mpfr),这里全部自己指定了安装目录,如果没有指定
则默认分装在在/usr/include、/usr/lib和/usr/share,管理起来不方便,比如想卸载的时候还得一个个去找:
安装gmp: ./configure --prefix=/usr/local/gmp-4.3.2; make install
安装mpfr: ./configure --prefix=/usr/local/mpfr-2.4.2 --with-gmp=/usr/local/gmp-4.3.2/; make install
安装mpc: ./configure
--prefix=/usr/local/mpc-0.8.1 --with-gmp=/usr/local/gmp-4.3.2/
--with-mpfr=/usr/local/mpfr-2.4.2/; make install
PS:安装过程中可能又出现新的错误提示,请看2、3、4条。
配置环境变量:我这里指定了安装位置,如果没有指定则
这几个库的默认位置是/usr/local/include和/usr/local/lib,不管有没有指定GCC编译时都可能会找不到这三个库,需要确
认库位置是否在环境变量LD_LIBRARY_PATH中,查看环境变量内容可以用命令
$echo $LD_LIBRARY_PATH
设置该环境变量命令如下:
指定安装:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/gmp-4.3.2/lib:/usr/local/mpfr-2.4.2/lib:/usr/local/mpc-0.8.1/lib
默认安装:$export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib
PS:十分不推荐这种安装方法,一般来说这样的确可以成功安装,但是也不排除安装过程中又出现新的问题,具体看问题5。
(2)gcc自带脚本安装(强烈推荐)
方法(1)的安装方法十分繁琐,安装过程中可能出现各种预料不到的新错误,因此gcc
源码包中自带了一个gcc依赖库安装脚本download_prerequisites,位置在gcc源码目录中的
contrib/download_prerequisites,因此只需要进入该目录,直接运行脚本安装即可:.
/download_prerequisites
PS:该脚本内容如下:
#! /bin/sh
# Download some prerequisites needed by gcc.
# Run this from the top level of the gcc source tree and the gcc
# build will do the right thing.
# (C) 2010 Free Software Foundation
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
MPFR=mpfr-2.4.2
GMP=gmp-4.3.2
MPC=mpc-0.8.1
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPFR.tar.bz2 || exit 1
tar xjf $MPFR.tar.bz2 || exit 1
ln -sf $MPFR mpfr || exit 1
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$GMP.tar.bz2 || exit 1
tar xjf $GMP.tar.bz2
ln -sf $GMP gmp || exit 1
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPC.tar.gz || exit 1
tar xzf $MPC.tar.gz || exit 1
ln -sf $MPC mpc || exit 1
rm $MPFR.tar.bz2 $GMP.tar.bz2 $MPC.tar.gz || exit 1
可见是通过wget的方式下载安装,因此如果没有安装wget则需要先安装下。
大家仔细看下这个脚本,发现非常简单,就是从网上自动下载三个依赖库并解压,然后建立三个改名后的软链接分别指向这三个库,这里建立软链接过程中也可能出错,具体看问题6,大家也可以自己修改脚本,改成直接修改名称然后移到gcc目录下。
技巧:从这里也可以看出,gcc所依赖的库其实只要解压了放在gcc当前目录下就行了,方法(1)的那么多步骤其实都可以省掉,直接将下载的三个压缩包解压后改名移到gcc下面即可,也不用设置环境变量了。
2. 编译gmp时出现错误:
No usable m4 in $PATH or /usr/5bin (see config.log for reasons).
由此可以看出是缺少M4文件。可以去这里下载:http://ftp.gnu.org/gnu/m4/然后编译安装,我由于是Ubuntu系统,就直接
sudo apt-get install m4安装了。
3. 安装mpfr时出现错误:
configure: error: gmp.h can't be found, or is unusable.
这是因为在安装mpfr时未先安装gmp导致的,mpfr依赖于gmp。
4. 安装mpc时出现错误:
configure: error: libgmp not found or uses a different ABI.和configure: error: libmpfr not found or uses a different ABI.&。
同样是因为未安装mpc依赖的库gmp和mpfr。
5. 在运行./install_gcc-4.6.2.sh过程中出现错误,即按照gcc过程中出现的问题:
(1)libmpfr.so.1: cannot open shared object file: No such file or directory
分析:该脚本就是安装gcc,但是如果你出现了问题1,并且使用方法(1)解决该问题,那么你后期就可能出现这样的问题,当然你运气没那么背的话一般不会出现这样的问题,反正我运行比较背,出现了这样的问题。
解决方法:可以参考这篇文章http://blog.csdn.net/leo115/article/details/7671819解决。
(2)../../gcc-4.6.2/gcc/realmpfr.h:27:17: fatal error: mpc.h: No such file or directory
分析:gcc没找到所依赖的库mpc,原因很多,最有可能是你没设置环境变量或mpc放的地方不对。
解决方法:设置环境变量,看问题1。
(3) /usr/include/stdc-predef.h:30:26: fatal error: bits/predefs.h: No such file or directory
分析:用命令&locate
bits/predefs.h&找下该头文件的路径,发现是在'/usr/include/x86_64-linux-gnu'
解决方法:设置环境变量:
#export C_INCLUDE_PATH=/usr/include/i386-linux-gnu && export CPLUS_INCLUDE_PATH=$C_INCLUDE_PATH
/usr/bin/ld: cannot find crti.o: No such file or directory
分析:同样用&locate
crti.o& 找下这个文件,在'/usr/lib/i386-linux-gnu/crti.o'。
解决方法:设置LIBRARY_PATH
(LDFLAGS)这个环境变量如下:
#export LIBRARY_PATH=/usr/lib/i386-linux-gnu
(5)unwind-dw2.c:1031:
error: field `info' has incomplete type
分析:这个错误搞了好久,因为网上找不到对应的解决方法,只说这是gcc的一个bug。
解决方法:深入到源文件中,发现错误的地方是这样的:
static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
struct dwarf_fde *
struct dwarf_cie *
const unsigned char *aug, *insn, *
memset (fs, 0, sizeof (*fs));
context-&args_size = 0;
context-&lsda = 0;
fde = _Unwind_Find_FDE (context-&ra - 1, &context-&bases); //这里返回了NULL
if (fde == NULL)
/* Couldn't find frame unwind info for this function.
target-specific fallback mechanism.
This will necessarily
not profide a personality routine or LSDA.
#ifdef MD_FALLBACK_FRAME_STATE_FOR
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success); // 出错的地方
return _URC_END_OF_STACK;
return _URC_NO_REASON;
return _URC_END_OF_STACK;
//出错返回
出错的地方用标注了,因为fde返回了NULL,导致不能找到frame unwind info,最重要的是下面这个方法
MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
出错了,为什么返回NULL我肯定研究不出来,只知道这个函数调用失败了,导致不成功,于是我的解决方法十分偷懒,就是将下面的两行注释掉了,直接success,哈哈,勿喷我,因为这样做过后就解决了,后面一路成功~~~
// MD_FALLBACK_FRAME_STATE_FOR (context, fs, success); // 出错的地方
// return _URC_END_OF_STACK;
6.& 解决ln&-s&软链接产生Too&many&levels&of&symbolic&links错误
从网上查找了一下原因,原来是建立软连接的时候采用的是相对路径,所以才会产生这样的错误,解决方式是采用绝对路径建立软链接:这样问题就解决了。
本文查阅了网上的许多资料比较详细的讲解了CodeViz的安装和使用。CodeViz依赖于GraphViz,因而可以生成十分丰富的函数调用图。具体选项的使用及图像格式的选择可由读者根据个人需要和偏好自己揣摩使用。在分析源码的时候,把这些图形打印在手边,在上面做笔记,实在方便收益颇多。
九、参考资料:
1. http://blog.csdn.net/delphiwcdj/article/details/9936717
2. http://www.cppblog.com/hacrwang/archive//27296.html
3. http://www.cnblogs.com/xuxm2007/archive//1851086.html
阅读(...) 评论()【Graphviz】初识Graphviz
日常的开发工作中,为代码添加注释是代码可维护性的一个重要方面,但是仅仅提供注释是不够的,特别是当系统功能越来越复杂,涉及到的模块越来越多的时候,仅仅靠代码就很难从宏观的层次去理解。因此我们需要图例的支持,图例不仅仅包含功能之间的交互,也可以包含复杂的数据结构的示意图,数据流向等。(我自己学习Graphviz主要是为了对生物网络进行可视化)
但是,常用的UML建模工具,如VISIO等都略显复杂,且体积庞大。对于开发人员,特别是后台开发人员来说,命令行,脚本才是最友好的,而图形界面会很大程度的限制开发效率。相对于鼠标,键盘才是开发人员最好的朋友。
graphviz简介
本文介绍一个高效而简洁的绘图工具graphviz。graphviz是贝尔实验室开发的一个开源的工具包,它使用一个特定的DSL(领域特定语言):dot作为脚本语言,然后使用布局引擎来解析此脚本,并完成自动布局(本文在后面说了,自动布局是Graphviz的强项之一)。graphviz提供丰富的导出格式,如常用的图片格式,SVG,PDF格式等。
graphviz中包含了众多的布局器:
dot 默认布局方式,主要用于有向图
neato 基于spring-model(又称force-based)算法
twopi 径向布局
circo 圆环布局
fdp 用于无向图
graphviz的设计初衷是对有向图/无向图等进行自动布局,开发人员使用dot脚本定义图形元素,然后选择算法进行布局,最终导出结果。
首先,在dot脚本中定义图的顶点和边,顶点和边都具有各自的属性,比如形状,颜色,填充模式,字体,样式等。然后使用合适的布局算法进行布局。布局算法除了绘制各个顶点和边之外,需要尽可能的将顶点均匀的分布在画布上,并且尽可能的减少边的交叉(如果交叉过多,就很难看清楚顶点之间的关系了)。所以使用graphviz的一般流程为:
定义一个图,并向图中添加需要的顶点和边
为顶点和边添加样式
使用布局引擎进行绘制
一旦熟悉这种开发模式,就可以快速的将你的想法绘制出来。配合一个良好的编辑器(vim/emacs)等,可以极大的提高开发效率,与常见的GUI应用的所见即所得模式对应,此模式称为所思即所得。比如在我的机器上,使用vim编辑dot脚本,然后将F8映射为调用dot引擎去绘制当前脚本,并打开一个新的窗口来显示运行结果:
对于开发人员而言,经常会用到的图形绘制可能包括:函数调用关系,一个复杂的数据结构,系统的模块组成,抽象语法树等。
graphviz包含3种元素,图,顶点和边。每个元素都可以具有各自的属性,用来定义字体,样式,颜色,形状等。下面是一些简单的示例,可以帮助我们快速的了解graphviz的基本用法。
第一个graphviz图
比如,要绘制一个有向图,包含4个节点a,b,c,d。其中a指向b,b和c指向d。可以定义下列脚本:
1: digraph abc{
使用dot布局方式,绘制出来的效果如下:
的顶点中的文字为定义顶点变量的名称,形状为椭圆。边的默认样式为黑色实线箭头,我们可以在脚本中做一下修改,将顶点改为方形,边改为虚线。
定义顶点和边的样式
在digraph的花括号内,添加顶点和边的新定义:
1: node [shape="record"];
2: edge [style="dashed"];
则绘制的效果如下:
进一步修改顶点和边样式
进一步,我们将顶点a的颜色改为淡绿色,并将c到d的边改为红色,脚本如下:
1: digraph abc{
2: node [shape="record"];
3: edge [style="dashed"];
5: a [style="filled", color="black", fillcolor="chartreuse"];
12: c -& d [color="red"];
绘制的结果如下:
应当注意到,顶点和边都接受属性的定义,形式为在顶点和边的定义之后加上一个由方括号括起来的key-value列表,每个key-value对由逗号隔开。如果图中顶点和边采用统一的风格,则可以在图定义的首部定义node,
edge的属性。比如上图中,定义所有的顶点为方框,所有的边为虚线,在具体的顶点和边之后定义的属性将覆盖此全局属性。如特定与a的绿色,c到d的边的红色。
子图的绘制
graphviz支持子图,即图中的部分节点和边相对对立(软件的模块划分经常如此)。比如,我们可以将顶点c和d归为一个子图:
1: digraph abc{
3: node [shape="record"];
4: edge [style="dashed"];
6: a [style="filled", color="black", fillcolor="chartreuse"];
subgraph cluster_cd{
label="c and d";
bgcolor="mintcream";
18: c -& d [color="red"];
将c和d划分到cluster_cd这个子图中,标签为”c and d”,并添加背景色,以方便与主图区分开,绘制结果如下:
应该注意的是,子图的名称必须以cluster开头,否则graphviz无法设别。
事实上,从dot的语法及上述的示例中,很容易看出,dot脚本很容易被其他语言生成。比如,使用一些简单的数据库查询就可以生成数据库中的ER图的dot脚本。
如果你追求高效的开发速度,并希望快速的将自己的想法画出来,那么graphviz是一个很不错的选择。
当然,graphviz也有一定的局限,比如绘制时序图(序列图)就很难实现。graphviz的节点出现在画布上的位置事实上是不确定的,依赖于所使用的布局算法,而不是在脚本中出现的位置,这可能使刚开始接触graphviz的开发人员有点不适应。graphviz的强项在于自动布局,当图中的顶点和边的数目变得很多的时候,才能很好的体会这一特性的好处:
比如上图,或者较上图更复杂的图,如果采用手工绘制显然是不可能的,只能通过graphviz提供的自动布局引擎来完成。如果仅用于展示模块间的关系,子模块与子模块间通信的方式,模块的逻辑位置等,graphviz完全可以胜任,但是如果图中对象的物理位置必须是准确的,如节点A必须位于左上角,节点B必须与A相邻等特性,使用graphviz则很难做到。毕竟,它的强项是自动布局,事实上,所有的节点对与布局引擎而言,权重在初始时都是相同的,只是在渲染之后,节点的大小,形状等特性才会影响权重。
本文只是初步介绍了graphviz的简单应用,如图的定义,顶点/边的属性定义,如果运行等,事实上还有很多的属性,如画布的大小,字体的选择,颜色列表等,大家可以通过graphviz的官网()来找到更详细的资料。
本文摘自:(中间有部分省略)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。doxygen+graphviz生成工程中的类继承树及函数调用图 - hequn8128 - 博客园
在阅读代码量比较多的项目时,类的继承树和函数调用图能够直观地向我们显示类之间或者函数之间的各种关系,方便我们了解程序的整体框架,很多时候可以起到事半功倍的作用。这里尝试了用doxygen+graphviz生成工程中的类继承树和函数调用图的方法,总体来说操作比较方便。网上还有其他一些方法,比如eclipse插件还有Rational Software Rrchitect,对于eclipse插件,功能比较有限,而Rational Software Rrchitect软件装的时候老有问题,以后再尝试下。
doxygen是一款用来生成项目文档的软件,类似于javadoc,但是比javadoc要强大,还可以对项目代码的结构进行分析。最初doxygen设计来分析c++代码,现在也支持如java, python, obj-c, php等语言。
graphviz是一款展示图和网络结构的软件,用来绘制DOT语言脚本描述的图形。
总的来说,就是用doxygen来生成结构,用graphviz来显示结构。
一、软件安装。(环境:win7 64bit)
首先,安装doxygen,可以在官网的下载,下载doxygen-1.8.8-setup.exe,安装即可。软件集成了32位和64位安装包。然后,安装graphviz,,下载windows安装包。
二、配置doxygen。(graphviz安装好后不需要其他配置操作)
doxygen打开的页面如下图所示,有三个配置选项卡:wizard,expert,run。
1)wizard选项卡。
project)step1中先设置doxygen生成文档的工作空间,step2中设置要生成文档的工程名字,源代码的目录,是否递归处理源代码,还有生成文档存放的位置。
mode)中选择要处理的语言
Diagrams)勾选Use do tool from the GraphViz package,下面的复选框也全勾上。
2)Expert选项卡。
build)中主要勾选EXTRACE_ALL, EXTRACE_PRIVATE,&EXTRACE_STATIC,&EXTRACE_LOCAL_CALSSES,&EXTRACE_LOCAL_METHODS
Doc)中勾选MUL_LOOK, &设置DOT_PATH即doc.exe的位置,位于graphviz安装路径下的bin目录下。(这里比较关键,我一开始没设置路径,识别不出graphviz的地址,继承关系解析出来了,但是图没画出来)。
3)Run选项卡
可以查看Show configuration的配置。以下是我的配置。
# Doxyfile 1.8.8
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING
PROJECT_NAME
= javautil
PROJECT_NUMBER
PROJECT_BRIEF
PROJECT_LOGO
OUTPUT_DIRECTORY
= E:/doxygenWorkspace/javautil
CREATE_SUBDIRS
ALLOW_UNICODE_NAMES
OUTPUT_LANGUAGE
BRIEF_MEMBER_DESC
REPEAT_BRIEF
ABBREVIATE_BRIEF
= "The $name class" \
"The $name widget" \
"The $name file" \
provides \
specifies \
contains \
represents \
"The $name class"
ALWAYS_DETAILED_SEC
INLINE_INHERITED_MEMB
FULL_PATH_NAMES
STRIP_FROM_PATH
STRIP_FROM_INC_PATH
SHORT_NAMES
JAVADOC_AUTOBRIEF
QT_AUTOBRIEF
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS
SEPARATE_MEMBER_PAGES
OPTIMIZE_OUTPUT_FOR_C
OPTIMIZE_OUTPUT_JAVA
OPTIMIZE_FOR_FORTRAN
OPTIMIZE_OUTPUT_VHDL
EXTENSION_MAPPING
MARKDOWN_SUPPORT
AUTOLINK_SUPPORT
BUILTIN_STL_SUPPORT
CPP_CLI_SUPPORT
SIP_SUPPORT
IDL_PROPERTY_SUPPORT
DISTRIBUTE_GROUP_DOC
SUBGROUPING
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS
TYPEDEF_HIDES_STRUCT
LOOKUP_CACHE_SIZE
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL
EXTRACT_PRIVATE
EXTRACT_PACKAGE
EXTRACT_STATIC
EXTRACT_LOCAL_CLASSES
EXTRACT_LOCAL_METHODS
EXTRACT_ANON_NSPACES
HIDE_UNDOC_MEMBERS
HIDE_UNDOC_CLASSES
HIDE_FRIEND_COMPOUNDS
HIDE_IN_BODY_DOCS
INTERNAL_DOCS
CASE_SENSE_NAMES
HIDE_SCOPE_NAMES
SHOW_INCLUDE_FILES
SHOW_GROUPED_MEMB_INC
FORCE_LOCAL_INCLUDES
INLINE_INFO
SORT_MEMBER_DOCS
SORT_BRIEF_DOCS
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES
SORT_BY_SCOPE_NAME
STRICT_PROTO_MATCHING
GENERATE_TODOLIST
GENERATE_TESTLIST
GENERATE_BUGLIST
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS
MAX_INITIALIZER_LINES
SHOW_USED_FILES
SHOW_FILES
SHOW_NAMESPACES
FILE_VERSION_FILTER
LAYOUT_FILE
CITE_BIB_FILES
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
WARN_IF_UNDOCUMENTED
WARN_IF_DOC_ERROR
WARN_NO_PARAMDOC
WARN_FORMAT
= "$file:$line: $text"
WARN_LOGFILE
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
= E:/javatest
INPUT_ENCODING
FILE_PATTERNS
*.markdown \
EXCLUDE_SYMLINKS
EXCLUDE_PATTERNS
EXCLUDE_SYMBOLS
EXAMPLE_PATH
EXAMPLE_PATTERNS
EXAMPLE_RECURSIVE
IMAGE_PATH
INPUT_FILTER
FILTER_PATTERNS
FILTER_SOURCE_FILES
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER
INLINE_SOURCES
STRIP_CODE_COMMENTS
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS
VERBATIM_HEADERS
CLANG_ASSISTED_PARSING = NO
CLANG_OPTIONS
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX
COLS_IN_ALPHA_INDEX
IGNORE_PREFIX
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML
HTML_OUTPUT
HTML_FILE_EXTENSION
HTML_HEADER
HTML_FOOTER
HTML_STYLESHEET
HTML_EXTRA_STYLESHEET
HTML_EXTRA_FILES
HTML_COLORSTYLE_HUE
HTML_COLORSTYLE_SAT
HTML_COLORSTYLE_GAMMA
HTML_TIMESTAMP
HTML_DYNAMIC_SECTIONS
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET
DOCSET_FEEDNAME
= "Doxygen generated docs"
DOCSET_BUNDLE_ID
= org.doxygen.Project
DOCSET_PUBLISHER_ID
= org.doxygen.Publisher
DOCSET_PUBLISHER_NAME
= Publisher
GENERATE_HTMLHELP
HHC_LOCATION
GENERATE_CHI
CHM_INDEX_ENCODING
BINARY_TOC
TOC_EXPAND
GENERATE_QHP
QHP_NAMESPACE
= org.doxygen.Project
QHP_VIRTUAL_FOLDER
QHP_CUST_FILTER_NAME
QHP_CUST_FILTER_ATTRS
QHP_SECT_FILTER_ATTRS
QHG_LOCATION
GENERATE_ECLIPSEHELP
ECLIPSE_DOC_ID
= org.doxygen.Project
DISABLE_INDEX
GENERATE_TREEVIEW
ENUM_VALUES_PER_LINE
TREEVIEW_WIDTH
EXT_LINKS_IN_WINDOW
FORMULA_FONTSIZE
FORMULA_TRANSPARENT
USE_MATHJAX
MATHJAX_FORMAT
= HTML-CSS
MATHJAX_RELPATH
= http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS
MATHJAX_CODEFILE
SEARCHENGINE
SERVER_BASED_SEARCH
EXTERNAL_SEARCH
SEARCHENGINE_URL
SEARCHDATA_FILE
= searchdata.xml
EXTERNAL_SEARCH_ID
EXTRA_SEARCH_MAPPINGS
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX
LATEX_OUTPUT
LATEX_CMD_NAME
MAKEINDEX_CMD_NAME
= makeindex
COMPACT_LATEX
PAPER_TYPE
EXTRA_PACKAGES
LATEX_HEADER
LATEX_FOOTER
LATEX_EXTRA_FILES
PDF_HYPERLINKS
USE_PDFLATEX
LATEX_BATCHMODE
LATEX_HIDE_INDICES
LATEX_SOURCE_CODE
LATEX_BIB_STYLE
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF
RTF_OUTPUT
COMPACT_RTF
RTF_HYPERLINKS
RTF_STYLESHEET_FILE
RTF_EXTENSIONS_FILE
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN
MAN_OUTPUT
MAN_EXTENSION
MAN_SUBDIR
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML
XML_OUTPUT
XML_PROGRAMLISTING
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK
DOCBOOK_OUTPUT
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD
PERLMOD_LATEX
PERLMOD_PRETTY
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING
MACRO_EXPANSION
EXPAND_ONLY_PREDEF
SEARCH_INCLUDES
INCLUDE_PATH
INCLUDE_FILE_PATTERNS
PREDEFINED
EXPAND_AS_DEFINED
SKIP_FUNCTION_MACROS
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
GENERATE_TAGFILE
ALLEXTERNALS
EXTERNAL_GROUPS
EXTERNAL_PAGES
= /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS
MSCGEN_PATH
HIDE_UNDOC_RELATIONS
DOT_NUM_THREADS
DOT_FONTNAME
= Helvetica
DOT_FONTSIZE
DOT_FONTPATH
CLASS_GRAPH
COLLABORATION_GRAPH
GROUP_GRAPHS
UML_LIMIT_NUM_FIELDS
TEMPLATE_RELATIONS
INCLUDE_GRAPH
INCLUDED_BY_GRAPH
CALL_GRAPH
CALLER_GRAPH
GRAPHICAL_HIERARCHY
DIRECTORY_GRAPH
DOT_IMAGE_FORMAT
INTERACTIVE_SVG
= "D:/Program Files (x86)/Graphviz2.38/bin"
DOTFILE_DIRS
MSCFILE_DIRS
DIAFILE_DIRS
PLANTUML_JAR_PATH
DOT_GRAPH_MAX_NODES
MAX_DOT_GRAPH_DEPTH
DOT_TRANSPARENT
DOT_MULTI_TARGETS
GENERATE_LEGEND
DOT_CLEANUP
点Run doxygen即可开始解析并生成类之间的关系图。
点Show HTML output进行查看。选择Class-&Class Hierarchy查看类的继承图。下图为java.util包中的类继承图的一部分,另存为可以查看大图。

我要回帖

更多关于 graphviz 使用 的文章

 

随机推荐