Skip to content

Instantly share code, notes, and snippets.

@micbou
Last active June 7, 2018 14:02
Show Gist options
  • Save micbou/6770487343be36a929201f1d2f50a191 to your computer and use it in GitHub Desktop.
Save micbou/6770487343be36a929201f1d2f50a191 to your computer and use it in GitHub Desktop.
YCM extra conf for MSVC
import os
import re
import subprocess
import platform
CL_VERSION_REGEX = re.compile( '\d{2}.\d{2}.\d{5}(.\d{2})?' )
MSVC_BIN_DIR = os.path.join('..', '..', 'VC')
def get_arch_from_python_interpreter():
if platform.architecture()[0] == '64bit':
return 64
return 32
def get_msvc_dir(version):
if version == 12:
return os.path.join(os.environ['VS120COMNTOOLS'], MSVC_BIN_DIR)
if version == 14:
return os.path.join(os.environ['VS140COMNTOOLS'], MSVC_BIN_DIR)
if version == 15:
return get_msvc15_dir()
raise RuntimeError('msvc parameter should be 12, 14, or 15.')
def get_msvc15_dir():
vswhere = os.path.join(os.environ['ProgramFiles(x86)'],
'Microsoft Visual Studio',
'Installer',
'vswhere.exe')
if not os.path.exists(vswhere):
raise RuntimeError('cannot find vswhere. '
'VS 2017 version 15.2 or later is required.')
installation_path = subprocess.check_output(
[vswhere, '-latest', '-property', 'installationPath']
).strip().decode('utf8')
return os.path.join(installation_path, 'VC', 'Auxiliary', 'Build')
def get_vc_mod(arch):
if arch == 64:
return 'x86_amd64'
return 'x86'
def get_cl_version(arch, version):
msvc_dir = get_msvc_dir(version)
vc_vars_script_path = os.path.join(msvc_dir, 'vcvarsall.bat')
cl_output = subprocess.check_output([vc_vars_script_path,
get_vc_mod(arch),
'&',
'cl.exe'],
stderr = subprocess.STDOUT)
for line in cl_output.decode('latin1').splitlines():
cl_version_match = CL_VERSION_REGEX.search(line)
if cl_version_match:
return cl_version_match.group( 0 )
raise RuntimeError('Cannot find MSVC version.')
def get_target_flag(arch, version):
if arch == 64:
return 'x86_64-pc-windows-msvc{0}'.format(get_cl_version(arch, version))
return 'i686-pc-windows-msvc{0}'.format(get_cl_version(version))
def get_include_flags(arch, version):
msvc_dir = get_msvc_dir(version)
vc_vars_script_path = os.path.join(msvc_dir, 'vcvarsall.bat')
set_output = subprocess.check_output([vc_vars_script_path,
get_vc_mod(arch),
'&',
'set'])
for set_line in set_output.decode('latin1').splitlines():
try:
environ_var, environ_value = set_line.split( '=' )
except ValueError:
continue
if environ_var == 'INCLUDE':
return environ_value.split(';')[:-1]
raise RuntimeError('Cannot find include flags.')
def get_msvc_flags(arch, version):
flags = ['-target', get_target_flag(arch, version)]
for flag in get_include_flags(arch, version):
flags.extend(['-isystem', flag])
return flags
def FlagsForFile(filename, **kwargs):
flags = [
'-x',
'c++',
]
arch = get_arch_from_python_interpreter()
version = kwargs['client_data'].get('g:ycm_msvc_version', 14)
flags.extend(get_msvc_flags(arch, version))
return {'flags': flags}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment