-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathmsvs_tools.py
138 lines (106 loc) · 4.59 KB
/
msvs_tools.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/env python
# SPDX-FileCopyrightText: (c) 2020 Western Digital Corporation or its affiliates,
# Arseniy Aharonov <[email protected]>
#
# SPDX-License-Identifier: MIT
import os
from stat_attributes import TOOL_PATH, RESOURCES_DIRECTORY
from services import executeForOutput, toPosixPath, Configuration
from build_tools import BuildTools
NMAKE_ARGUMENTS = "/S /C /NOLOGO /F"
SUPPORTED = {8.0: 2005, 9.0: 2008, 10.0: 2010, 11.0: 2012, 12.0: 2013, 14.0: 2015, 15.0: 2017, 16.0: 2019, 17.0: 2022}
SOLUTION_FORMATS = {8.0: 9.0, 9.0: 10.0, 10.0: 11.0, 11.0: 11.0, 12.0: 12.0, 14.0: 12.0, 15.0: 12.0, 16.0: 12.0, 17.0: 12.0}
class MsvsTools(BuildTools):
def __init__(self, configuration):
"""
:type configuration: Configuration
"""
super(MsvsTools, self).__init__()
self.__toolsPath, self.__versionId = locateTools(configuration.getInt('MSVS_VERSION', None))
self.__devBatchFile = self.__determineDevBatchFile()
self.__nmakeFile = None
@property
def path(self):
return self.__toolsPath
@property
def devBatchFile(self):
return self.__devBatchFile
@property
def nmakeFilePath(self):
if not self.__nmakeFile:
self.__nmakeFile = self.__queryDevEnvironment("where nmake").splitlines()[-1]
return self.__nmakeFile
@property
def versionId(self):
return self.__versionId
@property
def year(self):
return SUPPORTED[self.__versionId]
@property
def solutionFormat(self):
return SOLUTION_FORMATS[self.__versionId]
def getCommandToCompile(self):
return '"{nmake}" {arguments} {{0}}'.format(nmake=self.nmakeFilePath, arguments=NMAKE_ARGUMENTS)
def getAttributes(self):
return dict(MSVS_DEV=toPosixPath(self.__devBatchFile))
def __determineDevBatchFile(self):
filename = os.path.join(self.__toolsPath, "VsDevCmd.bat")
if not os.path.isfile(filename):
filename = os.path.join(self.__toolsPath, "vsvars32.bat")
if not os.path.isfile(filename):
raise VsToolsException(VsToolsException.INCOMPATIBLE_TOOLS)
return filename
def __queryDevEnvironment(self, queryCommandLine):
commandLine = " ".join(['"{0}"'.format(self.devBatchFile), "&&", queryCommandLine])
output = executeForOutput(commandLine)
if not output:
raise VsToolsException(VsToolsException.INCOMPATIBLE_TOOLS)
return output
class VsToolsException(Exception):
"""
Custom exception for STAT VS-Tools
"""
NO_TOOLS_FOUND = "No MSVS Tools were found on this PC."
UNSUPPORTED_TOOLS = "MSVS Tools {0} are not explicitly supported."
INCOMPATIBLE_TOOLS = "MSVS Tools are not operable."
def locateTools(versionYear):
return __findSpecific(versionYear) if versionYear else __findLatest()
def __versionYearToVersionId(versionYear):
for version in SUPPORTED:
if SUPPORTED[version] == versionYear:
return version
else:
raise VsToolsException(VsToolsException.UNSUPPORTED_TOOLS.format(versionYear))
def __queryVswhereForPath(version=None):
cmd = os.path.join(TOOL_PATH, RESOURCES_DIRECTORY, "vswhere.exe")
if not version:
version = executeForOutput(" ".join([cmd, "-legacy", "-property", "installationVersion", "-latest"]))
version = float(version.split(".")[0]) if version else None
searchPattern = '-version [{0},{1})'.format(version, version + 1.0) if version else ''
cmdLine = " ".join([cmd, "-legacy", searchPattern, "-property", "installationPath", "-latest"])
toolsPath = executeForOutput(cmdLine)
if not toolsPath == '':
toolsPath = os.path.join(toolsPath, "Common7", "Tools")
return toolsPath, version
def __findSpecific(versionYear):
versionId = __versionYearToVersionId(versionYear)
toolsPath = __queryOsEnvironmentForPath(versionId)
if not toolsPath:
toolsPath, _ = __queryVswhereForPath(versionId)
if not toolsPath:
raise VsToolsException(VsToolsException.NO_TOOLS_FOUND)
return toolsPath, versionId
def __findLatest():
toolsPath, versionId = __queryVswhereForPath()
if toolsPath:
return toolsPath, versionId
for versionId in sorted(SUPPORTED, reverse=True):
toolsPath = __queryOsEnvironmentForPath(versionId)
if toolsPath:
return toolsPath, versionId
else:
raise VsToolsException(VsToolsException.NO_TOOLS_FOUND)
def __queryOsEnvironmentForPath(version):
return os.environ.get("VS{0}0COMNTOOLS".format(int(version)), '')
if __name__ == '__main__':
pass