废话

生命在于折腾。

之前不用这个插件的原因:

  • 因为要使这个插件起作用,前前后后需要下载几百MB(win下更是超过了1GB)的东西,包括了Clang编译器,ycmd的c艹源码还有ycm本身的vim script,也就是说我安装这个插件比一个IDE的体积还大。

  • 另外一个原因就是就是Windows下使用安装插件及其麻烦,这样的话就有可能无法保持相同体验,还不如不要算了。

现在为什么使用呢?第一句话。

熟悉之后感觉前面的折腾还是非常值得的,体验接近ide了,ycm不仅提供了语义级别的智能补全,还提供了函数定义跳转,而所有这些都是非常迅速不会导致vim变卡。

编译流程


主要参考官方wiki中的这一部分Instructions for 64-bit using MinGW64 clang。

这短短的几句话忽略了大量的细节,如果是新手的话相信是很难搞得定的。所以我来细化它。

编译环境——MSYS2


MSYS2是作为MinGw的替代者出现的,它的出现可以说结束了Windows下模拟Linux环境混乱的局面,它移植来自Arch Linux中强大的包管理器:pacman。我们通过pacman来安装其它东西,比如说MinGw(目的在于提供编译WIndows本地程序的工具集),git(我们再也不需要装一个msysgit然后再装一个MinGw了)。

这是一篇较为详细的对比:Cygwin 与 MinGW/MSYS/MSYS2,如何选择?

官方对比How does MSYS2 differ from Cygwin

Cygwin的话,我的理解,它提供接口更加兼容POSIX,在win api和应用之间加了一层兼容层(cygwin1.dll,所以由Cygwin的gcc编译出来的应用程序在效率是输给MinGw)的,所以在win下编译unix下开源软件,首选是MinGw,你可以看到好多IDE(CodeBlock,QT等)其实包含了MinGW。

官网:msys2,下载对应平台的exe安装好之后,在开始菜单打开MSYS2 Shell,你还会发现另外两个快捷方式MinGW-W64 win64 Shell和MinGW-W64 win32 Shell,不过现在它们还打不开。

$ pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime

执行完毕之后,关闭Shell,重新打开。

$ pacman -Su #更新其它组件到最新..

关闭重打开,更换pacman的源。

$ cd /etc/pacman.d
$ gvim -p mirrorlist.mingw32 mirrorlist.mingw64 mirrorlist.msys #你在文件浏览器打开这个路径然后用其它编辑器,这里只是示意而已.

然后在这三个文件最开头分别添加一行(按照上面的顺序)

Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MINGW/i686

Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MINGW/x86_64

Server = http://mirrors.ustc.edu.cn/msys2/REPOS/MSYS2/$arch

# 安装以下东西..
pacman -Sy
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-make tmux zsh git mingw64/mingw-w64-x86_64-cmake winpty-git

解释下,第一个是编译器,第二个是调试器,第三个工程管理工具make,后面两个是文本三巨头之二,在后来是版本管理神器,cmake则是很受欢迎的新一代工程管理工具也是我们编译YCM需要的工具,最后一个是解决mintty下有些工具卡死没有输出的情况的工具。

# winpty使用示例,这里直接调用python会卡死..
$ winpty python

mingw-w64相关默认安装/mingw64下,所以在MSYS2 Shell下默认找不到gcc命令的,你可以将相关路径添加到诸如/etc/profile,.bashrc和.zshrc这样的文件中,也可以在win下面改Path变量。

但更直接的方式在打开前面提到的快捷方式MinGW-W64 win64 Shell,注意别看错打开win32的shell了。

pacman的基本使用

# 安装新包
pacman -S <package_names|package_groups>
# 移除包
pacman -R <package_names|package_groups>
# 搜索包,支持正则搜索
pacman -Ss <name_pattern>

编译一个64位的gvim/vim (非必须,你可以直接到官网下载安装即可,我有点强迫症,想保证两者 都是64位的)


打开MinGW-W64 win64 Shell。

VIM官网只提供了32位的程序,按照上面的wiki我们需要编译一个带有python2特性的64位vim好来验证我们是否安装成功了。

这里可以使用我的编译脚本和vim配置,从github上脱下之后,里面有一个build_vim.sh脚本用于编译vim。

$ git clone https://github.com/tracyone/vim vim_conf && cd vim_conf

在执行这个脚本之前你需要,你需要编辑这个脚本最开头宏定义,里面定义诸如安装路径,python安装路径,架构等..

其中有python2,python3,ruby,lua,tcl,perl等外部接口支持,注意把不需要的接口对应的变量注释掉,否则会编译失败。

去官网下载最新python2,并加入Path变量,然后安装,然后修改下面几个变量

# python2 support
PYTHON=/e/program_files/Python27
DYNAMIC_PYTHON=yes
PYTHON_VER=27
$ ./build_vim.sh all

上面那条命令会下载vim源代码(接近800MB),并编译gvim和vim最终打开文件管理器,你只需要双击install.exe然后再弹出的界面中输入d就能完成最后的安装了。另外,也拷贝了我的vimrc到vim安装目录下。所以首次打开时会自动安装插件,请确保网络通畅,由于需要安装较多插件(并且包含了接近200MB的YCM插件),请非常耐心等待。

安装YCM(非编译)

上面那一步顺利完成的话已经装好,如果没有就自己按照下面的方法来做。

第一种方法:

"使用vim-plug插件来安装ycm,下面这句话加入你的vimrc然后重启vim,执行`:PlugInstall YouCompleteMe`
Plug 'Valloric/YouCompleteMe', { 'do': 'git submodule update --init --recursive' }

第二种:你可以手动安装YCM,执行下面命令之后,将YouCompleteMe整个拷贝到vim插件管理器指定的路径之下。

git clone https://github.com/Valloric/YouCompleteMe.git
cd YouCompleteMe
git submodule update --init --recursive

编译YCM


打开MinGW-W64 win64 Shell。

首先你得下载一个编译好的64位的LLVM with Clang Support的安装包,奇怪的是官网只提供了32位的安装包,一度我想用MinGw从源代码编译一个,后来太多错误就放弃了,最后发现这个项目有提供64位的安装包ClangOnWin。

安装到你想要安装的地方,这里我安装到c:/LLVM。

Windows路径的变换:如果Windows路径是"C:\Program Files\Vim",那么你需要用转义符号转义空格,并改变斜杠的方向,最后变成"C:/Program\ Files/Vim"。

$ cd <root of vim installed>/vimfiles/bundle/YouCompleteMe
$ mkdir build ;cd build
$ cmake -G "MSYS Makefiles" -DCMAKE_MAKE_PROGRAM=E:/msys64/mingw64/bin/mingw32-make.exe -DPATH_TO_LLVM_ROOT=C:/LLVM . E:/program_files/Vim/vimfiles/bundle/YouCompleteMe/third_party/ycmd/cpp
$ mingw32-make ycm_core

至此结束,要确保正常运行,需要保证添加到Path环境变量中,在MSYS2 Shell中同样需要保证这两个路径在Path变量中,否则会出现加载模块的错误。

  • Python2所在路径
  • mingw64/bin路径
  • llvm所在路径

也可以分别将相关的dll拷贝到YouCompleteMe/third_party/ycmd路径下:libstdc++-6.dll,libwinpthread-1.dll,libclang.dll和libgcc_s_seh-1.dll。

使用教程和配置

使用YouCompleteMe对工程进行补全,需要为每个工程提供一个项目文件:.ycm_extra_conf.py,主要指定的是编译器的option,比如说连接的库,库路径,头文件路径,宏定义,编译器优化标志等等。

这里要介绍一个插件,YCM-Generator,他能根据项目中Makefiles等文件生成对应的.ycm_extra_conf.py文件。很多时候这东西是不错的,但是某些情况还是不够灵活,比如说如果Makefile里面是交叉编译器的话,它不支持。

项目根目录下打开vim并执行:call GenYcm()(我的配置里面的函数)。

另外一个插件ycm_simple_conf,这个插件需要编写一个xml文件,然后根据这个xml文件生成,这样的话就比较灵活点。

在每个项目的根目录下编写.ycm_simple_conf.xml文件。

<project type="c++">
<include path="/home/local/libA/include"/>
<include path="/home/local/libB/include"/>
<include path="include"/>
<include path="build"/>
</project>
这个函数是为插件YCM-Generator的写的。
function! GenYCM()
let l:cur_dir=getcwd()
cd $VIMFILES/bundle/YCM-Generator
:silent execute ":!./config_gen.py ".l:cur_dir
if v:shell_error == 0
echom "Generate successfully!"
:YcmRestartServer
else
echom "Generate failed!"
endif
exec ":cd ". l:cur_dir
endfunction "下面三个映射是YCM提供函数跳转功能
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
nnoremap <leader>jl :YcmCompleter GoToDeclaration<CR>
nnoremap <leader>jf :YcmCompleter GoToDefinition<CR> "由于Clang编译器的限制,ycm跳转功能有致命缺陷,无法跳到另外文件的函数定义上面
"所以我写了YcmGotoDef函数加上插件a.vim,实现粗略的跳转,原理是当Ycm跳到对应函数
"声明的头文件时使用a.vim的功能跳到对应源文件,在使用正则搜索,跳到函数定义上面。
nnoremap <Leader>g :call TracyoneGotoDef("")<cr>
nnoremap <C-\>g :call TracyoneGotoDef("sp")<cr> function! TracyoneGotoDef(open_type)
let l:ycm_ret=s:YcmGotoDef(a:open_type)
if l:ycm_ret < 0
try
execute "cs find g ".expand("<cword>")
catch /^Vim\%((\a\+)\)\=:E/
call s:EchoWarning("cscope query failed")
if a:open_type != "" | wincmd q | endif
return -1
endtry
else
return 0
endif
return 0
endfunction func! s:YcmGotoDef(open_type)
let l:cur_word=expand("<cword>")."\s*\(.*[^;]$"
:redir => l:msg
execute a:open_type
silent! execute ":YcmCompleter GoToDefinition"
:redir END
let l:rs=split(l:msg,'\r\n\|\n')
"make sure index valid
if get(l:rs,-1,3) !=3 && l:rs[-1] =~ 'Runtime.*'
:redir => l:msg
silent! execute ":YcmCompleter GoToDeclaration"
:redir END
let l:rs=split(l:msg,'\r\n\|\n')
if get(l:rs,-1,3) != 3 && l:rs[-1] !~ 'Runtime.*'
execute ":silent! A"
" search failed then go back
if search(l:cur_word) == 0
execute ":silent! A"
return -2
endif
return 3
elseif get(l:rs,-1,3) == 3 "not exist no error
return 0
else
return -3
endif else
return 1
endif
endfunc "当tab补全时vim上面会分裂一个小窗口显示函数变量原型,我们按下esc或者结束补全时
"自动关闭那个窗口
autocmd misc_group InsertLeave * if pumvisible() == 0|pclose|endif let g:syntastic_always_populate_loc_list = 1
let g:ycm_confirm_extra_conf=0
let g:syntastic_always_populate_loc_list = 1
let g:ycm_semantic_triggers = {
\ 'c' : ['->', ' ', '.', ' ', '(', '[', '&'],
\ 'cpp,objcpp' : ['->', '.', ' ', '(', '[', '&', '::'],
\ 'perl' : ['->', '::', ' '],
\ 'php' : ['->', '::', '.'],
\ 'cs,java,javascript,d,vim,python,perl6,scala,vb,elixir,go' : ['.'],
\ 'ruby' : ['.', '::'],
\ 'lua' : ['.', ':']
\ }
let g:ycm_collect_identifiers_from_tag_files = 1
let g:ycm_filetype_blacklist = {
\ 'tagbar' : 1,
\ 'qf' : 1,
\ 'notes' : 1,
\ 'unite' : 1,
\ 'text' : 1,
\ 'vimwiki' : 1,
\ 'pandoc' : 1,
\ 'infolog' : 1,
\ 'mail' : 1
\}
let g:ycm_global_ycm_extra_conf = $VIMFILES . "/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py"

关于.ycm_extra_conf.py的生成,最后我用ultisnips这个插件,自定义snippets,生成.ycm_extra_conf.py的配置,你可以参考

snippets中python.snippets的写法。

ubuntu 32bit 安装ycm流程

下面假设你已经通过vim的vundle之类的插件管理器安装好Ycm了。

编译安装clang编译器到/opt/Clang

sudo update;sudo apt-get upgrade
sudo apt-get install g++ subversion cmake autoconf automake
cd ~;mkdir -p work/clang && cd work/clang
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ../../
mkdir build && cd build
cmake ../llvm
cmake --build .
cmake -DCMAKE_INSTALL_PREFIX=/opt/Clang -P cmake_install.cmake

编译ycm

cd ~/.vim/bundle/YouCompleteMe/
mkdir build
cd build
cmake -G "Unix Makefiles" -DPATH_TO_LLVM_ROOT=/opt/Clang . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp && make ycm_core

其它

在Visual Studio编译gvim和ycmd

ycm的github主页上已经提供了在vs下编译ycmd的官方方法,详细点这里

Windows下编译YouCompleteMe流程的更多相关文章

  1. [转] Windows下编译OpenSSL

    简述 OpenSSL是一个开源的第三方库,它实现了SSL(Secure SocketLayer)和TLS(Transport Layer Security)协议,被广泛企业应用所采用.对于一般的开发人 ...

  2. Windows下编译objective-C

    Windows下编译objective-C 2011-08-31 14:32 630人阅读 评论(0) 收藏 举报 windowscocoa工具objective clibraryxcode   目录 ...

  3. 在Windows下编译FFmpeg详细说明

    MinGW:一个可自由使用和自由发布的Windows特定头文件和使用GNC工具集导入库的集合,允许你生成本地的Windows程序而不需要第三方C运行时 MinGW,即 Minimalist GNU F ...

  4. 如何在WINDOWS下编译BOOST C++库 .

    如何在WINDOWS下编译BOOST C++库 cheungmine 2008-6-25   写出来,怕自己以后忘记了,也为初学者参考.使用VC8.0和boost1.35.0.   1)下载boost ...

  5. 在Windows下编译OpenSSL(VS2005和VC6)

    需要说明的是请一定安装openssl-0.9.8a .  openssl-1.0.0我没有编译成功. 如何在Windows下编译OpenSSL (Vs2005使用Vc8的cl编译器)1.安装Activ ...

  6. windows下编译java源文件的编码错误

    import java.util.Arrays;public class ArrayAsAReference{ public static void main(String[] args) { int ...

  7. Windows下编译SDL

    Windows下编译SDL的理由我就不多说了,无论用VS来编译或调试SDL库都是很方便的.而且SDL源代码中也包含了VC工程,你所要做的只是解压VC工程,进行适当的配置,然后编译.调试. 编译SDL大 ...

  8. Windows下编译安装 FFmpeg

    在Linux/Mac下编译 ffmpeg是非常方便的.但要在 Windows下编译 ffmpeg还真要花点时间.以下就是在 Windowns下编译ffmpeg的步骤: 一.安装Cygwin 在wind ...

  9. windows下编译php7图形库php_ui.dll

    CSDN博客 具有图形化编程才有意思,这几天看到了php ui 图形扩展,只是现在只能下载php 7.1的 本次教程编译php7.2.6的 php ui 要是linux下编译起来比较简单 但是 win ...

随机推荐

  1. apache服务器设置

    服务器目录 目录说明 bin: apache常用的一些命令 cgi-bin:存放一些脚本语言命令 conf:apache配置文件 error:错误记录 htodcs存放站点文件 logs:记录日志 m ...

  2. typeof instanceof 和 obj.constructor

     1.typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果: 'number','boolean','string','function'(函数),'object'(NU ...

  3. CSS 图像拼合技术

    CSS 图像拼合技术 一.图像拼合 图像拼合就是单个图像的集合. 有许多图像的网页可能需要很长的时间来加载和生成多个服务器的请求. 使用图像拼合会降低服务器的请求数量,并节省带宽. 二.图像拼合 - ...

  4. 20144303 《Java程序设计》课程总结

    20144303 <Java程序设计>课程总结 每周读书笔记链接汇总 第一周:http://www.cnblogs.com/20144303sys/p/5248979.html 第二周:h ...

  5. wamp 环境下配置多台虚拟主机

    首先启动wamp,成功之后,单击图标,找到Apache服务器下的 httpd.conf ,直接打开 按下Ctrl+F键,在搜索框中搜索 Virtual hosts, 搜寻结果如下图: 3. 然后打开w ...

  6. .net知识点汇总

    死锁的必要条件?怎么克服? 答:系统的资源不足,进程的推进的顺序不合适,资源分配不当,一个资源每次只能被一个进程使用,一个资源请求资源时,而此时这个资源已阻塞,对已获得资源不放,进程获得资源时,未使用 ...

  7. 分页式存储管理方式AND请求分页式存储管理

    先说下什么是页(页面):就是将用户的程序的的地址空间分成固定大小的区域,称为”页“,或者”页面“ 之后将这些页离散的放进内存中,这样解决了内存的碎片问题 记得老师上课说了下这两个概念不能混,现在区分下 ...

  8. How to implement multiple constructor with different parameters in Scala

    Using scala is just another road, and it just like we fall in love again, but there is some pain you ...

  9. Eclipse 使用中遇到的一些问题!

    解决办法~ 1.先检查本地svn 版本与Eclipse 中svn插件 的区别 2.发现版本一致,没解决,发现如图 发现   svn接口报错 javaHL(JNI) Not Available!@ 所以 ...

  10. ctci1.2

    ;     ; i < len/; i++){         tmp = *(str+i);         *(str+i) = *(str+len--i);         *(str+l ...