首页 > 程序开发 > 综合编程 > 其他综合 >

Debian+GCC+LLVM Clang+Vim配置YouCompleteMe

2016-11-12

一:系统安装与配置:虚拟机软件:Virtualbox 5 1 8(已安装相应扩展包)虚拟机:Debian 8 5 64位,系统安装完成之后,用root用户登录终端(因为Debian 8默认没有安装sudo)。

一:系统安装与配置

虚拟机软件:Virtualbox 5.1.8(已安装相应扩展包)

虚拟机:Debian 8.5 64位

系统安装完成之后,用root用户登录终端(因为Debian 8默认没有安装sudo),用如下命令编辑软件源配置文件,把安装DVD介质注释掉,以便于能从官方网络源更新软件:

nano /etc/apt/sources.list

然后更新软件列表:apt-get update

安装编译用的基础工具包:apt-get install build-essential

用如下命令来安装Virtualbox 扩展工具包:

apt-get install module-assistant
m-a prepare

mount /media/cdrom

sh /media/cdrom/VBoxLinuxAdditions.run

安装完成之后重启系统

重启之后用如下命令安装必要的依赖包和工具:

apt-get install python-dev zip flex bison libncurses5-dev libgnome2-dev libgnomeui-dev libbonoboui2-dev libcairo2-dev libx11-dev libxpm-dev libxt-dev ruby-dev mercurialgit-all sudo

然后执行事先写好的编译安装GCC 5.4的shell脚本,build_gcc,脚本内容如下:

注意:脚本中配置很多依赖库的目录名要根据实际情况而定,具体的安装过程可参照我的另一篇文章,只是版本不一样,其它没什么区别,这里,你可以选择目前最新的工具包。

#!/bin/sh
cd /home/guo/gmp/
./configure --prefix=/usr
make -j2
make install
cd /home/guo/mpfr/
./configure --prefix=/usr
make -j2
make install
cd /home/guo/mpc/
./configure --prefix=/usr
make -j2
make install
ldconfig 
cd /home/guo/libedit/
./configure --prefix=/usr
make -j2
make install
cd /home/guo/pcre/
./configure --prefix=/usr
make -j2
make install
cd /home/guo/swig/
./configure --prefix=/usr
make -j2
make install
cd /home/guo/gawk/
./configure --prefix=/usr
make -j2
make install
ldconfig 
mkdir /usr/lib/gcc/x86_64-linux-gnu/5.4.0
cd /home/guo/gcc/
./configure --prefix=/usr/lib/gcc/x86_64-linux-gnu/5.4.0 --enable-vtable-verify --enable-werror --disable-multilib
make -j2
make install
cd /usr/bin/
rm cpp
rm g++
rm gcc
rm gcc-ar
rm gcc-nm
rm gcc-ranlib
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/bin/cpp cpp
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/bin/g++ g++
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/bin/gcc gcc
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/bin/gcc-ar gcc-ar
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/bin/gcc-nm gcc-nm
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/bin/gcc-ranlib gcc-ranlib
cd /usr/lib/x86_64-linux-gnu/
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib64/libstdc++.so.6.0.21 libstdc++.so.6

GCC安装完成之后,执行编译安装LLVM Clang 3.8.1的shell脚本,build_clang,脚本内容如下:

关于LLVM的目录结构:将Clang源码解压到llvm/tools下,将clang-tools-extra解压到llvm/tools/clang/tools/下,将compiler-rt、libc++、libc++abi、test-suite解压到llvm/projects下

#!/bin/sh
mkdir /home/guo/build/
cd /home/guo/build/
rm -rf /home/guo/gcc/
../llvm/configure --with-clang-srcdir=../llvm/tools/clang/ --with-gcc-toolchain=/usr/lib/gcc/x86_64-linux-gnu/5.4.0/ --enable-optimized --enable-targets=host-only
make
make install
cd ../llvm/projects/libcxx/lib/
./buildit
cp ./libc++.so.1.0 /usr/lib/x86_64-linux-gnu/
cd /usr/lib/x86_64-linux-gnu/
ln -sf libc++.so.1.0 libc++.so
ln -sf libc++.so.1.0 libc++.so.1
cd /home/guo/llvm/projects/libcxxabi/lib
./buildit
cp ./libc++abi.so.1.0 /usr/lib/x86_64-linux-gnu/
cd /usr/lib/x86_64-linux-gnu/
ln -sf libc++abi.so.1.0 libc++abi.so
cd /usr/lib/x86_64-linux-gnu/
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib64/libstdc++.so.6.0.21 libstdc++.so.6
cd /home/guo/vim74/
./configure --with-features=huge --enable-multibyte --enable-fontset --enable-sniff --enable-xim --enable-rubyinterp --enable-pythoninterp --with-python-config-dir=/usr/lib/python2.7/config --enable-perlinterp --enable-luainterp --enable-gui=gtk2 --enable-cscope --prefix=/usr
make VIMRUNTIMEDIR=/usr/share/vim/vim74
make install
mkdir -p /home/guo/.vim/colors
chown -R guo:guo /home/guo/.vim/
mkdir -p /root/.vim/colors
touch /home/guo/.vimrc
chown guo:guo /home/guo/.vimrc
cp /home/guo/solarized/vim-colors-solarized/colors/solarized.vim /home/guo/.vim/colors/
cp /home/guo/solarized/vim-colors-solarized/colors/solarized.vim /root/.vim/colors
cat /home/guo/vimrcusr > /home/guo/.vimrc
cat /home/guo/vimrcroot > /etc/vim/vimrc
cd /usr/bin/
ln -sf vim vi
cp /usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib64/libstdc++.so.6.0.21 /usr/lib/x86_64-linux-gnu/
cd /usr/lib/x86_64-linux-gnu/
ln -sf libstdc++.so.6.0.21 libstdc++.so.6
cd /home/guo/binutils-2.27
./configure --prefix=/usr
make -j2
make install
cd /home/guo/gdb-7.11.1
./configure --prefix=/usr
make -j2
make install
cd /home/guo/cmake-3.6.2
./configure --prefix=/usr
make -j2
make install
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib64/libstdc++.so.6.0.21 /usr/lib/x86_64-linux-gnu/libstdc++.so.6
注意:上面红色标记的命令用到的文件我把其内容贴在下面,至于solarized,可以从这里下载,也许在安装完GCC之后需要再次对GCC 最新的动态库进行链接(也许有操作让该库恢复到旧版本),才能正常编译安装Clang。用如下命令:

cd /usr/lib/x86_64-linux-gnu/
ln -sf /usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib64/libstdc++.so.6.0.21 libstdc++.so.6

vimrcusr:

syntax enable
syntax on
set number
set nocompatible
set backspace=indent,eol,start
set background=dark
set tabstop=2
set expandtab
%retab!
colorscheme solarized
filetype off
let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'
let g:ycm_error_symbol='>>'
let g:ycm_warning_symbol='>*'
inoremap         pumvisible() ? "\" : "\"
"设置跳转的快捷键,可以跳转到definition和declaration
nnoremap gc :YcmCompleter GoToDeclaration
nnoremap gf :YcmCompleter GoToDefinition
nnoremap gg :YcmCompleter GoToDefinitionElseDeclaration
"nmap  :YcmDiags
"开启基于tag的补全,可以在这之后添加需要的标签路径
let g:ycm_collect_identifiers_from_tags_files = 1
"开启语义补全
let g:ycm_seed_identifiers_with_syntax = 1
"在接受补全后不分裂出一个窗口显示接受的项
set completeopt-=preview
"不显示开启vim时检查ycm_extra_conf文件的信息
let g:ycm_confirm_extra_conf=0
"每次重新生成匹配项,禁止缓存匹配项
let g:ycm_cache_omnifunc=0
"在注释中也可以补全
let g:ycm_complete_in_comments=1
"输入第一个字符就开始补全
let g:ycm_min_num_of_chars_for_completion=1
"不查询ultisnips提供的代码模板补全,如果需要,设置成1即可
let g:ycm_use_ultisnips_completer=1

let g:ycm_collect_identifiers_from_comments_and_strings = 1

let g:ycm_key_invoke_completion = ''

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

" The following are examples of different formats supported.
" Keep Plugin commands between vundle#begin/end.
" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
" plugin from http://vim-scripts.org/vim/scripts.html
Plugin 'L9'

Plugin 'Valloric/YouCompleteMe'

" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList       - lists configured plugins
" :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line
vimrcroot:
" All system-wide defaults are set in $VIMRUNTIME/debian.vim (usually just
" /usr/share/vim/vimcurrent/debian.vim) and sourced by the call to :runtime
" you can find below.  If you wish to change any of those settings, you should
" do it in this file (/etc/vim/vimrc), since debian.vim will be overwritten
" everytime an upgrade of the vim packages is performed.  It is recommended to
" make changes after sourcing debian.vim since it alters the value of the
" 'compatible' option.

" This line should not be removed as it ensures that various options are
" properly set to work with the Vim-related packages available in Debian.
runtime! debian.vim

" Uncomment the next line to make Vim more Vi-compatible
" NOTE: debian.vim sets 'nocompatible'.  Setting 'compatible' changes numerous
" options, so any other options should be set AFTER setting 'compatible'.
"set compatible

" Vim5 and later versions support syntax highlighting. Uncommenting the next
" line enables syntax highlighting by default.
"syntax on

" If using a dark background within the editing area and syntax highlighting
" turn on this option as well
"set background=dark

" Uncomment the following to have Vim jump to the last position when
" reopening a file
"if has("autocmd")
"  au BufReadPost * if line("&#39;\"") > 1 && line("&#39;\"") <= line("$") | exe "normal! g&#39;\"" | endif
"endif

" Uncomment the following to have Vim load indentation rules and plugins
" according to the detected filetype.
"if has("autocmd")
"  filetype plugin indent on
"endif

" The following are commented out as they cause vim to behave a lot
" differently from regular Vi. They are highly recommended though.
"set showcmd		" Show (partial) command in status line.
"set showmatch		" Show matching brackets.
"set ignorecase		" Do case insensitive matching
"set smartcase		" Do smart case matching
"set incsearch		" Incremental search
"set autowrite		" Automatically save before commands like :next and :make
"set hidden             " Hide buffers when they are abandoned
"set mouse=a		" Enable mouse usage (all modes)

" Source a global configuration file if available
if filereadable("/etc/vim/vimrc.local")
  source /etc/vim/vimrc.local
endif

syntax enable
syntax on
set number
set nocompatible
set backspace=indent,eol,start
set background=dark
set tabstop=2
set expandtab
%retab!
colorscheme solarized

filetype off
注意,在配置完成Vim之前不要打开Vim。

如果你要用clang++来编译含有C++11语法的C++代码,编译时用如下形式:

clang++ --std=c++11 -stdlib=libc++ -lc++abi test.cpp

到这里,GCC 5.4 和 Clang 3.8.1还有一些工具就安装好了,接下来主要配置Vim 7.4和YouCompleteMe

安装Vim插件Vundle:

git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

安装.vimrc配置文件中的Vim插件和下载YouCompleteMe(这个过程可能要花较长时间,具体情况根据你的网络质量而定):

vim +PluginInstall +qall

用如下命令来编译YouCompleteMe

cd ~
mkdir ycm_build
cd ycm_build
cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=/usr/local/lib/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
make -j2

应用YouCompleteMe配置文件:

mv ycm_extra_conf.py .ycm_extra_conf.py

ycm_extra_conf.py的内容为:

# This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here&#39;s the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to 

import os
import ycm_core

# These are the compilation flags that will be used in case there&#39;s no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
&#39;-Wall&#39;,
&#39;-Wextra&#39;,
&#39;-Werror&#39;,
&#39;-Wc++98-compat&#39;,
&#39;-Wno-long-long&#39;,
&#39;-Wno-variadic-macros&#39;,
&#39;-fexceptions&#39;,
&#39;-DNDEBUG&#39;,
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
# source code needs it.
&#39;-DUSE_CLANG_COMPLETER&#39;,
# THIS IS IMPORTANT! Without a "-std=" flag, clang won&#39;t know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don&#39;t want that so ALWAYS specify
# a "-std=".
# For a C project, you would set this to something like &#39;c99&#39; instead of
# &#39;c++11&#39;.
&#39;-std=c++11&#39;,
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to &#39;c&#39; instead of &#39;c++&#39;.
&#39;-x&#39;,
&#39;c++&#39;,
&#39;-I&#39;,
&#39;/home/guo/Algoritbms/ch-8/&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include/c++/5.4.0&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include/c++/5.4.0/x86_64-unknown-linux-gnu&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include/c++/5.4.0/backward&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib/gcc/x86_64-unknown-linux-gnu/5.4.0/include&#39;,
&#39;-isystem&#39;,
&#39;/usr/local/include&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib/gcc/x86_64-unknown-linux-gnu/5.4.0/include-fixed&#39;,
&#39;-isystem&#39;,
&#39;/usr/include/x86_64-linux-gnu&#39;,
&#39;-isystem&#39;,
&#39;/usr/include&#39;
&#39;-isystem&#39;,
&#39;../BoostParts&#39;,
&#39;-isystem&#39;,
# This path will only work on OS X, but extra paths that don&#39;t exist are not
# harmful
&#39;/System/Library/Frameworks/Python.framework/Headers&#39;,
&#39;-isystem&#39;,
&#39;../llvm/include&#39;,
&#39;-isystem&#39;,
&#39;../llvm/tools/clang/include&#39;,
&#39;-I&#39;,
&#39;.&#39;,
&#39;-I&#39;,
&#39;./ClangCompleter&#39;,
&#39;-isystem&#39;,
&#39;./tests/gmock/gtest&#39;,
&#39;-isystem&#39;,
&#39;./tests/gmock/gtest/include&#39;,
&#39;-isystem&#39;,
&#39;./tests/gmock&#39;,
&#39;-isystem&#39;,
&#39;./tests/gmock/include&#39;,
]

# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of &#39;flags&#39;. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
#   set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# &#39;flags&#39; list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = &#39;&#39;

if os.path.exists( compilation_database_folder ):
  database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
  database = None

SOURCE_EXTENSIONS = [ &#39;.cpp&#39;, &#39;.cxx&#39;, &#39;.cc&#39;, &#39;.c&#39;, &#39;.m&#39;, &#39;.mm&#39; ]

def DirectoryOfThisScript():
  return os.path.dirname( os.path.abspath( __file__ ) )


def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
  if not working_directory:
    return list( flags )
  new_flags = []
  make_next_absolute = False
  path_flags = [ &#39;-isystem&#39;, &#39;-I&#39;, &#39;-iquote&#39;, &#39;--sysroot=&#39; ]
  for flag in flags:
    new_flag = flag

    if make_next_absolute:
      make_next_absolute = False
      if not flag.startswith( &#39;/&#39; ):
        new_flag = os.path.join( working_directory, flag )

    for path_flag in path_flags:
      if flag == path_flag:
        make_next_absolute = True
        break

      if flag.startswith( path_flag ):
        path = flag[ len( path_flag ): ]
        new_flag = path_flag + os.path.join( working_directory, path )
        break

    if new_flag:
      new_flags.append( new_flag )
  return new_flags


def IsHeaderFile( filename ):
  extension = os.path.splitext( filename )[ 1 ]
  return extension in [ &#39;.h&#39;, &#39;.hxx&#39;, &#39;.hpp&#39;, &#39;.hh&#39; ]


def GetCompilationInfoForFile( filename ):
  # The compilation_commands.json file generated by CMake does not have entries
  # for header files. So we do our best by asking the db for flags for a
  # corresponding source file, if any. If one exists, the flags for that file
  # should be good enough.
  if IsHeaderFile( filename ):
    basename = os.path.splitext( filename )[ 0 ]
    for extension in SOURCE_EXTENSIONS:
      replacement_file = basename + extension
      if os.path.exists( replacement_file ):
        compilation_info = database.GetCompilationInfoForFile(
          replacement_file )
        if compilation_info.compiler_flags_:
          return compilation_info
    return None
  return database.GetCompilationInfoForFile( filename )


def FlagsForFile( filename, **kwargs ):
  if database:
    # Bear in mind that compilation_info.compiler_flags_ does NOT return a
    # python list, but a "list-like" StringVec object
    compilation_info = GetCompilationInfoForFile( filename )
    if not compilation_info:
      return None

    final_flags = MakeRelativePathsInFlagsAbsolute(
      compilation_info.compiler_flags_,
      compilation_info.compiler_working_dir_ )

    # NOTE: This is just for YouCompleteMe; it&#39;s highly likely that your project
    # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
    # ycm_extra_conf IF YOU&#39;RE NOT 100% SURE YOU NEED IT.
    try:
      final_flags.remove( &#39;-stdlib=libc++&#39; )
    except ValueError:
      pass
  else:
    relative_to = DirectoryOfThisScript()
    final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )

  return {
    &#39;flags&#39;: final_flags,
    &#39;do_cache&#39;: True
  }

配置文件中最重要的部分为:

&#39;-x&#39;,
&#39;c++&#39;,
&#39;-I&#39;,
&#39;/home/guo/Algoritbms/ch-8/&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include/c++/5.4.0&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include/c++/5.4.0/x86_64-unknown-linux-gnu&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include/c++/5.4.0/backward&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib/gcc/x86_64-unknown-linux-gnu/5.4.0/include&#39;,
&#39;-isystem&#39;,
&#39;/usr/local/include&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include&#39;,
&#39;-isystem&#39;,
&#39;/usr/lib/gcc/x86_64-linux-gnu/5.4.0/lib/gcc/x86_64-unknown-linux-gnu/5.4.0/include-fixed&#39;,
&#39;-isystem&#39;,
&#39;/usr/include/x86_64-linux-gnu&#39;,
&#39;-isystem&#39;,
&#39;/usr/include&#39;
&#39;-isystem&#39;,
&#39;../BoostParts&#39;,
&#39;-isystem&#39;,
这部分是指定YouCompleteMe在补全时依赖的头文件声明,&#39;-I&#39;后面的路径是用户自己的项目头文件路径,&#39;-isystem&#39;,后面的路径是系统默认的头文件路径。这里很关键的就是系统默认的头文件路径,可以在用gcc和g++编译自己的C和C++源代码时,加上"-v"选项,然后就会打印出搜索路径,把"搜索从这里开始"到"搜索列表结束"中的路径按照格式添加进去就可以了。

YouCompleteMe是根据头文件来补全的,也就是说它只能补全你源码里#include中的东西和一些基本的关键字,我在Vim的配置文件中配置了用CTL + A进行全局补全,比如printf之类的。

相关文章
最新文章
热点推荐