为libstdc++生成CTAGS(来自当前的GCC)

Generate CTAGS for libstdc++ (from current GCC)

本文关键字:GCC libstdc++ 生成 CTAGS      更新时间:2023-10-16

我知道YoucompleteMe基于LLVM,但我想使用OmniCppComplete。如果我在c++中使用修改后的头文件,效果会很好。修改后的头文件已经过时,不包含c++ 11中的任何内容。

如果注意到,我可以修改我自己的标题,例如:

$ find . -name '*.h' | xargs sed -i 's/__STL_BEGIN_NAMESPACE/namespace std {/'
$ find . -name '*.h' | xargs sed -i 's/__STL_END_NAMESPACE/}/'

或者使用以下设置:

let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]

两者都不起作用,当然大多数头文件没有和任何文件扩展名。我已经尝试过通过使用文件列表来解决这个问题。我如何在我当前的GCC(例如/usr/include/c++/…)的基础上创建工作CTAGS ?常见的方法是什么?

谢谢

这是我得到的,如果我尝试从LIBSTD++完成一些事情:

std::fs
Omni completion (^O^N^P) Back at original
Ctrl+x, Ctrl+o
Omni completion (^O^N^P) Pattern not found

最后,我绝望地给修改了libstdc++ (GCC)头文件的作者写了一封电子邮件。他很快回答了我(谢谢!):

要求:
安装vim和vim-omnicppcomplete和标签(vim-omnicppcomplete的依赖)。

解决方案:

$ cp -R /usr/include/c++/$GCC_VERSION ~/.vim/cpp_src
# it is not necessary to rename headers without an extension
# replace the "namespace std _GLIBCXX_VISIBILITY(default)" with "namespace std"
$ find . -type f | xargs sed -i 's/namespace std _GLIBCXX_VISIBILITY(default)/namespace std/'
$ ctags -f cpp_tags -R --c++-kinds=+p --fields=+iaS --extra=+q --language-force=C++ -I _GLIBCXX_NOEXCEPT cpp_src
编辑你的~/.vimrc:

" configure tags - add additional tags here or comment out not-used ones
set tags+=~/.vim/cpp_tags
" build tags of your own project with Ctrl-F12
map <C-F12> :!ctags -R --sort=yes --c++-kinds=+p --fields=+iaS --extra=+q -I _GLIBCXX_NOEXCEPT .<CR>
" OmniCppComplete
let OmniCpp_NamespaceSearch = 1
let OmniCpp_GlobalScopeSearch = 1
let OmniCpp_ShowAccess = 1
let OmniCpp_ShowPrototypeInAbbr = 1 " show function parameters
let OmniCpp_MayCompleteDot = 1 " autocomplete after .
let OmniCpp_MayCompleteArrow = 1 " autocomplete after ->
let OmniCpp_MayCompleteScope = 1 " autocomplete after ::
" also necessary for fixing LIBSTDC++ releated stuff
let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
" automatically open and close the popup menu / preview window
au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
set completeopt=menuone,menu,longest,preview

libstdc++的自动完成现在应该在vim中工作!
手动自动补全Ctrl+x -> Ctrl+o

如果你仍然对自动完成有问题,你可以在文档中找到解决方案(见FAQ 7)。

再见

在努力搜索如何使用标签创建c++特定的标签文件后,我终于取得了理想的进展。不得不说,ctags确实有点难用,但功能强大。

首先要强调的是,不要忽略标签提供的-I选项(更多选项信息见这里)。在标签文件中看到更多的符号是非常重要的。简单地说,标签不能处理一些不规则的语法语句,例如前缀或后缀为C/c++宏的语句。如果很多函数的前缀或后缀都是某种宏,那么ctags很可能会放弃它。最后,你在编码时看不到它们。

这是我用来从c++标准头路径中尽可能多地找到这样的宏的一种方法,例如/usr/include/c++/4.9.3,并将它们添加到-I选项。

find/usr/include/c++/-type f -exec grep '_GLIBCXX_' {} ;| grep - v - e " ^[#如果| #结束]"|排序- u> glibcxx.log

在该命令之后,您将发现c++ 4.9.3源文件中使用的几个宏,然后选择其中的一些以被标签忽略。

生成c++标签文件的最后一个命令是:

ctags -R——languages=c++——langmap=c++:+.tcc。——c++-kinds=+p——fields=+iaS——extra=+qf -I "_GLIBCXX_NOEXCEPT _GLIBCXX_USE_NOEXCEPT _GLIBCXX_NOTHROW _GLIBCXX_USE_CONSTEXPR _GLIBCXX_BEGIN_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_CONSTEXPR _GLIBCXX_NAMESPACE_LDBL _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_VISIBILITY+" -f cc-4.9.3。标签/usr/include/c + +/4.9.3/

警告

  1. 不要忘记在tcc后面写.符号,这意味着匹配那些没有明确扩展名的文件,如vector, set
  2. 不要忘记在VISIBILITY后面写+符号,它表示匹配std _GLIBCXX_VISIBILITY(**)
  3. 不要忘记在.tcc后面写+符号,这意味着将所表示的扩展附加到当前语言的地图上,否则替换地图

我实际上也使用OmniCppComplete,并且一直愉快地使用仅c++标记文件(在其他文件中)。有一段时间,我把标签文件分成更小的部分(如c++、boost、X11等)。下面是我在Ubuntu 14.04上生成标签文件的解决方案:

ctags -f cpp_tags --c-kinds=cdefgmstuv --c++-kinds=cdefgmstuv --fields=+iaSmKz --extra=+q --langmap=c++:+.tcc. --languages=c,c++ -I "_GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_END_NAMESPACE_VERSION _GLIBCXX_VISIBILITY+" -n $INC_DIR/* /usr/include/$CPP_TARGET/c++/$CPP_VERSION/bits/* /usr/include/$CPP_TARGET/c++/$CPP_VERSION/ext/* $INC_DIR/bits/* $INC_DIR/ext $SYSTEM/* $SYSTEM2/*

地点:

CPP_VERSION=4.8
INC_DIR=/usr/include/c++/$CPP_VERSION
CPP_TARGET=x86_64-linux-gnu
SYSTEM=/usr/lib/gcc/x86_64-linux-gnu/4.8/include
SYSTEM2=/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed

请注意,生成大多数标记的真正技巧是-I选项!它可能需要调整。当然,——c-kinds/c++-kinds和fields选项也可以调整。

最后一部分是添加:

tags+=cpp_tags

到你的.vimrc文件,以允许标签被看到。

所有这些都不需要修改头文件。如果您使用不同的c++库,则可能需要使用-I选项以使标记正确显示(甚至完全显示)。

现在我想起来了,我可能也应该在Vim Wiki上发布这些信息。

你关于let OmniCpp_DefaultNamespaces的第二部分可以改进。试试let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD", "_GLIBCXX_STD_A", "_GLIBCXX_STD_C"]。这就是我使用的,应该允许找到更多的项目。

最后,不要忘记使用Vim的CTRL-p来完成std::fs。它非常强大……并且不需要标签文件!

相关文章: