一般来说,如果我们想要研究一个c/c 项目的源码,我们首先要做的是为该项目生成tags文件,linux内核是c写的,所以它也不例外。
tags文件种类有很多,比如 ctags、etags、cscope、gtags 等,有关他们的区别可以参考下面链接里的内容:
https://github.com/oracle/opengrok/wiki/Comparison-with-Similar-Tools
根据我的测试,gtags是最好用的,其官方地址是:
https://www.gnu.org/software/global/
由于linux内核的项目结构非常庞大,如果我们在项目的根目录直接为所有文件生成tags的话,会包含很多不必要的文件,比如我们只想要x86平台的相关实现,但结果却包含了各种其他平台的逻辑。
那怎么办呢,其实linux的Makefile里已经帮我们写好了如何生成各种tags,看下面的命令:
代码语言:javascript复制$ make help
# 省略其他
tags/TAGS - Generate tags file for editors
cscope - Generate cscope index
gtags - Generate GNU GLOBAL index
# 省略其他
由上可以看到,我们只要执行对应的make命令,就可以生成各种tags文件了,我们来试下:
代码语言:javascript复制$ make gtags
GEN gtags
$ ls -lh G*
-rw-r--r-- 1 yt yt 6.7M Nov 16 22:45 GPATH
-rw-r--r-- 1 yt yt 397M Nov 16 22:45 GRTAGS
-rw-r--r-- 1 yt yt 320M Nov 16 22:45 GTAGS
由上可见,make gtags命令正确生成了gtags相关的各种文件。
但它是如何实现的呢,看下Makefile里对应的逻辑:
代码语言:javascript复制# Generate tags for editors
# ---------------------------------------------------------------------------
quiet_cmd_tags = GEN $@
cmd_tags = $(BASH) $(srctree)/scripts/tags.sh $@
tags TAGS cscope gtags: FORCE
$(call cmd,tags)
当我们执行make gtags等命令时,它最终调用的都是shell脚本./scripts/tags.sh,参数是我们想要生成的tags类型。
粗略看下该脚本里的内容:
代码语言:javascript复制case "$1" in
"cscope")
docscope
;;
"gtags")
dogtags
;;
"tags")
rm -f tags
xtags ctags
remove_structs=y
;;
"TAGS")
rm -f TAGS
xtags etags
remove_structs=y
;;
esac
由上可见,当我们通过make命令生成各种不同的tags时,该tags类型会被传到这个脚本里, 然后再根据这个类型执行对应的方法生成对应的tags。
由于该脚本的内容比较简单,这里就不再继续讲解了,有兴趣的同学可以自己看下。
在生成tags文件后,我们就可以在各种编辑器里使用了,下面是emacs编辑器使用gtags的效果图:
还不错吧。