Last active
June 7, 2018 14:02
-
-
Save micbou/6770487343be36a929201f1d2f50a191 to your computer and use it in GitHub Desktop.
YCM extra conf for MSVC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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