]>
Commit | Line | Data |
---|---|---|
d14feb6c | 1 | # @file WindowsVsToolChain.py\r |
de4ce46d SB |
2 | # Plugin to configures paths for the VS2017 and VS2019 tool chain\r |
3 | ##\r | |
4 | # This plugin works in conjuncture with the tools_def\r | |
5 | #\r | |
6 | # Copyright (c) Microsoft Corporation\r | |
7 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
8 | ##\r | |
9 | import os\r | |
10 | import logging\r | |
11 | from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin\r | |
12 | import edk2toollib.windows.locate_tools as locate_tools\r | |
13 | from edk2toollib.windows.locate_tools import FindWithVsWhere\r | |
14 | from edk2toolext.environment import shell_environment\r | |
15 | from edk2toolext.environment import version_aggregator\r | |
776ec4ea | 16 | from edk2toollib.utility_functions import GetHostInfo\r |
de4ce46d | 17 | \r |
d14feb6c | 18 | \r |
de4ce46d SB |
19 | class WindowsVsToolChain(IUefiBuildPlugin):\r |
20 | \r | |
21 | def do_post_build(self, thebuilder):\r | |
22 | return 0\r | |
23 | \r | |
24 | def do_pre_build(self, thebuilder):\r | |
25 | self.Logger = logging.getLogger("WindowsVsToolChain")\r | |
3b4ad37e SB |
26 | interesting_keys = ["ExtensionSdkDir", "INCLUDE", "LIB", "LIBPATH", "UniversalCRTSdkDir",\r |
27 | "UCRTVersion", "WindowsLibPath", "WindowsSdkBinPath", "WindowsSdkDir", "WindowsSdkVerBinPath",\r | |
28 | "WindowsSDKVersion", "VCToolsInstallDir", "Path"]\r | |
de4ce46d | 29 | \r |
776ec4ea | 30 | #\r |
de4ce46d SB |
31 | # VS2017 - Follow VS2017 where there is potential for many versions of the tools.\r |
32 | # If a specific version is required then the user must set both env variables:\r | |
d14feb6c SB |
33 | # VS150INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc\r |
34 | # VS150TOOLVER: version number for the VC compiler tools\r | |
35 | # VS2017_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above)\r | |
776ec4ea | 36 | # VS2017_HOST: set the host architecture to use for host tools, and host libs, etc\r |
de4ce46d SB |
37 | if thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2017":\r |
38 | \r | |
776ec4ea SZ |
39 | # check to see if host is configured\r |
40 | # HostType for VS2017 should be (defined in tools_def):\r | |
41 | # x86 == 32bit Intel\r | |
42 | # x64 == 64bit Intel\r | |
43 | # arm == 32bit Arm\r | |
44 | # arm64 == 64bit Arm\r | |
45 | #\r | |
46 | HostType = shell_environment.GetEnvironment().get_shell_var("VS2017_HOST")\r | |
47 | if HostType is not None:\r | |
48 | HostType = HostType.lower()\r | |
49 | self.Logger.info(\r | |
50 | f"HOST TYPE defined by environment. Host Type is {HostType}")\r | |
51 | else:\r | |
52 | HostInfo = GetHostInfo()\r | |
53 | if HostInfo.arch == "x86":\r | |
54 | if HostInfo.bit == "32":\r | |
55 | HostType = "x86"\r | |
56 | elif HostInfo.bit == "64":\r | |
57 | HostType = "x64"\r | |
58 | else:\r | |
59 | raise NotImplementedError()\r | |
60 | \r | |
61 | # VS2017_HOST options are not exactly the same as QueryVcVariables. This translates.\r | |
62 | VC_HOST_ARCH_TRANSLATOR = {\r | |
63 | "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"}\r | |
64 | \r | |
de4ce46d SB |
65 | # check to see if full path already configured\r |
66 | if shell_environment.GetEnvironment().get_shell_var("VS2017_PREFIX") != None:\r | |
67 | self.Logger.info("VS2017_PREFIX is already set.")\r | |
68 | \r | |
69 | else:\r | |
d14feb6c SB |
70 | install_path = self._get_vs_install_path(\r |
71 | "VS2017".lower(), "VS150INSTALLPATH")\r | |
de4ce46d SB |
72 | vc_ver = self._get_vc_version(install_path, "VS150TOOLVER")\r |
73 | \r | |
74 | if install_path is None or vc_ver is None:\r | |
d14feb6c SB |
75 | self.Logger.error(\r |
76 | "Failed to configure environment for VS2017")\r | |
de4ce46d SB |
77 | return -1\r |
78 | \r | |
79 | version_aggregator.GetVersionAggregator().ReportVersion(\r | |
80 | "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO)\r | |
81 | version_aggregator.GetVersionAggregator().ReportVersion(\r | |
82 | "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL)\r | |
83 | \r | |
d14feb6c SB |
84 | # make VS2017_PREFIX to align with tools_def.txt\r |
85 | prefix = os.path.join(install_path, "VC",\r | |
86 | "Tools", "MSVC", vc_ver)\r | |
de4ce46d SB |
87 | prefix = prefix + os.path.sep\r |
88 | shell_environment.GetEnvironment().set_shell_var("VS2017_PREFIX", prefix)\r | |
776ec4ea | 89 | shell_environment.GetEnvironment().set_shell_var("VS2017_HOST", HostType)\r |
de4ce46d | 90 | \r |
3b4ad37e SB |
91 | shell_env = shell_environment.GetEnvironment()\r |
92 | # Use the tools lib to determine the correct values for the vars that interest us.\r | |
93 | vs_vars = locate_tools.QueryVcVariables(\r | |
776ec4ea | 94 | interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType], vs_version="vs2017")\r |
3b4ad37e | 95 | for (k, v) in vs_vars.items():\r |
776ec4ea | 96 | shell_env.set_shell_var(k, v)\r |
3b4ad37e | 97 | \r |
de4ce46d SB |
98 | # now confirm it exists\r |
99 | if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2017_PREFIX")):\r | |
100 | self.Logger.error("Path for VS2017 toolchain is invalid")\r | |
101 | return -2\r | |
102 | \r | |
103 | #\r | |
104 | # VS2019 - Follow VS2019 where there is potential for many versions of the tools.\r | |
105 | # If a specific version is required then the user must set both env variables:\r | |
d14feb6c SB |
106 | # VS160INSTALLPATH: base install path on system to VC install dir. Here you will find the VC folder, etc\r |
107 | # VS160TOOLVER: version number for the VC compiler tools\r | |
108 | # VS2019_PREFIX: path to MSVC compiler folder with trailing slash (can be used instead of two vars above)\r | |
776ec4ea | 109 | # VS2017_HOST: set the host architecture to use for host tools, and host libs, etc\r |
de4ce46d SB |
110 | elif thebuilder.env.GetValue("TOOL_CHAIN_TAG") == "VS2019":\r |
111 | \r | |
776ec4ea SZ |
112 | # check to see if host is configured\r |
113 | # HostType for VS2019 should be (defined in tools_def):\r | |
114 | # x86 == 32bit Intel\r | |
115 | # x64 == 64bit Intel\r | |
116 | # arm == 32bit Arm\r | |
117 | # arm64 == 64bit Arm\r | |
118 | #\r | |
119 | HostType = shell_environment.GetEnvironment().get_shell_var("VS2019_HOST")\r | |
120 | if HostType is not None:\r | |
121 | HostType = HostType.lower()\r | |
122 | self.Logger.info(\r | |
123 | f"HOST TYPE defined by environment. Host Type is {HostType}")\r | |
124 | else:\r | |
125 | HostInfo = GetHostInfo()\r | |
126 | if HostInfo.arch == "x86":\r | |
127 | if HostInfo.bit == "32":\r | |
128 | HostType = "x86"\r | |
129 | elif HostInfo.bit == "64":\r | |
130 | HostType = "x64"\r | |
131 | else:\r | |
132 | raise NotImplementedError()\r | |
133 | \r | |
134 | # VS2019_HOST options are not exactly the same as QueryVcVariables. This translates.\r | |
135 | VC_HOST_ARCH_TRANSLATOR = {\r | |
136 | "x86": "x86", "x64": "AMD64", "arm": "not supported", "arm64": "not supported"}\r | |
137 | \r | |
de4ce46d SB |
138 | # check to see if full path already configured\r |
139 | if shell_environment.GetEnvironment().get_shell_var("VS2019_PREFIX") != None:\r | |
140 | self.Logger.info("VS2019_PREFIX is already set.")\r | |
141 | \r | |
142 | else:\r | |
d14feb6c SB |
143 | install_path = self._get_vs_install_path(\r |
144 | "VS2019".lower(), "VS160INSTALLPATH")\r | |
de4ce46d SB |
145 | vc_ver = self._get_vc_version(install_path, "VS160TOOLVER")\r |
146 | \r | |
147 | if install_path is None or vc_ver is None:\r | |
d14feb6c SB |
148 | self.Logger.error(\r |
149 | "Failed to configure environment for VS2019")\r | |
de4ce46d SB |
150 | return -1\r |
151 | \r | |
152 | version_aggregator.GetVersionAggregator().ReportVersion(\r | |
153 | "Visual Studio Install Path", install_path, version_aggregator.VersionTypes.INFO)\r | |
154 | version_aggregator.GetVersionAggregator().ReportVersion(\r | |
155 | "VC Version", vc_ver, version_aggregator.VersionTypes.TOOL)\r | |
156 | \r | |
d14feb6c SB |
157 | # make VS2019_PREFIX to align with tools_def.txt\r |
158 | prefix = os.path.join(install_path, "VC",\r | |
159 | "Tools", "MSVC", vc_ver)\r | |
de4ce46d SB |
160 | prefix = prefix + os.path.sep\r |
161 | shell_environment.GetEnvironment().set_shell_var("VS2019_PREFIX", prefix)\r | |
776ec4ea | 162 | shell_environment.GetEnvironment().set_shell_var("VS2019_HOST", HostType)\r |
de4ce46d | 163 | \r |
3b4ad37e SB |
164 | shell_env = shell_environment.GetEnvironment()\r |
165 | # Use the tools lib to determine the correct values for the vars that interest us.\r | |
166 | vs_vars = locate_tools.QueryVcVariables(\r | |
776ec4ea | 167 | interesting_keys, VC_HOST_ARCH_TRANSLATOR[HostType], vs_version="vs2019")\r |
3b4ad37e | 168 | for (k, v) in vs_vars.items():\r |
776ec4ea | 169 | shell_env.set_shell_var(k, v)\r |
3b4ad37e | 170 | \r |
de4ce46d SB |
171 | # now confirm it exists\r |
172 | if not os.path.exists(shell_environment.GetEnvironment().get_shell_var("VS2019_PREFIX")):\r | |
173 | self.Logger.error("Path for VS2019 toolchain is invalid")\r | |
174 | return -2\r | |
175 | \r | |
176 | return 0\r | |
177 | \r | |
178 | def _get_vs_install_path(self, vs_version, varname):\r | |
179 | # check if already specified\r | |
02fcfdce JV |
180 | path = None\r |
181 | if varname is not None:\r | |
182 | path = shell_environment.GetEnvironment().get_shell_var(varname)\r | |
183 | \r | |
de4ce46d SB |
184 | if(path is None):\r |
185 | # Not specified...find latest\r | |
02fcfdce JV |
186 | try:\r |
187 | path = FindWithVsWhere(vs_version=vs_version)\r | |
188 | except (EnvironmentError, ValueError, RuntimeError) as e:\r | |
189 | self.Logger.error(str(e))\r | |
190 | return None\r | |
191 | \r | |
192 | if path is not None and os.path.exists(path):\r | |
de4ce46d SB |
193 | self.Logger.debug("Found VS instance for %s", vs_version)\r |
194 | else:\r | |
d14feb6c | 195 | self.Logger.error(\r |
02fcfdce | 196 | f"VsWhere successfully executed, but could not find VS instance for {vs_version}.")\r |
de4ce46d SB |
197 | return path\r |
198 | \r | |
199 | def _get_vc_version(self, path, varname):\r | |
200 | # check if already specified\r | |
201 | vc_ver = shell_environment.GetEnvironment().get_shell_var(varname)\r | |
202 | if (path is None):\r | |
d14feb6c SB |
203 | self.Logger.critical(\r |
204 | "Failed to find Visual Studio tools. Might need to check for VS install")\r | |
de4ce46d SB |
205 | return vc_ver\r |
206 | if(vc_ver is None):\r | |
207 | # Not specified...find latest\r | |
208 | p2 = os.path.join(path, "VC", "Tools", "MSVC")\r | |
209 | if not os.path.isdir(p2):\r | |
210 | self.Logger.critical(\r | |
211 | "Failed to find VC tools. Might need to check for VS install")\r | |
212 | return vc_ver\r | |
213 | vc_ver = os.listdir(p2)[-1].strip() # get last in list\r | |
214 | self.Logger.debug("Found VC Tool version is %s" % vc_ver)\r | |
215 | return vc_ver\r |