cc++ ctags cscope

    技术2022-06-29  66

    c/c++ ctags cscope

     

    支持c++, 第一种ctags + ctags 第二种ctags

    1

    $ find . -name "*.h" -o -name "*.c" -o -name "*.cc" –o –name "*.cpp" > cscope.files

    (EXPR1-o EXPR2: -o表示“或(or)”, 查找所有后缀为“*.h", "*.c", ....文件。 find 后的路径最好为绝对路径,eg: find ~/project ****, 因若在生成cscope.out的子目录下用vim打开原文件并添加数据库cs add ../cscope.out后,末行命令cs find s *** 可能由于相对路径问题找不到。因此可将上面的命令中路径用命令代换方式:

    $ find `pwd` -name "*.h" -o -name "*.c" -o -name "*.cc" –o –name "*.cpp" > cscope.files

    )

     

        $ cscope -bkq -i cscope.files

    $ ctags –R

     

    ctags生成tags目录的子目录中,用vim打开原文件时,若要用tags相关命令查找,需先加入tags所在路径,末行命令下:set tags=../tags (注意 settags中间有空格)

     

    2ctagsc++生成tags:

    ctags -R --kinds-c++=+p --fields=+iaS --extra=+q

     

    每个参数解释如下:

    -R:ctags循环生成子目录的tags

    --c++-kinds=+px :ctags记录c++文件中的函数声明和各种外部和前向声明

    --fields=+iaS :ctags要求描述的信息,其中i表示如果有继承,则标识出父类;a表示如果元素是类成员的话,要标明其调用权限(即是public还是private);S表示如果是函数,则标识函数的signature

    --extra=+q:强制要求ctags做如下操作如果某个语法元素是类的一个成员,ctags默认会给其记录一行,可以要求ctags对同一个语法元斯屹记一行,这样可以保证在VIM中多个同名函数可以通过路径不同来区分。

     

    参考文章:

     

    1vim + cscope/ctags 查看分析代码

     

     

    使用vim + cscope/ctags,就能够实现Source Insight的功能,可以很方便地查看分析源代码。

     

     

    关键词: vim, cscope, ctags, tags

     

     

    1. 查看vim是否支持cscope

        $ vim --version | grep cscope

     

     

    2. 编译支持cscope VIM(--enable-cscope)

        # USE="bash-completion cscope nls perl python -acl -gpm -minimal -ruby -vim-pager -vim-with-x" emerge vim

        # emerge -av dev-util/cscope

        # emerge -av dev-util/ctags

        $ which cscope

        $ which ctags

     

     

    3. 查看帮助

        $ man cscope

        $ man ctags

        :help cscope (vim command)

        参考[1]  http://vimcdoc.sourceforge.net/doc/if_cscop.html

     

     

    4. 使用cscope[2]

        当前目录有main.c,其中调用了cstest.c中的print(),此函数在cstest.h中进行了声明。

        使用下面的命令生成代码的符号索引文件:

        $ cscope -Rbkq

        这个命令会生成三个文件:cscope.out, cscope.in.out, cscope.po.out

     

        其中cscope.out是基本的符号索引,后两个文件是使用"-q"选项生成的,可以加快cscope的索引速度。上面命令的参数含义如下:

        -R: 在生成索引文件时,搜索子目录树中的代码

        -b: 只生成索引文件,不进入cscope的界面

        -k: 在生成索引文件时,不搜索/usr/include目录

        -q: 生成cscope.in.outcscope.po.out文件,加快cscope的索引速度

        -i: 如果保存文件列表的文件名不是cscope.files时,需要加此选项告诉cscope到哪儿去找源文件列表。可以使用"-",表示由标准输入获得文件列表。

        -I dir: -I选项指出的目录中查找头文件

        -u: 扫描所有文件,重新生成交叉索引文件

        -C: 在搜索时忽略大小写

        -P path: 在以相对路径表示的文件前加上的path,这样,你不用切换到你数据库文件所在的目录也可以使用它了。

       

     

        在缺省情况下,cscope在生成数据库后就会进入它自己的查询界面,一般不用这个界面,所以使用了"-b"选项。如果已经进入了这个界面,按CTRL-D退出。

     

        接下来可以在vim里浏览代码了

        $ vim main.c

        vim里命令状态下添加符号索引库

        : cscope add cscope.out

        然后可以查看相应的函数定义或文件,ctrl+t返回。

        : cscope find g print

        : cscope find f cstest.h

       

        # 注意# 所生成的cscope.outtags文件要在打开VIM所在的文件夹,否则VIM无法找到相关符号信息。

     

     

    5. 创建相应的快捷键

        将以下内容添加到~/.vimrc中,vim会自动加载当前目录下的符号索引cscope.out,可以使用ctrl+tctrl+]等。

     

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

    " cscope setting

     

    if has("cscope")

       set csprg=/usr/bin/cscope              "指定用来执行 cscope 的命令

       set csto=1                             "先搜索tags标签文件,再搜索cscope数据库

       set cst                                "使用|:cstag|(:cs find g),而不是缺省的:tag

       set nocsverb                           "不显示添加数据库是否成功

       " add any database in current directory

       if filereadable("cscope.out")

          cs add cscope.out                   "添加cscope数据库

       endif

       set csverb                             "显示添加成功与否

    endif

     

    nmap <C-@>s :cs find s <C-R>=expand("<cword>")<CR><CR>

    nmap <C-@>g :cs find g <C-R>=expand("<cword>")<CR><CR>

    nmap <C-@>c :cs find c <C-R>=expand("<cword>")<CR><CR>

    nmap <C-@>t :cs find t <C-R>=expand("<cword>")<CR><CR>

    nmap <C-@>e :cs find e <C-R>=expand("<cword>")<CR><CR>

    nmap <C-@>f :cs find f <C-R>=expand("<cfile>")<CR><CR>

    nmap <C-@>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>

    nmap <C-@>d :cs find d <C-R>=expand("<cword>")<CR><CR>

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

     

        其中<C-@>g是先同时按ctrl+@键,之后再按一个g。功能就是查看当前光标所在符号的定义。

     

     

    6. vim阅读代码

        添加cscope符号索引数据库后,可以调用"cscope find"命令进行查找,vim支持8 cscope的查询功能。如在代码中查找调用work()函数的函数,可以在vim命令状态下输入":cs find c work",回车即可。还可以进行字符串查找,它会对双引号或单引号括起来的内容查找。还可以输入一个正则表达式,这类似于egrep程序的功能。

        :cs help (vim command下查询)

     

        s: 查找C语言符号,即查找函数名、宏、枚举值等出现的地方

        g: 查找函数、宏、枚举等定义的位置,类似ctags所提供的功能

        d: 查找本函数调用的函数

        c: 查找调用本函数的函数

        t: 查找指定的字符串

        e: 查找egrep模式,相当于egrep 功能,但查找速度快多了

        f: 查找并打开文件,类似vim find功能

        i: 查找包含本文件的文件

     

     

    7. 查看阅读c++代码[3]

        cscope 缺省只解析C文件(.c.h)lex文件(.l)yacc文件(.y),虽然它也可以支持C++以及Java,但它在扫描目录时会跳过C++ Java后缀的文件。如果希望cscope解析C++Java文件,需要把这些文件的名字和路径保存在一个名为cscope.files的文件。当 cscope发现在当前目录中存在cscope.files时,就会为cscope.files中列出的所有文件生成索引数据库。

        下面的命令会查找当前目录及子目录中所有后缀名为".h", ".c", "cc"".cpp"的文件,并把查找结果重定向到文件cscope.files中。然后cscope根据 cscope.files中的所有文件,生成符号索引文件。最后一条命令使用ctags命令,生成一个tags文件,在vim中执行":help tags"命令查询它的用法。它可以和cscope一起使用。

     

        $ find . -name "*.h" -o -name "*.c" -o -name "*.cc" -o "*.cpp" > cscope.files

        $ cscope -bkq -i cscope.files

        $ ctags -R

     

     

    8. vim中使用tags查找符号

     

        查看ctags帮助

        $ man ctags

        :help ctags  (vim command)

        :help tags   (vim command)

       

        在源代码根目录下执行 ctags -R 命令用来为程序源代码生成标签文件,其-R选项表示递归操作,同时为子目录也生成标签文件。vim利用生成的标签文件,可以进行相应检索、并在不同的文件 C语言元素之间来回切换。

        $ ctags -R

     

        A) vim 中使用":tag xxx"跳到函数或数据结构xxx处。使用tag命令时,可以使用TAB 键进行匹配查找,继续按TAB键向下切换。

        某个函数有多个定义时

        :tag

        跳到第一个定义处,优先跳转到当前文件

        :tnext

        跳到第一个

        :tfirst

        跳到前count

        :[count]tprevious

        跳到后count

        :[count]tnext

        跳到最后一个

        :tlast

        你也可以在所有 tagname中选择:

        :tselect tagname

        如果想跳到包含block的标识符":tag /block" 然后用TAB键来选择。这里'/'就是告诉vim 'block'是一个语句块标签。

     

        B) "ctrl+]"快捷键,跳转到光标所在函数标识符的定义处。

     

        C) 使用"ctrl+t"退回上层。 如果想在以write_开头的标识符中选择一下, :tselect /^write_ 这里,'^'表示开头,同理,'$'表示末尾。

     

        D) 运行vim的时候,必须在"tags"文件所在的目录下运行。否则,运行vim的时候还要用":set tags=xxx"命令设定"tags"文件的路径,这样vim才能找到"tags"文件(这儿我们已经设置过了"set tags=tags;",在子目录中也可以使用)。

     

        E) 在函数中移动光标的快捷键:

        [{ 转到上一个位于第一列的"{"

        }] 转到下一个位于第一列的"{"

        { 转到上一个空行

        } 转到下一个空行

        gd 转到当前光标所指的局部变量的定义

        * 转到当前光标所指的单词下一次出现的地方

        # 转到当前光标所指的单词上一次出现的地方

     

     

    9. taglist插件使用[4]

        该插件可以像Source Insight那样将当前文件中的宏、全局变量、函数等tag显示在Symbol窗口,用鼠标点上述tag,就跳到该tag定义的位置;可以按字母序、该 tag所属的类或scope,以及该tag在文件中出现的位置进行排序;如果切换到另外一个文件,Symbol窗口更新显示这个文件中的tag taglist依赖于ctags

     

        要使用taglist插件,必须满足:

        1).打开VIM的文件类型自动检测功能;

        2).系统中装了Exuberant ctags工具,并且taglist能够找到此工具(因为taglist需要调用它来生成tag文件);

        3).你的VIM支持system()调用;

     

        安装taglist 插件

        # emerge -av app-vim/taglist

     

        查看帮助

        :help helptags

        :help taglist

        :help taglist-intro

     

        打开 tag窗口

        :TlistToggle

     

        .vimrc中配置如下

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

    " ctags setting

    set tags=./tags,./../tags,./*/tags;

     

    " Tag list (ctags)

     

    filetype on                            "文件类型自动检测

     

    if MySys() == "windows"                "设定windows系统中ctags程序的位置

       let Tlist_Ctags_Cmd = 'ctags'

    elseif MySys() == "linux"              "设定linux系统中ctags程序的位置

       let Tlist_Ctags_Cmd = '/usr/bin/ctags'

    endif

     

    let Tlist_Show_One_File = 1            "不同时显示多个文件的 tag,只显示当前文件的

    let Tlist_Exit_OnlyWindow = 1          "如果taglist窗口是最后一个窗口,则退出vim

    let Tlist_Use_Right_Window = 1         "在右侧窗口中显示taglist窗口

     

    map <silent> <F8> :TlistToggle<cr>     "在映射F8键打开tags窗口

    """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

     

     

    10. 建立索引数据库、查看内核源码[5]

    liuby@liuby ~/git/kernel/linux-2.6.30.5 $ make cscope

      GEN     cscope

    liuby@liuby ~/git/kernel/linux-2.6.30.5 $ make tags

      GEN     tags

    liuby@liuby ~/git/kernel/linux-2.6.30.5 $ ls tags -l

    -rw-r--r-- 1 liuby liuby 89648962 03-12 06:12 tags

    liuby@liuby ~/git/kernel/linux-2.6.30.5 $ ls cscope.* -l -rw-r--r-- 1 liuby liuby    403901 03-12 06:02 cscope.files

    -rw-r--r-- 1 liuby liuby 182562815 03-12 06:04 cscope.out

    -rw-r--r-- 1 liuby liuby  23011328 03-12 06:04 cscope.out.in

    -rw-r--r-- 1 liuby liuby 133571208 03-12 06:04 cscope.out.po

     

    参考文献:

    [1] http://vimcdoc.sourceforge.net/doc/if_cscop.html

    [2] http://easwy.com/blog/archives/advanced-vim-skills-cscope/

    [3] http://easwy.com/blog/archives/vim-cscope-ctags/

    [4] http://easwy.com/blog/archives/advanced-vim-skills-taglist-plugin/

    [5] http://www.kongove.cn/web/doc/vim-ctags-cscope-source.html

     

     

     

    2         Vim中如何使用ctags?OK?C/C++

     

    如何在Vim中使用ctags?之前在《把Vim打造成真正的IDE》系列里已经讲过大致的ctagsvim中的使用,这篇文章我们就详细的讲一下。

    首先要明白,ctags是什么?

    官方的解释是:产生标记文件以帮助在源文件中定位对象。

    其生成的标记文件tags中包括这些对象的列表:

    #define定仪的宏枚举型变量的值函数的定仪、原型和声明名字空间(namespace类型定仪(typedefs变量(包括定仪和声明)类(class)、拮构(struct)、枚举类型(enum)和联合(union类、拮构和联合中成员变量或函数

    那么我们用怎样的参数来使ctags正常的生成我们需要的tags文件呢?在这里我们就不去挨个学习那些枯燥的参数了,直接参看 omnicppcomplete 提供的ctags生成语句:

    ctags-R--c++-kinds=+px--fields=+iaS--extra=+q .

    每个参数解释如下:

    -R:ctags循环生成子目录的tags

    --c++-kinds=+px :ctags记录c++文件中的函数声明和各种外部和前向声明

    --fields=+iaS :ctags要求描述的信息,其中i表示如果有继承,则标识出父类;a表示如果元素是类成员的话,要标明其调用权限(即是public还是private);S表示如果是函数,则标识函数的signature

    --extra=+q:强制要求ctags做如下操作如果某个语法元素是类的一个成员,ctags默认会给其记录一行,可以要求ctags对同一个语法元斯屹记一行,这样可以保证在VIM中多个同名函数可以通过路径不同来区分。

    OK,那么tags文件就生成好啦,利用这个文件我们可以做很多强大的事情,包括前面用过的插件omnicppcompletetaglistshowfunc之类的,都是依赖于它的。

    那么除了插件上的作用外,我们用户在vim里面怎么使用他呢?

    其实最简单的就是:把光标移动到某个元素上,CTRL+],就会跳转到对应的定仪啦。CTRL+o可以回退到原来的地方。

    还有一个操作经常被人忽略,就是,如果当前光标下是个局部变量,在VIM里输入gd的话,就会跳到这个局部变量的定仪处,也是非常方便滴~~

    另外,tags必须在vim运行的当前目录,才能在vim里面正确跳转,当然也不是没有办法解决:settags="tags的文件路径"即可,不过如果像我前面文章说的那样定仪了F12来快速生成tags的话(快速连接),也不会经常用到更改路径吧,哈哈。

    顺便说一句,tags生成路径最好不要包含中文哦

     

     


    最新回复(0)