VIM补全插件YouCompleteMe编译安装详细步骤 - Go语言中文社区

VIM补全插件YouCompleteMe编译安装详细步骤


# VIM神级补全插件YouCompleteMe安装详细步骤

YouCompleteMe(以下简称YCM)是Google搜索组程序员Valloric开发的VIM代码自动补全插件,与其它补全插件相比,最大的特点是能够基于语义完成补全,支持多种语言(智能补全支持Python/C家族/JS/Rust等)。对于C/C++语言,该插件能够利用Clang前端编译器的语义补全接口对当前代码产生符合上下文的智能补全提示,且其补全结果排名应用了搜索引擎的结果排序技术。
效果如下
ycm_snapshot
该插件是属于用VIM编码的杀手级插件,使用该插件以后,自动完成功能秒杀sublime text,notepad++等文本编辑器,直逼Visual Studio.
虽然好用,但是该插件出了名的难装,因为需要自己编译。
关于如何从Clang源码开始安装该插件,网上有数篇blog解释了具体步骤,但是经过一一实验,由于系统环境不同,全部失败了。为了安装该插件,本人找资料、编译(共编译了cmake 3.4.3/gcc 4.8.2/llvm 3.9/glibc 2.21/YCM等5个组件,历时大半天)。 整个安装配置过程前后花了至少一天半,现将安装的曲折过程全程记录如下。

安装编译过程主要参考了以下两篇资料
Full Installation Guide
compile-llvm-against-a-custom-glibc

系统环境

  $ rpm --query centos-release
      centos-release-6-4.el6.centos.10.x86_64
  $ gcc --version # 原版本4.4, 后来自己手动编译了4.8以支持C++ 11
    gcc (GCC) 4.8.2 20140120 (Red Hat 4.8.2-15)
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

第一次尝试

第一次安装不使用完全安装,直接按照YCM官网的指南直接输入

  python install.py --clang-completer
  python run_tests.py

结果编译链接过程出现以下错误

  [ 98%] Building CXX object ycm/tests/CMakeFiles/ycm_core_tests.dir/main.cpp.o
[100%] Building CXX object ycm/tests/CMakeFiles/ycm_core_tests.dir/TestUtils.cpp.o
Linking CXX executable ycm_core_tests
../../clang+llvm-3.6.0-x86_64-linux-gnu/lib/libclang.so: undefined reference to `posix_spawn@GLIBC_2.15'
../../clang+llvm-3.6.0-x86_64-linux-gnu/lib/libclang.so: undefined reference to `memcpy@GLIBC_2.14'
collect2: error: ld returned 1 exit status
make[3]: *** [ycm/tests/ycm_core_tests] Error 1
make[2]: *** [ycm/tests/CMakeFiles/ycm_core_tests.dir/all] Error 2
make[1]: *** [ycm/tests/CMakeFiles/ycm_core_tests.dir/rule] Error 2
make: *** [ycm_core_tests] Error 2
Traceback (most recent call last):
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/build.py", line 196, in 
    Main()
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/build.py", line 189, in Main
    BuildYcmdLibs( GetCmakeArgs( args ) )
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/build.py", line 152, in BuildYcmdLibs
    _err = sys.stderr )
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 1021, in __call__
    return RunningCommand(cmd, call_args, stdin, stdout, stderr)
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 486, in __init__
    self.wait()
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 500, in wait
    self.handle_command_exit_code(exit_code)
  File "/home/user/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/sh/sh.py", line 516, in handle_command_exit_code
    raise exc(self.ran, self.process.stdout, self.process.stderr)
sh.ErrorReturnCode_2: 

  RAN: '/usr/bin/make -j 8 ycm_core_tests'

  STDOUT:


  STDERR:

输入以下命令查看依赖库

  strings ~/.vim/bundle/YouCompleteMe/third_party/ycmd/libclang.so.3.8 | grep -i glibc

发现是liclang.so.3.8需要至少Glibc 2.15, GlibCXX 3.4.19, Centos 6.4自带的Glibc版本2.12版本太低,无法满足最低版本要求。
于是去LLVM官网上下载了一个针对Centos6编译好的Clang3.8,然后按照完全安装指南指定编译选项

  cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp

结果问题依旧。需要系统更高版本Glibc的问题依然未解决。接着尝试了下载针对Fedora 18预编译的YCM所支持的最早Clang版本3.3,结果一样,链接失败。

由于YCM官网强烈不推荐自己编译Clang,于是本人尝试直接使用包管理器安装老版本Clang

  sudo yum install -y clang

结果使用-DEXTERNAL_LIBCLANG_PATH选项编译好YCM以后进入vim输入’:YcmToggleLogs stderr’发现不能用,YCM需要Clang3.8版本,晕死。
目前为止除非直接下载新版Glibc并替换系统库,否则无法继续下去。该问题的关键原因是可执行文件链接的库路径是直接硬编码在文件中的,具体原理可以参考这里。但是, 替换系统核心库Glibc是一件极其容易导致系统崩溃的行为,Google了一下发现已经有好几个人这么弄中招了。公司72服务器上有MySQL服务器保存了数T的用户行为数据,不能冒这个险。因此,唯一的选择只能是从源码重新编译Clang+llvm,并链接指定的Glibc库。
总结: 由于10.200.8.72(以下简称72)上安装的64位Centos 6.4系统版本太老不支持直接安装YCM自带的预编译的的llvm+clang(要求GLibc >= 2.15且GLibCXX >= 3.4.19, 其中72上自带的Glibc 2.12为系统核心组件无法替换,因此只能重新编译clang3.8或以上的版本并链接下载的新版GLibc)

## 成功编译过程

cmake 3.4.3 required by llvm compilation

    cd ~
    wget https://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz
    tar -zxf cmake-3.4.3-Linux-x86_64.tar.gz

gcc 4.8.2

    cd ~
    mkdir -p ~/gcc4.8/src
    wget https://ftp.gnu.org/gnu/gcc/gcc-4.8.2/gcc-4.8.2.tar.gz
    tar -zxf gcc-4.8.2.tar.gz -C ~/gcc4.8/src
    cd ~/gcc4.8/src/
    mkdir gcc-build-4.8.2
    cd gcc-build-4.8.2
    ../gcc-4.8.2/configure --enable-checking=release --enable-languages=c,c++ --disable-multilib
    make -j 6 # 2.3G+, 事后可删除gcc-build目录
    sudo cp -fp ./x86_64-unknown-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.18 /usr/lib64/ 
    mv /usr/lib64/libstdc++.so.6.0.18 /usr/lib64/libstdc++.so.6 # ln -sf ./lib/gcc/x86_64-redhat-linux/4.8.2/libstdc++.so /usr/lib64/

编译gcc大约需要半小时,为了节省时间,make时使用’-j 6’指定了6个核心

glibc 2.21

    mkdir -p ~/code/glibc
    wget http://ftp.gnu.org/gnu/glibc/glibc-2.21.tar.gz
    tar -zxf glibc-2.21.tar.gz -C ~/code/glibc
    cd ~/code/glibc/glibc-2.21
    mkdir build
    cd build
    export LD_FLAGS='-Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib64:/usr/lib64'
    ../configure --with-binutils=/usr/local/bin --prefix=/usr/local/glibc/glibc-2.21
    make -j 6
    sudo make install

安装过程会出现如下警告

/home/rstudio2/code/glibc/glibc-2.21/build/elf/ldconfig: Warning: ignoring configuration file that cannot be opened: /usr/local/glibc/glibc-2.21/etc/ld.so.conf: No such file or directory
make[1]: Leaving directory `/home/user/code/glibc/glibc-2.21'

不用理会,直接忽略

llvm 3.9

    mkdir ~/code
    cd ~/code/llvm_source_tree
    git clone http://llvm.org/git/llvm.git
    cd ~/code/llvm_source_tree/llvm/tools
    git clone http://llvm.org/git/clang.git
    cd ~/code/llvm_source_tree/llvm/projects
    git clone http://llvm.org/git/compiler-rt.git
    git clone http://llvm.org/git/test-suite.git # 1.8G+
    cd ~/code/llvm_source_tree/llvm
    git config branch.master.rebase true
    mkdir -p ~/code/llvm_source_tree/build
    cd ~/code/llvm_source_tree/build
    export CXXFLAGS='-std=c++11 -Wl,--rpath=/usr/local/glibc/glibc-2.21/lib:/lib64:/usr/lib64 -Wl,--dynamic-linker=/usr/local/glibc/glibc-2.21/lib/ld-linux-x86-64.so.2'
    ~/cmake-3.4.3-Linux-x86_64/bin/cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE='Release' ~/code/llvm_source_tree/llvm/
    make -j 6 # 1.5G+, 事后可删除build目录
    sudo make install

编译llvm大约需要半小时,为了节省时间,make时使用’-j 6’指定了6个核心

YCM

首先安装vim包管理插件vundle, 关于该插件如何安装,可以Google, 例如这里
接着正式开始安装YCM插件

    Plugin 'Valloric/YouCompleteMe' # bundle required
    cd .vim/bundle/YouCompleteM
    cmake28 -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/usr/local/lib/libclang.so.3.9 . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
    cmake28 --build . --target ycm_core
    python install.py  --clang-completer
    sudo pip install --upgrade pip
    sudo pip install flake8 nose future mock PyHamcrest
    python run_tests.py
                ----------------------------------------------------------------------
        Ran 221 tests in 6.323s

        OK (SKIP=3)

配置YCM

查看系统编译器include搜索路径

    echo | cpp -Wp,-v
    echo | /usr/local/bin/clang -std=c++11 -stdlib=libc++ -v -E -x c++ -

将这两个命令的输出添加至YCM配置文件
‘/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py’

编辑配置文件 .ycm_extra_conf.py

在flags编译器选项加入以下行

    '-I',
    '/usr/include/c++/4.8.2',
    '-I',
    '/opt/rh/devtoolset-2/root/usr/include/c++/',
    '-I',
    '/opt/rh/devtoolset-2/root/usr/lib/gcc/x86_64-redhat-linux/4.8.2/include',
    '-I',
    '/usr/local/include/',  

其中/opt/rh/devtoolset-2/root/usr 是写本文之前下载的gcc4.8.2源码的文件路径,当时编译的libstdc++.so.*已经找不到了,为了演示在开始步骤重新下载编译了gcc 4.8.2,这次放在了~/gcc目录下。

编辑vim配置文件’~/.vimrc’

    ~/.vimrc
        let g:ycm_auto_trigger = 1 
        " for ycm
        let g:ycm_error_symbol = '>>'
        let g:ycm_warning_symbol = '>*'
        let g:ycm_autoclose_preview_window_after_completion = 1 
        let g:ycm_autoclose_preview_window_after_insertion = 1 
        let g:ycm_global_ycm_extra_conf = "~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py"
        nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR>
        nnoremap <leader>gf :YcmCompleter GoToDefinition<CR>
        nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR>
        nnoremap <F4> :YcmDiags<CR>                                                                                                                                                                                                                            
        inoremap <c-o> <c-x><c-o>
        let g:ycm_semantic_triggers = { 
             'c' : ['->', '  ', '.', ' ', '(', '[', '&'],
             'cpp,objcpp' : ['->', '.', ' ', '(', '[', '&', '::'],
             'perl' : ['->', '::', ' '],
             'php' : ['->', '::', '.'],
             'cs,java,javascript,d,vim,python,perl6,scala,vb,elixir,go' : ['.'],
             'ruby' : ['.', '::'],
             'lua' : ['.', ':']
         }

至此,终于在服务器上的古董系统CentOS 6.4上搞定了YCM的安装,可以愉快的敲代码了。安装后效果
ycm_cpp_使用效果

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/vcbin/article/details/51770170
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2019-09-05 14:27:32
  • 阅读 ( 2180 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢