1. 程式人生 > >YouCompleteMe折騰配置以及clang+llvm編譯安裝

YouCompleteMe折騰配置以及clang+llvm編譯安裝

比較麻煩,未完待續。。。。。。

VIM

強調三個概念:

A buffer is the in-memory text of a file. 
A window is a viewport on a buffer.
A tab page is a collection of windows.

解釋:
1. vim 把載入進記憶體的檔案叫做 buffer,buffer 不一定可見;
2. 若要 buffer 要可見,則必須通過 window 作為載體呈現;
3. 同個看面上的多個 window 組合成一個 tab。
4. 一句話,vim 的 buffer、window、tab 你可以對應理解成視角、佈局、工作區。

現在業內一般不建議用 tab,因此這裡重點關注 buffer、window。

列出 增加 刪除 選擇/切換 退出 其他
buffer :ls
:buffers
:e :bd :bNum
:bn :bp :bl :bf
tab :tabs :tabe :tabc
:tabo
gt/gT
:tabp
:tabn
window C-w +
C-w -
C-w >
C-w <
:new
:vnew
:q :qa :wqa :only
C-w =
C-w q
C-w c
C-w o
C-w C-w
C-w h/j/k/l
file & dired :Ex :Sex
:He :Ve
:Te
其他操作 命令 命令 命令 命令 命令 命令
其他 u gu guu
U gU gUU
C-c fChar *
viw
C-o
C-i
:shell
exit

外掛:個人覺得以下幾乎是必需的外掛

外掛

  • vim-plug: 輕巧的外掛管理器
  • nerdtree: scrooloose/nerdtree 目錄結構瀏覽
  • YouCompleteMe: Valloric/YouCompleteMe 超級強大的自動補全,集成了具有語法檢查功能的syntactic
  • tagbar: majutsushi/tagbar 相當於eclipse的outline
  • ctrlp: kien/ctrlp.vim 全域性搜尋+狀態條
  • powerline: powerline/powerline
  • nerdcommenter:scrooloose/nerdcommenter
  • vim-expand-region:terryma/vim-expand-region
  • vim-surround:tpope/vim-surround
  • gtags : vim-scripts/gtags.vim 讓 vim 可以用 gnu-global ,gtags 要結合 gtags-cscope 一起使用
  • gtags-cscope : whatot/gtags-cscope.vim

外掛使用備忘

有些外掛用法容易忘記,記錄在這裡

nerdtree

NERDTree可以很方便地進行開啟檔案、查詢檔案等操作,但是刪除啊等等這些操作呢?見下圖

這裡寫圖片描述

nerdcommenter

註釋:SPC c c
取消:SPC c u

安裝YouCompleteMe

其他的外掛都很好裝,就是ycm不好裝。

按照步驟來,一定能成功的。

如果哪裡出錯了,仔細從頭地對照教程檢查;如果每一步真的都是按照步驟來,一定可以成功。

安裝Vundle

確保前提

Ensure that your version of Vim is at least 7.4.143 and that it has support for Python 2 or Python 3 scripting.

翻譯: 確保Vim版本至少為7.4.143,並且它支援Python 2或Python 3指令碼。

驗證:

  1. 在Vim中輸入 :version 可以檢視版本。

  2. After you have made sure that you have Vim 7.4.143+, type the following in Vim: echo has('python') || has('python3'). The output should be 1. If it’s 0, then get a version of Vim with Python support.

    翻譯: 確定Vim 7.4.143+後,在Vim中鍵入以下命令:echo has('python')|| has('python3'),輸出應為1;如果它為0,那麼去裝一個帶有Python支援的Vim版本。

安裝YouCompleteMe外掛

兩種方式安裝:

  1. Vundle安裝:Plugin 'Valloric/YouCompleteMe'

    如果用Vundle更新YCM,yum_support_lib庫API改變了,YCM會提醒你重新編譯它。

  2. git安裝:先用git clone --recursive https://github.com/Valloric/YouCompleteMe.git獲取最新的倉庫;而後使用git submodule update --init --recursive確認倉庫的完整性後,開始安裝流程

Download the latest version of libclang: 下載libclang(版本>=3.9)

翻譯: 下載最新版本的libclang(3.9以上版本)

下載地址:http://llvm.org/releases/download.html

官方建議下二進位制包:(別下錯了)

  • Clang for x86_64 Ubuntu 14.04 (.sig)
  • Clang for x86_64 Ubuntu 16.04 (.sig)
  • Clang for Mac OS X (.sig)

編譯安裝ycm_core庫之前戲

Compile the ycm_core library that YCM needs.
This library is the C++ engine that YCM uses to get fast completions.

翻譯: 編譯YCM需要的ycm_core庫。 這個庫是YCM用來獲得快速完成的C ++引擎。

編譯安裝ycm_core需要cmakepython-dev支援。

安裝cmake:

  • Ubuntu: sudo apt-get install cmake
  • Mac: brew install cmake

安裝python-dev:

  • Ubuntu: sudo apt-get install python-dev python3-dev
  • Mac: they should already be present(Mac下,它們是現成的,不需要額外裝)

Here we’ll assume you installed YCM with Vundle.
That means that the top-level YCM directory is in ~/.vim/bundle/YouCompleteMe.

翻譯: 現在我們假設你安裝YCM與Vundle。 這意味著頂層YCM目錄在中~/.vim/bundle/YouCompleteMe

正式編譯安裝ycm_core: Compile the ycm_core library that YCM needs. This library is the C++ engine that YCM uses to get fast completions.

We’ll create a new folder where build files will be placed. Run the following:

翻譯: 建立一個新資料夾,其中將放置構建檔案。 執行以下命令:

cd ~
mkdir ycm_build
cd ycm_build

下一步生成makefile,這一步很重要,有點複雜。

這一步作者的原英文介紹特別冗長,這裡總結了一下,列出來。作者的原文附在後面。

  1. 如果不需要C族語言的語義支援,在ycm_build目錄下執行: cmake -G "Unix Makefiles" . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
  2. 如果需要C族語言的語義支援,還得分幾種情況:

    1. 從llvm的官網下載了LLVM+Clang的二進位制包

      • 解壓到:~/ycm_temp/llvm_root_dir

        該目錄下有bin, lib, include等資料夾

      • 然後執行: cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp

    2. 如果想用系統的libclang: cmake -G "Unix Makefiles" -DUSE_SYSTEM_LIBCLANG=ON . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
    3. 如果想用自定義的libclang: cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp

      /path/to/libclang.so這部分填入你自己編譯libclang的路徑

至此,makefile已生成。

我自己是按照作者建議,從llvm網站下載的二進位制檔案,安裝的。

生成ycm_core

cmake --build . --target ycm_core --config Release

安裝完成

至此,YouCompleteMe已經算是安裝成功

注意:這時候,ycm_build目錄可以刪除啦!

安裝成功後,ycm_build以及ycm_temp目錄都可以刪除,不影響YouCompleteMe外掛的使用。

===================================================================================================

==================================================================================================

(可跳過)附錄:作者原文中主要步驟和關鍵點摘抄

Now we need to generate the makefiles. If you DON’T care about semantic support for C-family languages, run the following command in the ycm_build directory:

We’ll assume you downloaded a binary distribution of LLVM+Clang from llvm.org in step 3 and that you extracted the archive file to folder ~/ycm_temp/llvm_root_dir (with bin, lib, include etc. folders right inside that folder).

NOTE: This only works with a downloaded LLVM binary package, not a custom-built LLVM! See docs below for EXTERNAL_LIBCLANG_PATH when using a custom LLVM build.

With that in mind, run the following command in the ycm_build directory:

cmake -G "<generator>" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp, where is Unix Makefiles on Unix systems.

Now that configuration files have been generated, compile the libraries using this command: cmake --build . --target ycm_core --config Release

The --config Release part is specific to Windows and will be ignored on a Unix OS.

For those who want to use the system version of libclang, you would pass -DUSE_SYSTEM_LIBCLANG=ON to cmake instead of the -DPATH_TO_LLVM_ROOT=... flag.

注意作者這裡的NOTE提示:

NOTE: We STRONGLY recommend AGAINST use of the system libclang instead of the upstream compiled binaries. Random things may break. Save yourself the hassle and use the upstream pre-built libclang.

如果是custom libclang而不是downloaded LLVM binary package:

You could also force the use of a custom libclang library with -DEXTERNAL_LIBCLANG_PATH=/path/to/libclang.so flag (the library would end with .dylib on a Mac). Again, this flag would be used instead of the other flags.
If you compiled LLVM from source, this is the flag you should be using.

Running the cmake command will also place the libclang.[so|dylib|dll] in the YouCompleteMe/third_party/ycmd folder for you if you compiled with clang support (it needs to be there for YCM to work).

Don’t forget that if you want the C-family semantic completion engine to work,
you will need to provide the compilation flags for your project to YCM.

==================================================================================================

==================================================================================================

配置

  1. 前戲準備

        cp ~/.vim/bundle/YouCompleteMe/third_party/ycmd/examples/.ycm_extra_conf.py ~/  
        vim ~/.ycm_extra_conf.py
    
        /*
        ** 注:下面需要註釋的內容只有稍微老一點的版本才有,最新的是沒有的
        */
        // 如果有如下內容,註釋掉:
        try:  
          final_flags.remove( '-stdlib=libc++' )  
        except ValueError:  
          pass 
        // 註釋完後變成下面這樣
        #try:  
        #  final_flags.remove( '-stdlib=libc++' )  
        #except ValueError:  
        #  pass 
  2. .vimrc中的配置

    " #####YouCompleteMe Configure   
    let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'  
    " 自動補全配置  
    set completeopt=longest,menu    "讓Vim的補全選單行為與一般IDE一致(參考VimTip1228)  
    autocmd InsertLeave * if pumvisible() == 0|pclose|endif "離開插入模式後自動關閉預覽視窗  
    inoremap <expr> <CR>       pumvisible() ? "\<C-y>" : "\<CR>"    "回車即選中當前項  
    "上下左右鍵的行為 會顯示其他資訊  
    "inoremap <expr> <Down>     pumvisible() ? "\<C-n>" : "\<Down>"  
    "inoremap <expr> <Up>       pumvisible() ? "\<C-p>" : "\<Up>"  
    "inoremap <expr> <PageDown> pumvisible() ? "\<PageDown>\<C-p>\<C-n>" : "\<PageDown>"  
    "inoremap <expr> <PageUp>   pumvisible() ? "\<PageUp>\<C-p>\<C-n>" : "\<PageUp>"  
    
    "youcompleteme  預設tab  s-tab 和自動補全衝突  
    "let g:ycm_key_list_select_completion=['<c-n>']  
    let g:ycm_key_list_select_completion = ['<Down>']  
    "let g:ycm_key_list_previous_completion=['<c-p>']  
    let g:ycm_key_list_previous_completion = ['<Up>']  
    let g:ycm_confirm_extra_conf=0 "關閉載入.ycm_extra_conf.py提示  
    
    let g:ycm_collect_identifiers_from_tags_files=1 " 開啟 YCM 基於標籤引擎  
    let g:ycm_min_num_of_chars_for_completion=2 " 從第2個鍵入字元就開始羅列匹配項  
    let g:ycm_cache_omnifunc=0  " 禁止快取匹配項,每次都重新生成匹配項  
    let g:ycm_seed_identifiers_with_syntax=1    " 語法關鍵字補全  
    nnoremap <F5> :YcmForceCompileAndDiagnostics<CR>    "force recomile with syntastic  
    "nnoremap <leader>lo :lopen<CR> "open locationlist  
    "nnoremap <leader>lc :lclose<CR>    "close locationlist  
    inoremap <leader><leader> <C-x><C-o>  
    "在註釋輸入中也能補全  
    let g:ycm_complete_in_comments = 1  
    "在字串輸入中也能補全  
    let g:ycm_complete_in_strings = 1  
    "註釋和字串中的文字也會被收入補全  
    let g:ycm_collect_identifiers_from_comments_and_strings = 0  
    let g:clang_user_options='|| exit 0'  
    "nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR> " 跳轉到定義處  
    " #####YouCompleteMe Configure   
  3. .ycm_extra_conf.py中的配置

    1. 用命令檢視庫路徑

      echo | clang -v -E -x c++ -
      結果可能如下:
      clang version 3.6.2 (tags/RELEASE_362/final)
      Target: i386-pc-linux-gnu
      Thread model: posix
      Found candidate GCC installation: /usr/lib/gcc/i686-redhat-linux/4.4.4
      Found candidate GCC installation: /usr/lib/gcc/i686-redhat-linux/4.4.7
      Found candidate GCC installation: /usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1
      Selected GCC installation: /usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1
      Candidate multilib: .;@m32
      Selected multilib: .;@m32
      太長了,這裡省略一部分中間內容;.........表示生咯的內容
       "/usr/local/bin/clang" -cc1 -triple ......... -mstackrealign -fobjc-runtime=gcc  directory "/include"
      
      #include "..." search starts here: 
      
      這裡沒有顯示任何東西,所以不需要包含任何路徑
      
      #include <...> search starts here:
      
      這裡就是需要包含的路徑下面這些都是需要包含的路徑
       /usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1/../../../../include/c++/4.8.1
       /usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1/../../../../include/c++/4.8.1/i686-pc-linux-gnu
       /usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1/../../../../include/c++/4.8.1/backward
       /usr/local/include
       /usr/local/bin/../lib/clang/3.6.2/include
       /usr/include
      End of search list.
      
      # 1 "<stdin>"
      
      
      # 1 "<built-in>" 1
      
      
      # 1 "<built-in>" 3
      
      
      # 318 "<built-in>" 3
      
      
      # 1 "<command line>" 1
      
      
      # 1 "<built-in>" 2
      
      
      # 1 "<stdin>" 2
      
    2. 整理上述內容,並新增到flag中

      將以上內容複製出來,修改成如下:
       '-isystem',
       '/usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1/../../../../include/c++/4.8.1',
       '-isystem',
       '/usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1/../../../../include/c++/4.8.1/i686-pc-linux-gnu',
       '-isystem',
       '/usr/local/bin/../lib/gcc/i686-pc-linux-gnu/4.8.1/../../../../include/c++/4.8.1/backward',
       '-isystem',
       '/usr/local/include',
       '-isystem',
       '/usr/local/bin/../lib/clang/3.6.2/include',
       '-isystem',
       '/usr/include',

補全 C 語言全域性函式問題(vim ~/.vimrc檔案修改)

預設情況下輸入 ., ->, :: 之後會觸發補全函式和類, 但是預設情況下是不補全全域性函式的,所以 C 語言中的 printf 之類的函式就無法補全

解決辦法就是手動呼叫補全,對應的 YCM 函式是 ycm_key_invoke_completion,將其繫結到快捷鍵 let g:ycm_key_invoke_completion = '<C-a>'(預設是 )

編譯安裝clang+llvm

Clang和LLVM的關係

Clang和LLVM到底是什麼關係,這是在研究Clang的過程中所不可避免的一個問題。如果要搞清楚Clang和LLVM之間的關係,首先先要知道 巨集觀的LLVM微觀的LLVM

巨集觀的LLVM ,指的是整個的LLVM的框架,它肯定包含了Clang,因為Clang是LLVM的框架的一部分,是它的一個C/C++的前端。雖然這個前端佔的比重比較大,但是它依然只是個前端,LLVM框架可以有很多個前端和很多個後端,只要你想繼續擴充套件。

微觀的LLVM ,指的是以實際開發過程中,包括實際使用過程中,劃分出來的LLVM。比如編譯LLVM和Clang的時候,LLVM的原始碼包是不包含Clang的原始碼包的,需要單獨下載Clang的原始碼包。

所以這裡想討論的是 微觀的 LLVM和Clang的關係。從編譯器使用者的角度,Clang使用了LLVM中的一些功能,目前所知道的主要就是對中間格式程式碼的優化,或許還有一部分生成程式碼的功能。從Clang和微觀LLVM的原始碼位置可以看出,Clang是基於微觀的LLVM的一個工具。而 從功能的角度來說,微觀的LLVM可以認為是一個編譯器的後端,而Clang是一個編譯器的前端

編譯安裝

先說一下目錄結構:

llvm
    tools
        clang(cfe)
            tools
                extra(clang-tools-extra)
    projects
        compiler-rt
  1. 下載llvm的原始碼

    wget http://llvm.org/releases/3.9.0/llvm-3.9.0.src.tar.xz
    tar xf llvm-3.9.0.src.tar.xz
    mv llvm-3.9.0.src llvm
  2. 下載clang的原始碼

    cd llvm/tools
    wget http://llvm.org/releases/3.9.0/cfe-3.9.0.src.tar.xz
    tar xf cfe-3.9.0.src.tar.xz
    mv cfe-3.9.0.src clang
    cd ../..
  3. 下載clang-tools-extra的原始碼

    cd llvm/tools/clang/tools
    wget http://llvm.org/releases/3.9.0/clang-tools-extra-3.9.0.src.tar.xz
    tar xf clang-tools-extra-3.9.0.src.tar.xz
    mv clang-tools-extra-3.9.0.src  extra
    cd ../../../..
  4. 下載compiler-rt的原始碼

    cd llvm/projects
    wget http://llvm.org/releases/3.9.0/compiler-rt-3.9.0.src.tar.xz
    tar xf compiler-rt-3.9.0.src.tar.xz
    mv compiler-rt-3.9.0.src compiler-rt
    cd ../..

    這樣之後 clang,clang-tool-extra 和 compiler-rt 就可以和 llvm 一起編譯了。

  5. 編譯安裝

    注意: 3.7.0以後,不允許在原始碼樹中進行構建,我們可以在llvm原始碼目錄同級目錄中建立一個目錄build目錄,然後使用絕對路徑進行構建

    ./configure --enable-optimized --enable-targets=host-only --prefix=/home/YouPathToInstall/llvm

    最後一個編譯選項時指定編譯路徑,前面兩個也儘量加上。
    不然編譯時間的時候會時間很長而且佔很大的檔案空間。

    make -j4 // 編譯使用4核cpu一起編譯,加快編譯速度
    make install
  6. 檢查是否安裝成功: clang –version

  7. 完畢之後

    cd ~/.vim/bundle/YouCompleteMe 
    mkdir ~/build  
    cd ~/build  
    
    #libclang.so 這個路徑,查詢的時候updatedb更新locate的資料  
    
    locate libclang.so  
    ~/.vim/bundle/YouCompleteMe/third_party/ycmd/libclang.so  
    ~/clang/build/Release+Asserts/lib/libclang.so  
    /usr/local/lib/libclang.so  
    cmake -G "Unix Makefiles"  ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ -DEXTERNAL_LIBCLANG_PATH=~/clang/build/Release+Asserts/lib/libclang.so

    要注意的是-DEXTERNAL_LIBCLANG_PATH這個引數,用於指定libclang.so的位置。如果不指定的話,YCM將無法正常工作,總是報:The YCM shut down, crash report…之類的錯誤。而這個libclang.so就是我們在編譯Clang的時候生成的。因此,相關路徑也即~/clang/build/Release+Asserts/lib/libclang.so需要替換成自己對應的路徑。