探索Linux下面如何阅读代码

来源:互联网 发布:会计证软件题库手机 编辑:程序博客网 时间:2024/04/29 03:16

1. 参考资料

参考资料:

  • Linux下阅读源码工具
  • vim 中Ctags的安装和使用
  • ctags
  • ctags中文
  • cscope的使用方法
  • 超详细的vim+cscope的使用规则
  • cscope官网:包括一些教程

2. 要点

baidu之后,发现有3点:

  • ctags:可以ctags --version检查本机上安装的ctags是否为下面这个版本,本文接下来的示例即以此ctags进行演练
    flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags --versionExuberant Ctags 5.9~svn20110310, Copyright (C) 1996-2009 Darren Hiebert  Compiled: Nov  9 2011, 17:40:39  Addresses: <dhiebert@users.sourceforge.net>, http://ctags.sourceforge.net  Optional compiled features: +wildcards, +regexflying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ 

  • cscope
  • taglist



3. ctags

当然,要学会游泳,最好的方式就是下水。所以,这里就通过一系列的命令熟悉整个环境。


3.1 建立tags文件

先用最简单的方式进行实践,比如用ctags -R .对当前目录下的文件生成tags文件。

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ll总用量 368drwxr-xr-x 4 flying-bird flying-bird  4096  6月 22 10:31 ./drwxrwxr-x 8 flying-bird flying-bird  4096  6月 18 22:20 ../-rw-rw-r-- 1 flying-bird flying-bird  1514  6月 18 19:01 Android.mk-rw-rw-r-- 1 flying-bird flying-bird  1154  6月 18 19:01 Asec.h-rw-rw-r-- 1 flying-bird flying-bird  2227  6月 18 19:01 CleanSpec.mk-rw-rw-r-- 1 flying-bird flying-bird 23457  6月 18 19:01 CommandListener.cpp-rw-rw-r-- 1 flying-bird flying-bird  2466  6月 18 19:01 CommandListener.h-rw-rw-r-- 1 flying-bird flying-bird 65366  6月 18 19:01 cryptfs.c-rw-rw-r-- 1 flying-bird flying-bird  5680  6月 18 19:01 cryptfs.h-rw-rw-r-- 1 flying-bird flying-bird  8518  6月 18 19:01 Devmapper.cpp-rw-rw-r-- 1 flying-bird flying-bird  1270  6月 18 19:01 Devmapper.h-rw-rw-r-- 1 flying-bird flying-bird 15543  6月 18 19:01 DirectVolume.cpp-rw-rw-r-- 1 flying-bird flying-bird  2767  6月 18 19:01 DirectVolume.h-rw-rw-r-- 1 flying-bird flying-bird  2674  6月 18 19:01 Ext4.cpp-rw-rw-r-- 1 flying-bird flying-bird   894  6月 18 19:01 Ext4.h-rw-rw-r-- 1 flying-bird flying-bird  6943  6月 18 19:01 Fat.cpp-rw-rw-r-- 1 flying-bird flying-bird  1138  6月 18 19:01 Fat.h-rw-rw-r-- 1 flying-bird flying-bird  4679  6月 18 19:01 fstrim.c-rw-rw-r-- 1 flying-bird flying-bird   723  6月 18 19:01 fstrim.hdrwxrwxr-x 8 flying-bird flying-bird  4096  6月 18 19:01 .git/-rw-rw-r-- 1 flying-bird flying-bird  2525  6月 18 19:01 hash.h-rw-rw-r-- 1 flying-bird flying-bird  7524  6月 18 19:01 Loop.cpp-rw-rw-r-- 1 flying-bird flying-bird  1294  6月 18 19:01 Loop.h-rw-rw-r-- 1 flying-bird flying-bird  5063  6月 18 19:01 main.cpp-rw-rw-r-- 1 flying-bird flying-bird  1440  6月 18 19:01 NetlinkHandler.cpp-rw-rw-r-- 1 flying-bird flying-bird   949  6月 18 19:01 NetlinkHandler.h-rw-rw-r-- 1 flying-bird flying-bird  2673  6月 18 19:01 NetlinkManager.cpp-rw-rw-r-- 1 flying-bird flying-bird  1247  6月 18 19:01 NetlinkManager.h-rw-rw-r-- 1 flying-bird flying-bird  6542  6月 18 19:01 Process.cpp-rw-rw-r-- 1 flying-bird flying-bird  1439  6月 18 19:01 Process.h-rw-rw-r-- 1 flying-bird flying-bird  1334  6月 18 19:01 ResponseCode.cpp-rw-rw-r-- 1 flying-bird flying-bird  2865  6月 18 19:01 ResponseCode.hdrwxrwxr-x 2 flying-bird flying-bird  4096  6月 18 19:01 tests/-rw-rw-r-- 1 flying-bird flying-bird  4249  6月 18 19:01 vdc.c-rw-rw-r-- 1 flying-bird flying-bird   732  6月 18 19:01 VoldCommand.cpp-rw-rw-r-- 1 flying-bird flying-bird   839  6月 18 19:01 VoldCommand.h-rw-rw-r-- 1 flying-bird flying-bird   819  6月 18 19:01 VoldUtil.c-rw-rw-r-- 1 flying-bird flying-bird   810  6月 18 19:01 VoldUtil.h-rw-rw-r-- 1 flying-bird flying-bird 19816  6月 18 19:01 Volume.cpp-rw-rw-r-- 1 flying-bird flying-bird  3328  6月 18 19:01 Volume.h-rw-rw-r-- 1 flying-bird flying-bird 48540  6月 18 19:01 VolumeManager.cpp-rw-rw-r-- 1 flying-bird flying-bird  5585  6月 18 19:01 VolumeManager.h-rw-rw-r-- 1 flying-bird flying-bird  2037  6月 18 19:01 Xwarp.cpp-rw-rw-r-- 1 flying-bird flying-bird  1049  6月 18 19:01 Xwarp.hflying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags -R .flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ll tags -rw-rw-r-- 1 flying-bird flying-bird 48915  6月 22 10:34 tagsflying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ 


3.2 了解tags文件

tags文件的内容包括宏、class、member function、function等所在的文件。示例如下:



tags文件一开始是注释信息,接下来是tags list,每一行的格式:tag name, file name, line number, tag kind. 其中kind含义如下:

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags --list-kinds=cc  classesd  macro definitionse  enumerators (values inside an enumeration)f  function definitionsg  enumeration namesl  local variables [off]m  class, struct, and union membersn  namespacesp  function prototypes [off]s  structure namest  typedefsu  union namesv  variable definitionsx  external and forward variable declarations [off]flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ ctags --list-kinds=c++c  classesd  macro definitionse  enumerators (values inside an enumeration)f  function definitionsg  enumeration namesl  local variables [off]m  class, struct, and union membersn  namespacesp  function prototypes [off]s  structure namest  typedefsu  union namesv  variable definitionsx  external and forward variable declarations [off]flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ 


3.3 打开tag所在的文件

然后用vim -t tagName命令,就可以打开tagName定义所在的文件,并自动定位到tagName所在的那一行。

示例:

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ vim -t usage

上述命令的执行效果:


要了解这一点,可以查看vim命令的帮助即可:

flying-bird@flying-bird:~/android/android_4.4.2_r2/system/vold$ vim -hVIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:10:09)用法: vim [参数] [文件 ..]       编辑指定的文件  或: vim [参数] -               从标准输入(stdin)读取文本  或: vim [参数] -t tag          编辑 tag 定义处的文件  或: vim [参数] -q [errorfile]  编辑第一个出错处的文件参数:   --在这以后只有文件名   -g使用图形界面 (同 "gvim")   -f  或  --nofork前台: 启动图形界面时不 fork   -vVi 模式 (同 "vi")   -eEx 模式 (同 "ex")

上面这个功能还是非常强的,因为经常需要查找某个函数的定义,用上面这个命令就非常方便了。


3.4 ts & tp & tn

这3个命令的全称分别是tag list, tag preview, tag next. 

前面介绍了可以用vim -t tagName打开一个source file,如果在多个文件中定义了多个名为tagName的language objects,那么这个vim命令也只是打开第一个包括了tagName的这个文件。——包括相同tag名称的文件,是按照文件名进行排序。

此时,可以通过ts来参考当前tagName还存在于哪些文件中。作为例子,我们以整个Android源码创建tags文件。然后执行vim -t usage命令:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ ll tags-rw-rw-r-- 1 flying-bird flying-bird 1920673761  6月 22 11:00 tagsflying-bird@flying-bird:~/android/android_4.4.2_r2$ vim -t usage

效果如下:



此时执行:ts看usage这个tag一共出现了几次:



这里显示了所有的usage。对于这种有多屏的情况,可以键入空格翻到下一屏。要跳转到目标文件,先Esc,此时屏幕最下面提示输入数字&回车:



比如输入231,然后回车,就自动打开对应的文件:


是不是非常方便?!


注意此时打开的是第231个usage的文件。此时:tn就是打开下一个即232 usage对应的文件,即在当前序号下跳转到下一个文件。对应地,可以练习tp的效果。如果要跳转很远的地方、或直接通过目录&文件名来跳转,还是像前面的操作那样,即输入:ts,列出所有的usage列表,上下翻屏,然后输入数字。


如此,通过:ts, :tp, :tn等就可以快速找到目标tag的位置。


3.5 Ctrl + ]

这个命令也非常有用,其作用是跳转到当前光标所在tag的所在。比如说当前行有一个函数调用,光标在这个函数调用处,通过在命令模式下输入Ctrl+]就可以跳转到该函数定义的地方。

相对应地,如果要再回到上次这个函数调用处呢?就是在命令模式下输入Ctrl+T。

再强调一下,这两个输入不需要先:,而是直接Ctrl+] 和 Ctrl+T。


比如下面这个例子,注意光标的位置(104行):



此时键入Ctrl+]之后,就是下面的效果:



如果再次Ctrl+T就回到上一次的地方。


需要补充的是,上面两个命令的跳转并不局限于当前打开的文件,而可以在vim的多个文件之间,必要情况下,会自动打开新的文件。


3.6 :ta tag

:ta tag是要先输入:的vim命令,它的作用是跳转到tag的定义所在。下面这个示例是以整个Android源码系统创建的tag file来操作,比如在某个文件中输入了:ta VolumeManager,如下:


回车后,就会打开VolumeManager所在的文件:



4. cscope

4.1 安装

直接从ubuntu软件中心,输入cscope,安装cscope.sourceforge.net对应的cscope即可。或者到这个网站上下载代码安装。


检查安装是否成功:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ cscope --versioncscope: version 15.7aflying-bird@flying-bird:~/android/android_4.4.2_r2$ cscope --helpUsage: cscope [-bcCdehklLqRTuUvV] [-f file] [-F file] [-i file] [-I dir] [-s dir]              [-p number] [-P path] [-[0-8] pattern] [source files]-b            Build the cross-reference only.-C            Ignore letter case when searching.-c            Use only ASCII characters in the cross-ref file (don't compress).-d            Do not update the cross-reference.-e            Suppress the <Ctrl>-e command prompt between files.-F symfile    Read symbol reference lines from symfile.-f reffile    Use reffile as cross-ref file name instead of cscope.out.-h            This help screen.-I incdir     Look in incdir for any #include files.-i namefile   Browse through files listed in namefile, instead of cscope.files-k            Kernel Mode - don't use /usr/include for #include files.-L            Do a single search with line-oriented output.-l            Line-oriented interface.-num pattern  Go to input field num (counting from 0) and find pattern.-P path       Prepend path to relative file names in pre-built cross-ref file.-p n          Display the last n file path components.-q            Build an inverted index for quick symbol searching.-R            Recurse directories for files.-s dir        Look in dir for additional source  files.-T            Use only the first eight characters to match against C symbols.-U            Check file time stamps.-u            Unconditionally build the cross-reference file.-v            Be more verbose in line mode.-V            Print the version number.Please see the manpage for more information.flying-bird@flying-bird:~/android/android_4.4.2_r2$ 


4.2 分析源代码文件

首先准备要分析的文件列表,然后用cscope命令进行分析:

find . -name "*.h" > cscope.filesfind . -name "*.c" >> cscope.filesfind . -name "*.cc" >> cscope.filesfind . -name "*.cpp" >> cscope.filesfind . -name "*.java" >> cscope.filescscope -bkq -i cscope.files


最后生成的文件:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ ll cs*-rw-rw-r-- 1 flying-bird flying-bird   17915097  6月 22 13:44 cscope.files-rw-rw-r-- 1 flying-bird flying-bird   62021632  6月 22 13:51 cscope.in.out-rw-rw-r-- 1 flying-bird flying-bird 1082712155  6月 22 13:51 cscope.out-rw-rw-r-- 1 flying-bird flying-bird  777698136  6月 22 13:51 cscope.po.outflying-bird@flying-bird:~/android/android_4.4.2_r2$ 

4.3 配置cscope

从http://cscope.sourceforge.net/cscope_vim_tutorial.html下载csope_maps.vim,并拷贝到/etc/vim/目录下。修改vimrc文件,让它source这个文件:

flying-bird@flying-bird:/etc/vim$ ll总用量 36drwxr-xr-x   2 root root  4096  6月 22 14:07 ./drwxr-xr-x 136 root root 12288  6月 22 08:42 ../-rw-r--r--   1 root root  7336  6月 22 13:58 cscope_maps.vim-rw-r--r--   1 root root   753  6月 22 14:07 gvimrc-rw-r--r--   1 root root  2300  6月 22 14:01 vimrc-rw-r--r--   1 root root   662  3月 12  2012 vimrc.tinyflying-bird@flying-bird:/etc/vim$ sudo vi vimrcflying-bird@flying-bird:/etc/vim$ cat vimrc" All system-wide defaults are set in $VIMRUNTIME/debian.vim (usually just。。。。。。。。。。。。。。。。。。" Source a global configuration file if availableif filereadable("/etc/vim/vimrc.local")  source /etc/vim/vimrc.localendifif filereadable("/etc/vim/cscope_maps.vim")  source /etc/vim/cscope_maps.vimendifflying-bird@flying-bird:/etc/vim$ 

4.4 使用

4.4.1 打开vim

可以使用vim打开一个文件,如:

flying-bird@flying-bird:~/android/android_4.4.2_r2$ gvim -t VolumeManager

此时,和ctags打开第一个定义tag的文件不同的是,现在会首先把所有文件都列出来,供你选择:


4.4.2 Ctrl + \ + S

当光标落在某个tag,此时按下Ctrl + \ + S(快速顺序按下),就会列出这个tag所有出现的地方。示例:


和ctags一样,Ctrl + T会跳会上一次的地方。


4.4.3 多窗口

通过gvim的菜单调出”文件浏览器“窗口;还可以把下面的output窗口拉出来,从而形成多窗口。效果:



5. taglist

5.1 下载&安装

从http://vim-taglist.sourceforge.net/index.html下载,比如taglist_46.zip。

安装方法可以参考http://vim-taglist.sourceforge.net/installation.html。

5.1.1 filetype on

有文档提到要设置filetype on.

在/etc/vim/vimrc中,有这么一段话:

" Uncomment the following to have Vim load indentation rules and plugins" according to the detected filetype."if has("autocmd")"  filetype plugin indent on"endif

经过验证,没有打开这个注释,下面的各项操作也是可以的。


5.1.2 system

在vim或者gvim环境中,输入“:echo exists('*system')”,其结果要求为1.


5.1.3 解压缩taglist

flying-bird@flying-bird:/etc/vim$ ll总用量 36drwxr-xr-x   2 root root  4096  6月 22 14:08 ./drwxr-xr-x 136 root root 12288  6月 22 17:44 ../-rw-r--r--   1 root root  7336  6月 22 13:58 cscope_maps.vim-rw-r--r--   1 root root   753  6月 22 14:07 gvimrc-rw-r--r--   1 root root  2300  6月 22 14:01 vimrc-rw-r--r--   1 root root   662  3月 12  2012 vimrc.tinyflying-bird@flying-bird:/etc/vim$ sudo cp ~/taglist_46.zip .[sudo] password for flying-bird: flying-bird@flying-bird:/etc/vim$ ll总用量 88drwxr-xr-x   2 root root  4096  6月 22 19:08 ./drwxr-xr-x 136 root root 12288  6月 22 17:44 ../-rw-r--r--   1 root root  7336  6月 22 13:58 cscope_maps.vim-rw-r--r--   1 root root   753  6月 22 14:07 gvimrc-rw-r--r--   1 root root 51455  6月 22 19:08 taglist_46.zip-rw-r--r--   1 root root  2300  6月 22 14:01 vimrc-rw-r--r--   1 root root   662  3月 12  2012 vimrc.tinyflying-bird@flying-bird:/etc/vim$ sudo unzip taglist_46.zip -d .Archive:  taglist_46.zip  inflating: ./plugin/taglist.vim      inflating: ./doc/taglist.txt       flying-bird@flying-bird:/etc/vim$ 

5.1.4 helptags

cd到doc目录,以root用户启动vim,然后输入:helptags .命令:

flying-bird@flying-bird:/etc/vim$ cd doc/flying-bird@flying-bird:/etc/vim/doc$ ll总用量 80drwxr-xr-x 2 root root  4096  6月 22 19:08 ./drwxr-xr-x 4 root root  4096  6月 22 19:08 ../-rwxr-xr-x 1 root root 69979  2月 26  2013 taglist.txt*flying-bird@flying-bird:/etc/vim/doc$ sudo vimflying-bird@flying-bird:/etc/vim/doc$ 

执行之后会在docs目录下面生成一个tags文件。


5.2 效果

以上配置完成之后,重启vim或gvim。输入:TlistToggle命令即可打开左边的符号窗口,或者输入:help taglist调出taglist的帮助窗口。





0 0
原创粉丝点击