標籤:
最後結果和檔案在
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 配置很像,但是如今標頭檔已經放在別處,我機子上是沒有那個檔案夾的。所以稍微理解下原理還是有必要的,以後只要找到
Vim的YCM(YouCompleteMe)外掛程式配置