大家好,我是小麦。在学习编程的路途漫漫,优秀的源码是非常珍贵的学习资源,阅读源码也是有效提高自己的一个好方法。
工欲善其事必先利其器;
我发现函数调用图可以让我们更加直观地了解到源码函数直接的调用和层次关系,提高阅读源码的效率 。
1 前言
看源码的时候,心血来潮想弄一下函数之前的调用关系,想起以前doxygen
配合graphviz
使用可以生成比较直观的函数调用关系图,但是前提是函数的注释需要严格按照doxygen
的规范,具体可以自己去搜索一下,当然使用source insight
等利器也很方便;
本文主要通过gcc
+egypt
+graphviz(dot)
三个工具轻松生成源码的函数调用关系图;下图是本人在阅读FreeRTOS
源码tasks.c
时生成的调用关系图,具体如下所示;
一个例子
2 graphviz 安装
Graphviz (Graph Visualization Software的缩写)是一个由AT&T实验室启动的开源工具包,用于绘制DOT语言脚本描述的图形。ubuntu下可以直接安装;
sudo apt-get install graphviz
直接输入指令后,系统开始安装;
成功安装graphviz
,这里我们就可以使用dot
工具了,具体使用方法如下;
3 egypt 安装
egypt官网: http://www.gson.org/egypt/
简洁的首页
下载后的文件为egypt-1.10.tar.gz
;找到文件所在路径;
sudo find \ -name egypt-1.10.tar.gz
然后解压:
sudo tar -xvf egypt-1.10.tar.gz
解压得到egypt-1.10
;
cd egypt-1.10 && sduo chmod +x egypt
最终可以看到文件结构如下;
将egypt
移动到/usr/bin
,方便后面直接调用,或者将当前egypt
所在路径添加到环境变量中;
sudo cp egypt /usr/bin
以上,已经完成了egypt
的安装;
使用方法如下;
egypt [--omit function,function,...] [--include-external] <rtl-file>... | dotty -
egypt [--omit function,function,...] [--include-external] <rtl-file>... | dot <dot-options>
4 测试
编写程序test.c
,具体如下所示;
#include <stdio.h>
void test0();
void test1();
void test2();
void test3();
int main()
{
test1();
test2();
test3();
return 0;
}
void test0(void){
printf("hello");
}
void test1(void)
{
test0();
}
void test2(void)
{
test1();
}
void test3(void)
{
}
编译需要加上参数-fdump-rtl-expand
生成相应的dump文件;
gcc -fdump-rtl-expand -c test.c
这里有我们需要的文件test.c.229r.expand
;
输入如下指令;
egypt test.c.229r.expand | dot -T png -o test.png?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg==,t_20
最终生成了顺利生成test.png?x-oss-process=image/watermark,g_center,image_YXJ0aWNsZS9wdWJsaWMvd2F0ZXJtYXJrLnBuZz94LW9zcy1wcm9jZXNzPWltYWdlL3Jlc2l6ZSxQXzQwCg==,t_20
,具体如下图所示;
最终调用关系图
5 结论
对C语言源码的阅读用这个办法还是有点小麻烦,无法一键生成调用关系,,
另外还需要gcc编译源码生成dumpfile
文件,如果想要方便一些,可能还需要自己写脚本实现自动化,如果大佬有更好的办法,欢迎留言区讨论。