Chinaunix首页 | 论坛 | 博客
  • 博客访问: 219186
  • 博文数量: 30
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 272
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-11 13:39
个人简介

天行健,君子以自强不息;地势坤,君子以厚德载物;

文章分类

全部博文(30)

文章存档

2017年(7)

2016年(3)

2015年(6)

2013年(14)

我的朋友

分类: LINUX

2013-09-12 20:28:54

        在浏览LDD3的例程源码时经常碰到内核接口,就想查询接口定义和实现,甚至查看此接口被使用的地方,因此需要用CSCOPE为Linux内核建立索引,然后在VIM中使用索引。刚刚接触CSCOPE的新手,一般都会按以下步骤操作来建立索引:
        首先, 进入到工程源码顶层目录(本例:进入到Linux源码目录),在命令行中输入: cscope -Rbq;然后等待这个过程完成;
        其次, 进入到LDD3例程源码目录,打开源码文件,并添加刚才生成的cscope.out文件;
        最后, 将光标定位到某个内核接口上,按快捷键查找此接口被使用的地方,VIM会列出一个列表展示了此接口使用的地方,当选择一个查看时VIM打开了文件,但是发现里面是空的;y而且发现列表中的文件路径一般为:../xx/yy.c等等; 或者查找此接口定义时,VIM可能提示错误:File ../xx/yy.h不存在;
        究其原因为使用命令: cscope -Rbq 建立的cscope索引时基于相对路径,即使索引建立了并且能查询到,但是跳向文件使用的是相对路径,而那个路径文件很有可能是不存在的,从而导致无法显示或者提示错误。因此在工程A(本例:LDD3例程)里面使用工程B(Linux内核)的索引文件时,就会出现此种现象。
        碰到此现象还存在一个模式: 当在工程A顶层目录建立CSCOPE索引时,然后进入到其某个子目录下打开源码文件,再引用顶层目录的cscope.out文件。此时使用cscope查找对象时,也会出现上面的现象。
        要解决以上问题的根本方法在于: 让cscope建立索引文件时使用绝对路径,而非相对路径。在cscope官方有篇文章“”,里面关于cscope.out生成的方法可以解决此问题,即使用cscope.files中的文件列表来生成cscope.out。我们可以将cscope.files里面的文件全部用绝对路径表示:利用find命令查找将要建立索引的文件(*.h *.c *.cpp和*.cc),并将其添加到cscope.files中,然后执行cscope -bqk即可得到cscope.out。
        为方便使用,写了个脚本生成绝对路径的cscope索引。水平有限,脚本写的简陋,此脚本需要两个参数:工程名,工程绝对路径,
        例如: ./gen_cscope_files.sh linux-kernel ~/rpmbuild/BUILD/kernel-2.6.35.fc14/linux-2.6.35.i686/
        使用后,会在当前目录下建立一个与工程名相同目录,并将生成好的cscope索引文件放入其中。打开VIM后,添加此目录下的cscope.out文件,即可实现任意目录下查找引用。当然了,也可以在.vimrc中配置此索引文件始终加载。

        为方便以后统一管理各个工程cscope文件,可以建一个统一的目录,并将脚本文件放入到此目录下,每次在此目录下运行脚本文件。例如,在个人目录下建立一个cscope的目录,然后将脚本文件放入此目录下。若按上面调用脚本,则会在cscope目录下生成linux-kernel目录,并且在linux-kernel中包含Linux内核的cscope的文件。继续运行脚本: ./gen_cscope_files.sh ldd3 /mnt/hgfs/share/ldd3, 则会在cscope目录下升级ldd3目录,并且在ldd3中包括ldd3例程的cscope文件。

        现在符合要求的索引建立完成了,但是每次打开VIM都去手动加载cscope.out文件是比较烦琐的事情。因此我们可以在.vimrc中添加代码,使其自带加载,如下:

点击(此处)折叠或打开

  1. if filereadable(expand("$HOME/cscope/ldd3/cscope.out"))
  2. cscope add ~/cscope/ldd3/cscope.out
  3. endif
  4. if filereadable(expand("$HOME/cscope/linux-kernel/cscope.out"))
  5. cscope add ~/cscope/linux-kernel/cscope.out
  6. endif
        利用此种模块生成有一点不足:如果代码处于稳定状态,基本不用变化,这是比较方便浏览;但是如果在子目录下某个模块处于编辑状态,代码经常需要变动,其cscope可能需要经常变动,而此种模式在顶层将所有子目录的cscope重新建立,当工程具体大时,将是一个耗时的工作。
        有个变通的方法是将处于编辑状态的模块源码,先不放入工程主目录。在合入工程主目录前,建立本地的cscope文件来使用,等待模块稳定后再合入主工程目录,并重新建立cscope索引。更理想的方法是:工程目录内的每个目录都有一个cscope.out文件,每个目录仅仅是改动自己的cscope.out文件。不过如果这么安排cscope.out的布局,自动加载工程所有的cscope.out会不会比较慢??
        下面附上cscope.out文件生成的脚本源码:

点击(此处)折叠或打开

  1. # generate cscope.* files for projects corss-ref
  2. #!/bin/bash
  3. help_usage() {
  4. echo "gen_cscope_files.sh project_name absolute_path_of_the_project"
  5. }
  6. # check number of parameters, accepts only two
  7. if [ $# -ne 2 ] ; then
  8. echo "Please input two parameters"
  9. help_usage
  10. exit 1
  11. fi
  12. # check if parameter 2 is absolute path of the project
  13. if [ ${2:0:1} != '/' ] ; then
  14. if [ ${2:0:1} != '~' ] ; then
  15. echo "Please input absolute path of the project"
  16. help_usage
  17. exit 1
  18. fi
  19. fi
  20. # check if cscope installed
  21. #APP_cscope=`rpm -qa | grep cscope`
  22. #if [ -z ${APP_cscope} ]; then
  23. # echo "cscope not found, please install the cscope program!"
  24. # exit 1
  25. #fi
  26. # check if project directory exist
  27. if [ ! -d ${1} ] ; then
  28. # if not exist, create it
  29. mkdir ${1}
  30. else
  31. # or existed, ask user to override it ?
  32. echo "${1} has existed, do you want to override it?[yes/no]"
  33. read answer
  34. if [ ${answer} == "yes" ]; then
  35. echo "clear old cscope files of the project ..."
  36. rm -rf ${1}/cscope.*
  37. else
  38. echo "Task canceled"
  39. exit 1
  40. fi
  41. fi
  42. #generate cscope.files for cscope
  43. cd ${1}
  44. echo "genrate cscope.files from ${2} ..."
  45. find ${2} -name "*.h" -o -name "*.c" -o -name "*.cc" -o -name "*.cpp" > cscope.files
  46. #call cscope to generate cscope.out from cscope.files
  47. echo "genrate cscope.out form cscope.files ..."
  48. cscope -bkq -i cscope.files
  49. #list the files generated
  50. echo "Task done, list the files generated"
  51. ls -l
阅读(2866) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~