使用vim看代码:cscope
http://blog.chinaunix.net/uid-24774106-id-3556337.html
vim+cscope+ctags 是Linux看代码利器,在网上搜vim教程一搜一大堆,很多讲的都不错,可惜自己都没学会。好早之前,我的老科长波哥曾经教过我一次,ctags我算是 学会大概,cscope只能算是入门级水平,比如查看某个函数调用,还得用:cs find c function这种比较慢的方法。我自己比较懒,花在熟练掌握工具的时间太少了,这么看来,自己还不是个好程序员。

cs show是显示当前可用的数据库,cs add是添加一个数据库。我们看下
我们不是已经添加了数据库了吗,为啥没找到了呢。原因就是我们生成cscope.out的时候,路径都是相对的路径。对于大工程我们怎么用cscope做到文件间的函数跳转呢?
阅读(404) | 评论(0) | 转发(0) |
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
vim+cscope+ctags 是Linux看代码利器,在网上搜vim教程一搜一大堆,很多讲的都不错,可惜自己都没学会。好早之前,我的老科长波哥曾经教过我一次,ctags我算是 学会大概,cscope只能算是入门级水平,比如查看某个函数调用,还得用:cs find c function这种比较慢的方法。我自己比较懒,花在熟练掌握工具的时间太少了,这么看来,自己还不是个好程序员。
cscope的存在让vim有了媲美Source Insight的能力,那么对大工程文件如何使用cscope呢?
最近在看PostgreSQL的源码,我们知道,PostgreSQL源码属于一个大型工程,src下面好多目录,不同目录下好多文件。好多教程讲述建立csope数据库的方法,都是下面的方法,以我的PostgreSQL为例)
最近在看PostgreSQL的源码,我们知道,PostgreSQL源码属于一个大型工程,src下面好多目录,不同目录下好多文件。好多教程讲述建立csope数据库的方法,都是下面的方法,以我的PostgreSQL为例)
-
root@manu:/usr/local/src/pgsrc/postgresql-9.2.3/src# cscope -Rbq
- root@manu:/usr/local/src/pgsrc/postgresql-9.2.3/src# ll
- .....
-
-rw-r--r-- 1 root root 2138112 3月 30 23:35 cscope.in.out-rw-r--r-- 1 root root 19451512 3月 30 23:35 cscope.out-rw-r--r-- 1 root root 14147844 3月 30 23:35 cscope.po.out
- .....
这种方法为带来问题(也可能是我功底比较浅),会带来什么问题呢?
讲这个之前,我们先学习下cscope的应用指令:在vim命令行下执行:cs help
讲这个之前,我们先学习下cscope的应用指令:在vim命令行下执行:cs help

cs show是显示当前可用的数据库,cs add是添加一个数据库。我们看下
-
root@manu:/usr/local/src/pgsrc/postgresql-9.2.3/src# cd backend/storage/file/
- root@manu:/usr/local/src/pgsrc/postgresql-9.2.3/src/backend/storage/file# vi fd.c
我们执行添加cscope 测试数据库的操作,在vim的命令行模式执行
- :cs add /usr/local/src/pgsrc/postgresql-9.2.3/src/cscope.out
- :cs show
可以看到如下db连接:

目前还正常,当我们使用:cs find 去查找函数调用的关系的时候:比如我读到closeAllVfds 函数实现的时候,我关心谁调用了fd.c中的closeAllVfds这个function。:cs find c 是干这个活的,请看上面的help。

结果是没找到。

我们不是已经添加了数据库了吗,为啥没找到了呢。原因就是我们生成cscope.out的时候,路径都是相对的路径。对于大工程我们怎么用cscope做到文件间的函数跳转呢?
下面介绍官方文档推荐的方法:Using Cscope on large projects (example: the Linux kernel),英文好的筒子可以直接去看原文,不用听我罗嗦。
1 建立cscope目录,我在自己的家目录下专门存放cscope数据库的目录:
1 建立cscope目录,我在自己的家目录下专门存放cscope数据库的目录:
-
root@manu:~/cscope# ll总用量 16drwxr-xr-x 2 root root 4096 3月 31 00:49 ./drwxr-xr-x 72 manu manu 12288 3月 31 00:48 ../
2 创建一个脚本来做建立cscope数据库的事情
-
root@manu:~/cscope# cat /usr/bin/makecscope.sh
-
#!/bin/sh
-
-
usage()
-
{
-
echo "usage : makecscope src_path project_name"
-
echo "I will create cscope db in ~/cscope/project_name"
-
}
-
if [ $# -ne 2 ]
-
then
-
usage
-
exit
-
fi
-
-
SRC_PATH=$1
-
CSCOPE_PATH=/home/manu/cscope/$2
-
-
mkdir -p $CSCOPE_PATH
-
cd $CSCOPE_PATH
-
find $SRC_PATH -name "*.h" -o -name "*.c" -o -name "Makefile" -o -name "makefile" > cscope.files
- cscope -bkq -i ./cscope.files
我们建立了一个sh脚本来干这个事情,sh脚本会接受两个参数
- 源码路径:脚本会搜索源代码路径下的所有.c .h Makefile makefile文件
- 项目的名称:脚本会在~/cscope目录下建立以第二个参数为名的目录,同时将生成的cscope数据库放入 该目录下
我们将这个makecscope.sh脚本放入/usr/bin/目录下,就可以在任意路径下执行这个脚本了
3 为任意项目创建cscope数据库,我们还是以PostgreSQL为例:
- root@manu:~/cscope# makecscope.sh /usr/local/src/pgsrc/postgresql-9.2.3/src/ postgres
我为路径为 /usr/local/src/pgsrc/postgresql-9.2.3/src/下的所有C文件 头文件和Makefile文件创建了cscope数据库,并将数据库放在了~/cscope/postgres路径下。
-
root@manu:~/cscope# cd postgres/
-
root@manu:~/cscope/postgres# ll
-
总用量 31532
-
drwxr-xr-x 2 root root 4096 3月 31 00:54 ./
-
drwxr-xr-x 3 root root 4096 3月 31 00:54 ../
-
-rw-r--r-- 1 root root 117338 3月 31 00:54 cscope.files
-
-rw-r--r-- 1 root root 1499136 3月 31 00:54 cscope.in.out
-
-rw-r--r-- 1 root root 17656981 3月 31 00:54 cscope.out
-
-rw-r--r-- 1 root root 13006272 3月 31 00:54 cscope.po.out
- root@manu:~/cscope/postgres#
创建好了数据库,我们看工程代码的时候,就可以添加这个cscope数据库了,然后就可以查看函数调用关系了。
=====================================================================================
这个问题解决了,我们还有一个问题是敲 :cs find c closeAllVfds这太不人性了,函数名很长的情况下,要人命。快捷键映射就很重要了。看下我的.vimrc里面的快捷键映射。(关心.vimrc 的筒子可以CU的草根老师博客下载那个vimrc的安装包,文章路径在此:配置自己的vim)
这个问题解决了,我们还有一个问题是敲 :cs find c closeAllVfds这太不人性了,函数名很长的情况下,要人命。快捷键映射就很重要了。看下我的.vimrc里面的快捷键映射。(关心.vimrc 的筒子可以CU的草根老师博客下载那个vimrc的安装包,文章路径在此:配置自己的vim)
-
nmap <leader>sa :cs add cscope.out<cr>
-
nmap <leader>ss :cs find s <C-R>=expand("")<cr><cr>
-
nmap <leader>sg :cs find g <C-R>=expand("")<cr><cr>
-
nmap <leader>sc :cs find c <C-R>=expand("")<cr><cr>
-
nmap <leader>st :cs find t <C-R>=expand("")<cr><cr>
-
nmap <leader>se :cs find e <C-R>=expand("")<cr><cr>
-
nmap <leader>sf :cs find f <C-R>=expand("")<cr><cr>
-
nmap <leader>si :cs find i <C-R>=expand("")<cr><cr>
- nmap <leader>sd :cs find d <C-R>=expand("")<cr><cr>
nmap表示在vim的普通模式下映射,当然相对与编辑模式和可视模式而言的,我们不多说。
=expand("cword")总体是为了得到:光标下的变量或函数。cword 表示:cursor word, 类似的还有:cfile表示光标所在处的文件名。
这个键在我的vim中对应的是逗号, 所以,上面的意思就 只要光标在我们关心的变量或者函数下,命令行模式敲,sc就相当与执行:cs find c 光标处函数名,注意,只需,sc三个键,不要敲冒号: 其他的键的映射也是类似的。
=expand("cword")总体是为了得到:光标下的变量或函数。cword 表示:cursor word, 类似的还有:cfile表示光标所在处的文件名。
这个键在我的vim中对应的是逗号, 所以,上面的意思就 只要光标在我们关心的变量或者函数下,命令行模式敲,sc就相当与执行:cs find c 光标处函数名,注意,只需,sc三个键,不要敲冒号: 其他的键的映射也是类似的。
有了这个快捷键,我们使用cscope的效率就提升了,加上ctrl+],ctrl+o,ctrl+t 我们看项目代码基本就比较舒服了。
有网友bottles在我的博文vim格式化C代码中问到:
对于这个问题,答案是肯定的,我们只需要执行:cs find f filename,就可以跳转到名字为filename的文件中去,注意不需要是全路径名。比如我可以从/usr/local/src/pgsrc/postgresql-9.2.3/src/backend/storage/file/fd.c文件中,在命令行模式下敲
就会跳转到/usr/local/src/pgsrc/postgresql-9.2.3/src/backend/postmaster/bgwriter.c。尽管他们不在同一路径下。
对于头文件的跳转,比如fd.c中有如下头文件:
我们只要将光标置于miscadmin.h处,执行快捷键,sf三个键,就能跳转到miscadmin.h头文件处。只需要三个键,跳转的特别快。
我的博文vim格式化C代码中,当时没有考虑到makefile,因为makefile的tab键不能展开为4个空格,这次一并在博文中修复了,对makefile做了特殊处理。
有网友bottles在我的博文vim格式化C代码中问到:
- 这个插件在不同文件当中都能跳转到定义吗?还有某些文件我想直接输入文件名不输入路径就open这个文件,这个功能用您说的插件能实现吗?我之前就是因为不能跳转到定义才用source insight里去的。
- :cs find f bgwriter.c
对于头文件的跳转,比如fd.c中有如下头文件:
- #include "miscadmin.h"
我的博文vim格式化C代码中,当时没有考虑到makefile,因为makefile的tab键不能展开为4个空格,这次一并在博文中修复了,对makefile做了特殊处理。
参考文献:
相关热门文章
给主人留下些什么吧!~~
评论热议
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通