cscope或ctags,为什么要在两者中选择一个?

146

我主要使用vim/gvim作为编辑器,正在考虑结合Linux Cross Reference (lxr)cscopectags来探索内核源代码。然而,我从未使用过cscopectags,希望了解为什么可能会选择其中一个,考虑到我将vim作为主要编辑器使用。

4个回答

176

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提供了更多功能,但需要更多的劳动力。


2
有没有办法让ctags更准确一些?我在内核根目录下执行了make tags,并且一直在尝试跳转,但大多数情况下都跳到了错误的位置。我读到过ctags在处理c预处理器方面存在问题,但考虑到lxr中使用了ctags,显然还是有一些解决方法的。 - Robert S. Barnes
2
如果存在深层宏魔法,那么ctags可能会失败 :-( 我主要用它来处理C++的东西,这方面依赖较少(尽管也有自己的问题...) - richq
12
cscopetagcst)设置为使:tagCTRL-]命令首先通过cscope搜索,然后再搜索tags。 - Hasturkun
1
另外,ctags 在递归搜索方面相当慢,使用“ctags -L cscope.files”将显著加快您的标记生成速度。 - Aaron H.
1
@RobertS.Barnes,一种解决方案是使用g C-],vim将显示与名称匹配的标签列表。您仍需要手动查找所需的正确定义。 - Hubert Kario
显示剩余5条评论

17

几个月前我处于同样的情况...

ctags的不精确性令人头疼,而在处理所有与宏相关的事情方面,我发现cscope要好得多(在Linux内核中有大量的宏)。

关于使用方法,实际上很简单......只需在内核根目录下键入cscope -R,然后你就没什么可担心的了。(我是说如果你只是想探索一下那是完美的...)

然后,所有的按键都基于Ctrl-\ (如果你对Ctrl过敏,可以重新映射),主要使用s和g....

在为内核开发时,我并不需要太多的自动补全功能。

总之,选择cscope会更加方便、准确。


5
您只需在内核根目录下键入"cscope -R"。最好在内核下键入"make cscope",否则您将获得Linux内核中存在的所有架构,并因此导致相同C符号的多重定义。 - kumar
1
“cscope”比“exuberant-ctags”更精确吗?我听说后者是改进版的“ctags”... - 71GA

4

嗯... 你应该使用 etags 而不是 ctags...

如果你使用 cscope,那么你可以看到调用链,也就是谁调用了这个函数以及这个函数调用了哪些函数?

我不确定这是否可以使用 etags/ctags 实现...

这只是其中一个功能... 那么,如何找出包含特定函数定义的文件呢?只有 cscope 才能实现。

我同时使用 cscope 和 etags,它们在不同的方面都很好,尤其是在处理大型代码库(例如Linux Kernel)时。事实上,当我开始工作于 Linux Kernel / Xen 时,我开始使用 cscope 和 etags。

LXR 不太好,因为你必须点击,经过网络等等,而你可以在你的内核代码上构建 cscope 和 tags 数据库,不必像 LXR 一样经过网络访问。


难道etags只适用于emacs吗?我只使用g/vim。 - Robert S. Barnes
是的,你说得对。来自man手册:etags程序用于创建一个标签表文件,格式被emacs(1)所理解;ctags程序用于创建一个类似的表格,格式被vi(1)所理解。 - rmk
1
我相信有两种etags和ctags。一种是emacs的,另一种是exuberant ctags的。第一种最初是为emacs编写的,但也可以用于vi;第二种最初是为vi编写的,但也可以用于emacs。尽管我是一个emacs用户,但我发现第二个(exuberant ctags)更容易使用。如果您安装了exuberant-ctags软件包,则etags / ctags二进制文件的链接将更改,并指向不同的二进制文件。 - ustun

1

建议使用全局gtags。可以使用vim插件gen_tags将gtags与vim集成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接