我主要使用vim/gvim作为编辑器,正在考虑结合Linux Cross Reference (lxr)和cscope或ctags来探索内核源代码。然而,我从未使用过cscope或ctags,希望了解为什么可能会选择其中一个,考虑到我将vim作为主要编辑器使用。
ctags有两个功能: 可以跳转到函数调用的定义,并且支持omni completion。第一个意味着当您在方法调用上时,按下g]
或CTRL-]
将跳转到该方法被定义或实现的位置。第二个特性意味着当您输入foo.
或foo->
,并且foo是一个结构体时,将显示一个带有字段完成的弹出菜单。
cscope也具备第一个特性 - 使用 set cscopetag
- 但不具备最后一个特性。然而,cscope还增加了跳转到任何调用函数的地方的能力。
因此,就代码库中的跳转而言,ctags只会将您引导到函数的实现位置,而cscope还可以显示函数被调用的位置。
为什么会选择其中之一? 好吧,我两个都使用。 ctags更易于设置,运行速度更快,如果您只关心单向跳转,它将显示更少的行。您只需运行 :!ctags -R .
,然后键入g]
即可使用。它还启用了那个omni complete的功能。
Cscope非常适合大型、未知的代码库。安装过程比较麻烦,因为cscope需要包含要解析的文件名称列表的文件。而且在vim中,默认情况下没有设置键绑定 - 您需要手动运行:cscope blah blah
命令。
为了解决第一个问题,我有一个bash脚本cscope_gen.sh
,它看起来像这样:
#!/bin/sh
find . -name '*.py' \
-o -name '*.java' \
-o -iname '*.[CH]' \
-o -name '*.cpp' \
-o -name '*.cc' \
-o -name '*.hpp' \
> cscope.files
# -b: just build
# -q: create inverted index
cscope -b -q
这段代码用于搜索我感兴趣的代码,创建列表并生成数据库。这样,我就可以运行“:!cscope_gen.sh”而不必记住所有设置步骤。
我使用以下片段将搜索映射到x 2,以缓解的另一个问题:
nmap <C-@><C-@> :cs find s <C-R>=expand("<cword>")<CR><CR>
有一个cscope_maps.vim插件,可以设置一系列相似的绑定键。我经常忘记所有选项的含义,所以倾向于使用ctrl-space。
总之:ctags更容易设置,而且大多数情况下无需做其他工作即可正常工作,它对于omni-complete也是至关重要的。如果您需要维护一个大型且大部分未知的代码库,则cscope提供了更多功能,但需要更多的劳动力。
几个月前我处于同样的情况...
ctags的不精确性令人头疼,而在处理所有与宏相关的事情方面,我发现cscope要好得多(在Linux内核中有大量的宏)。
关于使用方法,实际上很简单......只需在内核根目录下键入cscope -R,然后你就没什么可担心的了。(我是说如果你只是想探索一下那是完美的...)
然后,所有的按键都基于Ctrl-\ (如果你对Ctrl过敏,可以重新映射),主要使用s和g....
在为内核开发时,我并不需要太多的自动补全功能。
总之,选择cscope会更加方便、准确。
嗯... 你应该使用 etags 而不是 ctags...
如果你使用 cscope,那么你可以看到调用链,也就是谁调用了这个函数以及这个函数调用了哪些函数?
我不确定这是否可以使用 etags/ctags 实现...
这只是其中一个功能... 那么,如何找出包含特定函数定义的文件呢?只有 cscope 才能实现。
我同时使用 cscope 和 etags,它们在不同的方面都很好,尤其是在处理大型代码库(例如Linux Kernel)时。事实上,当我开始工作于 Linux Kernel / Xen 时,我开始使用 cscope 和 etags。
LXR 不太好,因为你必须点击,经过网络等等,而你可以在你的内核代码上构建 cscope 和 tags 数据库,不必像 LXR 一样经过网络访问。
make tags
,并且一直在尝试跳转,但大多数情况下都跳到了错误的位置。我读到过ctags在处理c预处理器方面存在问题,但考虑到lxr中使用了ctags,显然还是有一些解决方法的。 - Robert S. Barnescscopetag
(cst
)设置为使:tag
和CTRL-]
命令首先通过cscope搜索,然后再搜索tags。 - Hasturkung C-]
,vim将显示与名称匹配的标签列表。您仍需要手动查找所需的正确定义。 - Hubert Kario