最后结果和文件在
http://gist.github.com/zhuzhenpeng/5939304c8f298c82352b
GCC、Clang、llvm概念和关系
编译器分前端和后端
前端主要进行语法和语义分析,输入是源代码,输出是一棵抽象的语法树,平时大家说的parser就是指编译器的前端
后端主要优化中间代码和生成机器代码,输入是前端产出的语法树,输出是机器代码,Optimizer和Code generator 就是指后端
GCC既包含前前端和后端,clang是前端,llvm是后端。人们使用他们的组合是(前端 / 后端):
gcc / gcc
gcc / llvm
clang / llvm
clang / llvm是苹果公司在推动的。
clang提供了很强大的语义分析能力。
YouCompleteMe
老外写的一个很好用的代码补全工具,原理是利用C/S架构,编辑器作为客户端,后台反馈补全信息,而这些补全信息就是利用clang工具来获得的。
http://github.com/Valloric/YouCompleteMe
据说也可以用在emacs上,emacs本身就缺乏c++11的语法高亮,而补全工具目前除了rtags有涉及c++11其它好像都不尽人意,YCM应该十分不错(我没试)
http://github.com/Valloric/ycmd,这是服务端的项目
Vim安装和配置YCM
老外在github上说的安装步骤十分清楚了
在ubuntu下,我也是利用Vundle,在里面加一句 Plugin ‘Valloric/YouCompleteMe‘ 让它一直下(过程有点久,一直显示processing XXX)
直到undle提示我要编译,这时候去到目录下执行
./install.sh --clang-completer
就可以了
配置 .ycm_extra_conf.py 文件
这个文件的配置是我写这篇文章的主要目的。
官方给出的demo地址是 http://github.com/Valloric/ycmd/blob/master/cpp/ycm/.ycm_extra_conf.py
首先说下.ycm_extra_cong.py的作用,一般而言每个项目都需要有一个相应这个文件放在根目录,每当用vim打开项目的项目中的源代码时,ycmd服务器就会从源代码所在目录一直向上搜索直到找到这个.ycm_extra_cong.py文件,然后根据这个文件来获取这个源代码所需要的补全信息。
所以这份文件关键是告诉ycmd服务器用到的那些头文件的所在位置;比如如果是qt项目,就可以把相应的文件告诉ycmd,否则平时就不会进行qt代码的提示。
根据官方的说法,我们主要修改falgs就可以了。在falgs中,我们看到-I(大写i)和-isystem,根据gcc的man中的说法:
-I dir
Add the directory dir to the list of directories to be searched forheader files. Directories named by -I are searched before the standard system include directories.
-isystem dir
Search dir for header files, after all directories specified by -I but before the standard system directories.Mark it as a system directory, so that it gets the same special treatment as is applied to the standard system directories.
所以我们把自己项目中的头文件所在的文件夹放在-I 后面,而把c++的库的头文件、qt的库的头文件放在-isystem后面
在网上的一些教程中,有的说把默认配置文件写入.vimrc中
~/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py
至少现在看来是错的,目前这个YCM项目中的文件夹已经改变了不少,里面原本的文件夹已经变了位置甚至已经没有了
另一些教程中,很多人直接引用了这位老兄的配置文件
http://gist.github.com/locojay/4950253
有的人可能成功了但是不知所以然,有的人以为成功了但是实际没有(大部分情况下没有提示)
libc++-dev
实际上,我们需要c++的补充,最重要的是找齐c++的头文件所在的位置,并把它放在-isystem中
以我目前的机子为例,在ubuntu下,翻到/usr/include/c++/4.8/的目录下,看到有名为vector的文件,打开看到的内容是
。。。
#include <bits/stl_vector.h>
。。。
可以看到vector的声明是放在stl_vector.h文件中的,我尝试过把 /usr/include/c++/4.8/ 和它的全部子文件夹 添加到flags中但是没有效果,使用时显示没有vector的定义,我也不知道是不是因为名字的原因
后来我的解决方法是
sudo apt-get install libc++-dev
这个libc++-dev是新的基于11的对c++标准库的实现,是llvm c++ standard library development files
安装以后可以看到 /usr/include/c++/v1 文件夹放了全部的头文件,此时把它放入配置文件中就大功告成了,所有补全都有了提示。
可以把这个基本的只包含基本库的配置文件设为全局的,这样的话就不必再为临时编写c++文件而配置了:
let g:ycm_global_ycm_extra_conf = ‘your/path/to/.ycm_extra_cong.py‘
可以发现/usr/include/c++/v1 和网上的那个 /usr/lib/c++/v1 配置很像,但是如今头文件已经放在别处,我机子上是没有那个文件夹的。所以稍微理解下原理还是有必要的,以后只要找到