2021-03-22dingbinV1.0

本文概要记录Centos7下vim8.2和YouCompleteMe源码编译安装方法。

  • 操作日期: 2021-03-23.
  • 操作环境:CentOS Linux release 7.5.1804, 16核 20G

具体操作方法如下:

git 下载当前最新的vim版本源码:

git clone https://github.com/vim/vim.git

编译安装:

cd vim
#如果想编译gvim,即带图形界面的vim的话,需要安装支持X11的库和安装选项支持如下:
sudo yum install xorg-x11-server-devel libX11-devel libXt-devel gtk2-devel gtk3-devel -y

./configure --prefix=/home/xx/app/vim82    --with-features=huge --enable-fail-if-missing      --enable-python3interp=dynamic --with-python3-command=python3  --with-python3-config-dir=/home/xx/app/pyt
hon39/lib/python3.9/config-3.9-x86_64-linux-gnu     --enable-cscope           --enable-terminal --en
able-autoservername    --enable-multibyte    --enable-xim --enable-fontset --enable-gui=gtk3  --enable-gtk2-check     --enable-gnome-check     --enable-gtk3-check       --enable-motif-check      --enable-athena-check      --enable-nextaw-check     --with-compiledby=dingbin          --with-tclsh=tclsh    --with-x     --with-gnome
# --with-python3-command=python3 要保证which python3能找得到,前文提高,此处要求python编译时必须加入了--enable-shared选项。--with-python3-config-dir 的值一般通过python3-config --configdir 命令获得。python(即python2)和python3只能enable一个。这里一般推荐enable python3.

make -j14
make install
#将目标 vim所在路径加入~/.bashrc 中PATH环境变量中即可。

#下载Vundle插件,通过该插件下载其他所有的Vim插件,因此前提是该插件要手动下载,方式如下:
git clone https://github.com/VundleVim/Vundle.vim.git  ~/.vim/bundle/Vundle.vim 

首次精要配置Vim

拷贝如下内容到~/.vimrc中即可:

set nocompatible              " be iMproved, required
filetype off                  " required
set encoding=utf-8
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'flazz/vim-colorschemes'
Plugin 'godlygeek/csapprox'
Plugin 'Valloric/YouCompleteMe'
call vundle#end()            " required
filetype plugin indent on    " required

set cst
set csto=1
set nocsverb
set csverb

set aw         "set autowrite
set awa        "set autowriteall
set  title

"使打开文件时使光标自动定位到上一次文件被关闭时的准确行
if has("autocmd")
  autocmd BufRead *.txt set tw=78
  au BufReadPost * exe "normal! g`\""
endif

"设置高亮关键字显示
syntax enable
syntax on     "等同于syn on

"禁止在搜索到文件两端时重新搜索
"set nows          "set nowrapscan
set ws

"设置搜索式的匹配字符串高亮显示
set hls    "set hlsearch
"设置搜索式的匹配字符串不高亮显示
"set nohls  "set nohlsearch

"高亮光标所在的当前行set cursorline
set cul         "相反的设置是set nocul
"set nocul


"搜索时在未完全输入完毕要检索的文本时就开始检索
set is       "set incsearch
"搜索时在未完全输入完毕要检索的文本时不开始检索
"set nois       "set noincsearch

"设置以backspace删除自动缩进的,行末回车,行首的字符,很有用
set backspace=indent,eol,start

set ic   "相反是 set noic
"set scs  "相反是 set noscs

"增强模式中的命令行自动完成操作,非常有用
set wildmenu

"设置代码折叠为按语法折叠
"set foldmethod=syntax
"设定折叠方式为手动
set foldmethod=manual
"设置启动vim时不要自动折叠代码
set foldlevel=100
set fdc=1      "set foldcolumn=1

"设置帮助的语言为中文
set helplang=cn
"set helplang=en

"实现C程序的缩进(indent)
set cin

"设置行号
set nu
"set nonu


"设置256色彩
set t_Co=256
"设置配色方案
"colorscheme 简写成colo
"colo colorful
"colo white2
colo  desert
"colo  night
"colo  navajo
"colo  lucius
"colo  blackdust
"colo  freya
"colo  darkslategray
"colo  torte
"colo  fruidle
"colo colorful

"设置编辑模式下状态栏标尺显示
set ru "set ruler
"设置编辑模式下状态栏标尺不显示
"set noru "set noruler

"记录历史的行数
set history=1000

"检测文件类型
"filetype on
filetype plugin on
" 开启文件类型检测 的插件和缩进开
filetype plugin indent on

"设置可以至上一行和下一行的字符按键
set ww=b,s,<,>,[,]  ",h,l

"Alt组合键不映射到菜单上
set winaltkeys=no

"同时支持GBK和UTF-8编码
set fileencodings=utf-8,ucs-bom,gbk,cp936
set fileencoding=utf-8
set encoding=utf-8
"如果在终端环境下使用Vim,需要设置termencoding和终端所使用的编码一致。例如:
set termencoding=utf-8

"自动缩进的时候, 缩进尺寸为 4 个空格。
"即shiftWidth,自动缩进的空格数,用于<<,>>,cindent
set shiftwidth=4

"softtabstop,sts,默认是0,
"执行编辑操作,如插入 <Tab> 或者使用 <BS> 时,把 <Tab> 算作空格的数目
set softtabstop=4     "set sts=4

"编辑时将所有 Tab 替换为空格。
"该选项只在编辑时将 Tab 替换为空格, 如果打开一个已经存在的文件, 并不会将已有的Tab 替换为空格。
"设置了该选项后,如果想输入tab制表符,先输入CTRL-V或CTRL-Q,再输入tab制表符
set et    "相反的设置是set noet
"Tab 宽度为 4 个字符。
set ts=4      "即set tabstop=4

"覆盖文件时不备份
set nobackup
"成功保存文件之前备份
set wb          "set writebackup
"set nowb         "set nowritebackup

"插入括号时,短暂地跳转到匹配的对应括号
set sm            "set showmatch
"短暂跳转到匹配括号的时间
set matchtime=2

"设置魔术
set magic

"允许在有未保存的修改时切换缓冲区,此时的修改由 vim 负责保存
set hidden

"开启新行时使用智能自动缩进
set smartindent
set autoindent
"打开普通文件类型的自动缩进。 该自动缩进不如 cindent 智能, 但它可以为你编辑非 C/C++ 文件提供一定帮助。
set ai

"选中状态下 Ctrl+c 复制
"vmap <C-c> "+y
"注意使用的过程中可以通过e和b键盘以word为单位前进或后退以选择文本
"set keymodel=                    "不使用此功能
set keymodel=startsel,stopsel     "使用此功能

"visual 模式下标签查找(*,#)可用
vnoremap  *  y<ESC>/<C-r>"<CR>
vnoremap  #  y<ESC>?<C-r>"<CR>
nnoremap  g[  :tag <C-R>=expand("<cWORD>")<CR><CR>
vnoremap  g[  <ESC>:tag <C-r>*<CR>

:inoremap ( ()<ESC>i
:inoremap [ []<ESC>i
:inoremap ;; <ESC>A;<CR>

"插入模式下使Ctrl+ h,j,k,l四个键效果等同于移动上、下、左、右方向键
inoremap <C-h> <Left>
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-l> <Right>
"插入模式下使ctrl+ w,b两个键效果等同于普通模式下ctrl+w(前进一个单词),ctrl+b(
"后退一个单词)
inoremap <C-b> <C-o>b
inoremap <C-w> <C-o>w
"插入模式下使ctrl+ f(front),Ctrl+e(end)两个键效果等同于普通模式下<home>,<end>键
inoremap <C-e>  <C-o><End>
inoremap <C-f>  <C-o><Home>
"插入模式下ctrl + d,等效于普通模式下backspace键,
"插入模式下ctrl + x,等效于普通模式下delete键,
inoremap <C-d> <BS>
inoremap <C-x> <Del>

"指定在选择文本时,光标所在位置也属于被选中的范围
set selection=inclusive
"-----------------------------------------------------

"-----------------------------------------------------
"指定不折行。 如果一行太长, 超过屏幕宽度, 则向右边延伸到屏幕外面。如果使用图形界面的话, 指定不折行视觉效果会好得多。
set nowrap
"set wrap

"设置显示时一行的文本宽宽
set tw=80       "set textwidth=80

"添加水平滚动条。 如果你指定了不折行, 那为窗口添加一个水平滚动条就非常有必要了。
set guioptions-=b
"去除vim的GUI版本的toolbar
set guioptions+=T
"去除vim的GUI版本的menubar
set guioptions+=m

"设置断行,当一行的文字太长时,为自动智能在一个单词的中间
"空白处断开到下一行显示,注意:这里的断行只用显示,并不在行末加<EOF>
set lbr           "set linebreak
"打开断行模块对亚洲语言支持。 m 表示允许在两个汉字之间断行, 即使汉字之间没有出现空格。
"B 表示将两行合并为一行的时候, 汉字与汉字之间不要补空格。 该命令支持的更多的选项请参看用户手册。
set fo+=mB

"配置字体
"set fileencoding=gbk
"set guifont=Courier\ 11
"set guifont=Inconsolata\ Medium\ 9  "史上最好看的vim字体
"set guifont=Bitstream_Vera_Sans_Mono:h10:cANSI
"set gfw=幼圆:h10.5:cGB2312
set guifont=Bitstream\ Vera\ Sans\ Mono\ 13

"当右键单击窗口的时候, 弹出快捷菜单
set mousemodel=popup
"不使用选择模式
set selectmode=

"设置屏幕滚动的ctrl+d,ctrl+u的行数,默认是窗口的一半,即半屏
set scr=4

function AddFileTitle()
call append(0," ")
call setline(1,"////////////////////////////////////////////////////////////////////////")
call append(1,"/// @Filename         " . expand("%:p:t"))
call append(2,"/// @Description      ")
call append(3,"/// @Author           DingBin")
call append(4,"/// @Last modified    " . strftime("%Y-%m-%d %H:%M"))
call append(5,"////////////////////////////////////////////////////////////////////////")
endfunction

function AddFileComment()
call append(line(".") -1," ")
call setline(line(".") -1,"////////////////////////////////////////////////////////////////////////")
call append(line(".") - 1,"/// @brief     :")
call append(line(".") - 1,"/// @param     :")
call append(line(".") - 1,"/// @return    :")
call append(line(".") - 1,"////////////////////////////////////////////////////////////////////////")
endfunction

function AddoaArrayFor()
call append(line(".") -1," ")
call setline(line(".") -1,"for (oaUInt4 i = 0; i < .getNumElements(); i++ )")
endfunction

map time :0,50/\/\/\/ *@Last modified/s#@Last modified.*$#\=strftime("@Last modified    %Y-%m-%d %H:%M")#c

map addt :call AddFileTitle()<cr>
map addc :call AddFileComment()<cr>
map addf :call AddoaArrayFor()<cr>

"Mode Settings
let &t_SI.="\e[5 q" "SI = INSERT mode
"let &t_SR.="\e[4 q" "SR = REPLACE mode
let &t_EI.="\e[1 q" "EI = NORMAL mode (ELSE)

"Cursor settings:
"  1 -> blinking block
"  2 -> solid block
"  3 -> blinking underscore
"  4 -> solid underscore
"  5 -> blinking vertical bar
"  6 -> solid vertical bar

"let &t_SI = "\<Esc>]50;CursorShape=1\x7"
"let &t_SR = "\<Esc>]50;CursorShape=2\x7"
"let &t_EI = "\<Esc>]50;CursorShape=0\x7"

"-----------------------------------------------------
"关于状态行配置
"总是显示状态行
set laststatus=2            "set ls=2
"-----  状态栏设置_BEGIN_ -----
"显示当前文件名,文件格式,文件类型
set statusline=%2*%n%m%r%h%w%*\ %F\ %1*[FORMAT=%2*%{&ff}:%{&fenc!=''?&fenc:&enc}%1*]\ [TYPE=%2*%Y%1*]\ [COL=%2*%03v%1*]\ [ROW=%2*%03l%1*/%3*%L(%p%%)%1*]\
"设置状态栏根据不同状态显示不同颜色
function! InsertStatuslineColor(mode)
    if a:mode == 'i'
        hi statusline guibg=peru
    elseif a:mode == 'r'
        hi statusline guibg=blue
    else
        hi statusline guibg=red
    endif
endfunction
au InsertEnter * call InsertStatuslineColor(v:insertmode)
au InsertLeave * hi statusline guibg=lightGreen guifg=black
hi statusline guibg=lightGreen
"状态行颜色
highlight CursorLine cterm=NONE ctermbg=lightGray ctermfg=green
highlight StatusLineNC cterm=NONE ctermbg=lightGray ctermfg=green
"highlight CursorLine cterm=NONE ctermbg=lightGray ctermfg=green guifg=lightGray guibg=green
"highlight StatusLineNC cterm=NONE ctermbg=lightGray ctermfg=green   guibg=lightGray guifg=green
"highlight CursorLine cterm=NONE ctermbg=lightGray ctermfg=green guifg=red guibg=Green
"highlight StatusLineNC cterm=NONE ctermbg=lightGray ctermfg=green guifg=Gray guibg=White
"highlight CursorLine cterm=NONE  guifg=red guibg=Green
"highlight StatusLineNC cterm=NONE guifg=Gray guibg=White
"----- 状态栏设置_END_ -----





"ycm configuration
let g:ycm_confirm_extra_conf = 0
let g:ycm_global_ycm_extra_conf='~/.ycm_extra_conf.py'

let g:ycm_key_list_select_completion = ['<TAB>','<C-n>','<Down>']
let g:ycm_key_list_previous_completion = ['<S-TAB>','<C-p>','<Up>']

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:ycm_collect_identifiers_from_tags_files=1 " 开启 YCM 基于标签引擎
let g:ycm_min_num_of_chars_for_completion=1 " 从第1个键入字符就开始罗列匹配项
let g:ycm_cache_omnifunc=0 " 禁止缓存匹配项,每次都重新生成匹配项

"主动补全
"let g:ycm_key_invoke_completion = '<S-Space>'
let g:ycm_key_invoke_completion = '<c-k>'


let g:ycm_seed_identifiers_with_syntax=1 " 语法关键字补全
"nnoremap <leader>lo :lopen<CR> "open locationlist
"nnoremap <leader>lc :lclose<CR>    "close locationlist

"inoremap <leader><leader> <C-x><C-o>
let g:ycm_max_num_identifier_candidates = 50
let g:ycm_auto_trigger = 1
let g:ycm_error_symbol = '>>'
let g:ycm_warning_symbol = '>'


"YcmCompleter RefactorRename :重命名
"YcmCompleter GoToSymbol

nnoremap <leader>jo :YcmCompleter GoTo<CR> "跳转
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR> "跳转到定义或声明
nnoremap <leader>jf :YcmCompleter GoToDefinition<CR>  "跳转到定义
nnoremap <leader>jl :YcmCompleter GoToDeclaration<CR> "跳转到声明
nnoremap <leader>jt :YcmCompleter GetType<CR> "get类型

nnoremap :js :YcmCompleter GoToSymbol

nmap <leader>ji :YcmCompleter GoToInclude<CR>   "跳转到include、声明或定义
nmap <leader>jm :YcmCompleter GoToImprecise<CR> "跳转到实现
nmap <leader>jr :YcmCompleter GoToReferences<CR> "跳转到引用
nmap <leader>fi :YcmCompleter FixIt<CR> "根据Ycm的建议修复错误

nnoremap <F6> :YcmForceCompileAndDiagnostics<CR> "重新编译和诊断
nmap <F4> :YcmDiags<CR>  "F4进行诊断

上述文件中的如下几行:

Plugin 'VundleVim/Vundle.vim'
Plugin 'flazz/vim-colorschemes'
Plugin 'godlygeek/csapprox'
Plugin 'Valloric/YouCompleteMe'

是定义了vim的4个插件,简单解释如下:

在terminal上运行如下命令自动下载安装上述3个组件如下:

vim +PluginInstall +qall

接下来就会依次安装各插件,效果如下:

操作完成后,执行vim 显示如下:

告知YouCompleteMe组件未能使用成,是因为红色方框中的原因。这到底是啥原因呢?

经过无数时间的苦苦摸索,最终发现这个报错是因为python3编译安装的有问题导致的。返回去重新编译python3吧。参照另一篇文章《2020-03-23 Centos7下当前最高版本python3.9.2源码编译安装方法》中的方法操作即可。解决这个报错关键点是如下:

重新编译安装python库之后,再返回头重新编译vim82,最后启动vim效果如下图,可见它在terminal中的配色方案已经基本高度与其在GUI即gvim中的配色方案一致了。这正是我们想要的。

再次启动,不再报找不到python库符号的错了,说明那个问题解决了。

这个错是因为ycm相关代码比较旧,需要重新编译。如果把~/.vimrc 中这行Plugin 'Valloric/YouCompleteMe' 注释到,vim启动效果如下:

重新编译安装YCM

cd ~/.vim/bundle/YouCompleteMe
git submodule update --init --recursive
./install.py --clangd-completer

编译完成后,打印下图提示,可见最新版本YCM已经弃用了clang而改用了clangd.默认的clang是一个二进制可执行程序,是直接从网上下载好的。 用户最好自己重新编一个适合自己机器的clangd替换之,不过不替换一般也能用。

至此,打开一个CPP文件试试,效果如下:

可见补全跳转生效了。按下、jd 三个键,即可实现跳转。具体详细的跳转快捷键映射详见.vimrc中配置如下图所示(前文.vimrc示例已经贴出来了,供参考。)其中最常用的键就是<leader>jd。

最后再给出一个.ycm_extra_conf.py 的示例如下,供参考。

# This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here'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 <http://unlicense.org/>

from distutils.sysconfig import get_python_inc
import platform
import os
import subprocess
import ycm_core

DIR_OF_THIS_SCRIPT = os.path.abspath( os.path.dirname( __file__ ) )
DIR_OF_THIRD_PARTY = os.path.join( DIR_OF_THIS_SCRIPT, 'third_party' )
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]

# These are the compilation flags that will be used in case there'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 = [
'-Wall',
'-Wextra',
'-Wno-long-long',
'-Wno-variadic-macros',
'-Wthread-safety',
'-Wthread-safety-beta',
'-fexceptions',
'-DNDEBUG',
'-D_GLIBCXX_USE_CXX11_ABI=0', # esearch uses old ABI
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won'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't want that so ALWAYS specify
# a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++17',
# ...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 'c' instead of 'c++'.
'-x', 'c++',
'-I', '/home/dingbin/local/include',
'-I', './common',
'-I', './sword_finger_offer',
'-I','~/app/gcc102/include/c++/10.2.0',
'-I', '/usr/local/include'
]


# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. 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
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''

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


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


def FindCorrespondingSourceFile( filename ):
  if IsHeaderFile( filename ):
    basename = os.path.splitext( filename )[ 0 ]
    for extension in SOURCE_EXTENSIONS:
      replacement_file = basename + extension
      if os.path.exists( replacement_file ):
        return replacement_file
  return filename


def Settings( **kwargs ):
  if kwargs[ 'language' ] == 'cfamily':
    # If the file is a header, try to find the corresponding source file and
    # retrieve its flags from the compilation database if using one. This is
    # necessary since compilation databases don't have entries for header files.
    # In addition, use this source file as the translation unit. This makes it
    # possible to jump from a declaration in the header file to its definition
    # in the corresponding source file.
    filename = FindCorrespondingSourceFile( kwargs[ 'filename' ] )

    if not database:
      return {
        'flags': flags,
        'include_paths_relative_to_dir': DIR_OF_THIS_SCRIPT,
        'override_filename': filename
      }

    compilation_info = database.GetCompilationInfoForFile( filename )
    if not compilation_info.compiler_flags_:
      return {}

    # Bear in mind that compilation_info.compiler_flags_ does NOT return a
    # python list, but a "list-like" StringVec object.
    final_flags = list( compilation_info.compiler_flags_ )

    # NOTE: This is just for YouCompleteMe; it'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'RE NOT 100% SURE YOU NEED IT.
    try:
      final_flags.remove( '-stdlib=libc++' )
    except ValueError:
      pass

    return {
      'flags': final_flags,
      'include_paths_relative_to_dir': compilation_info.compiler_working_dir_,
      'override_filename': filename
    }
  return {}


def GetStandardLibraryIndexInSysPath( sys_path ):
  for path in sys_path:
    if os.path.isfile( os.path.join( path, 'os.py' ) ):
      return sys_path.index( path )
  raise RuntimeError( 'Could not find standard library path in Python path.' )


def PythonSysPath( **kwargs ):
  sys_path = kwargs[ 'sys_path' ]
  for folder in os.listdir( DIR_OF_THIRD_PARTY ):
    if folder == 'python-future':
      folder = os.path.join( folder, 'src' )
      sys_path.insert( GetStandardLibraryIndexInSysPath( sys_path ) + 1,
                       os.path.realpath( os.path.join( DIR_OF_THIRD_PARTY,
                                                       folder ) ) )
      continue

    if folder == 'cregex':
      interpreter_path = kwargs[ 'interpreter_path' ]
      major_version = subprocess.check_output( [
        interpreter_path, '-c', 'import sys; print( sys.version_info[ 0 ] )' ]
      ).rstrip().decode( 'utf8' )
      folder = os.path.join( folder, 'regex_{}'.format( major_version ) )

    sys_path.insert( 0, os.path.realpath( os.path.join( DIR_OF_THIRD_PARTY,
                                                        folder ) ) )
  return sys_path

一般这个文件是随不同的C/C++工程不同而不同,一般用一个千篇一律的模板,拷贝到自己的C++工程下,改动一下下图红框所示的地方,主要include的头文件查找目录改一下,就可以使用了。很方便。

03-06 00:00