The date of The author version note
2021-03-22 dingbin V1.0

This article Outlines the compilation and installation methods of VIM8.2 and Youcompleteme source code under Centos7.

  • Operating date: 2021-03-23.
  • Operating environment: CentOS Linux Release 7.5.1804, 16 cores 20G

The specific operation method is as follows:

Git download the current latest version of Vim source:

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

Compile and install:

Note: After Vim 8.2 is installed, we will continue to install the latest version of YouCompleteme, which uses clangd that requires GCC at least 8, clangd at least 7, and python3.8. Therefore, the preoperations for installing Vim in this article are: All three of the required versions of the components must be installed in advance.

CD Vim # If you want to compile GVim, Vim with a graphical interface, you will need to install X11-enabled libraries and install the following options:  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 --with-python3-command=python3 --with-gnome # --with-python3-command=python3 --with-gnome # --with-python3-command=python3 This requires that Python compile with the --enable-shared option. --with-python3-config-dir The value of --with-python3-config-dir is normally obtained through the python3-config --configdir command. Python (i.e. Python2) and Python 3 can only enable one. Enable python3. Make-j14 make install # Enable python3. Make-j14 make install # Enable python3. Make-j14 make install # Enable python3. Make-j14 make install # Enable python3. The Vundle plugin can be used to download all other Vim plugins, so if you need to manually download the Vundle plugin, you can do the following:  git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

First, configure Vim

Just copy the following into ~/.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进行诊断

The following lines in the above document:

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

Is the four plug-ins that define Vim, which are simply explained as follows:

Plugin 'vundleIM/vundle. vim' -- A Vundle Plugin is a Plugin that downloads other vim plugins, it must be the first one; Plugin 'Flazz/Vim-ColorSchemes' - Plugin for Vim colorscheme using its desert colorscheme Plugin 'GodlyGeek/CSApprox '-- This is an important Plugin to keep the color scheme of Vim in the terminal consistent with the color scheme of GUI/GVim. Plugin 'Valloric/YouCompleteMe' -- As you already know, YouCompleteMe is the famous C family language complete jump Plugin.

Run the following command on Terminal to automatically download and install the above three components as follows:

vim +PluginInstall +qall

You will then install each plug-in in turn, with the following effect:

After the operation is completed, the execution of Vim is shown as follows:

Tell you that the YouCompleteme component was not used because of the reason in the red box. What is the reason?

After countless hours of hard work, finally found that the error is caused by the Python 3 compilation and installation problems. Go back and recompile Python3. Refer to the method in another article, “Build and install the source code for the most recent version of Python 3.9.2 under 2020-03-23 Centos7.” The key points to resolve this error are as follows:

After recompiling and installing the Python library, I went back to the header to recompile VIM82 and finally started Vim. The effect is shown in the figure below. It can be seen that the color scheme in Terminal is basically the same as the color scheme in GUI (GVIM). That’s exactly what we want.

Error: Unable to find the symbol in the Python library. This error is resolved.

This error is because the YCM related code is old and needs to be recompiled. Plugin ‘Valloric/YouCompleteMe’ in ~/. Vimrc

Recompile and install YCM

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

After the compilation is complete, the following prompt is printed to show that the latest version of YCM has deprecated Clang and replaced it with Clangd. The default clang is a binary executable that is downloaded directly from the Internet. Users are better off reinventing their own clangd for their own machine, but it usually works without replacing it.

To do this, open a CPP file and try it out:

So the complete jump is in effect. Press, JD three keys, you can achieve the jump. The specific configuration of the shortcut key map is shown in the following figure. (The previous example of vimrc has been posted for your reference.) The most common key is <leader>jd.

Finally, an example of.ycm_extra_conf.py is given below for your reference.

# 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

Use the same template and copy it to your own C++ project. Make changes to the following red box, and change the header directory for the main include. It’s very convenient.