|
33 | 33 | LibError,
|
34 | 34 | LinkError,
|
35 | 35 | )
|
36 |
| -from .util import get_platform |
| 36 | +from .util import get_host_platform, get_platform |
37 | 37 |
|
38 | 38 |
|
39 | 39 | def _find_vc2015():
|
@@ -178,17 +178,43 @@ def _find_exe(exe, paths=None):
|
178 | 178 | return exe
|
179 | 179 |
|
180 | 180 |
|
181 |
| -# A map keyed by get_platform() return values to values accepted by |
182 |
| -# 'vcvarsall.bat'. Always cross-compile from x86 to work with the |
183 |
| -# lighter-weight MSVC installs that do not include native 64-bit tools. |
184 |
| -PLAT_TO_VCVARS = { |
| 181 | +_vcvars_names = { |
185 | 182 | 'win32': 'x86',
|
186 |
| - 'win-amd64': 'x86_amd64', |
187 |
| - 'win-arm32': 'x86_arm', |
188 |
| - 'win-arm64': 'x86_arm64', |
| 183 | + 'win-amd64': 'amd64', |
| 184 | + 'win-arm32': 'arm', |
| 185 | + 'win-arm64': 'arm64', |
189 | 186 | }
|
190 | 187 |
|
191 | 188 |
|
| 189 | +def _get_vcvars_spec(host_platform, platform): |
| 190 | + """ |
| 191 | + Given a host platform and platform, determine the spec for vcvarsall. |
| 192 | +
|
| 193 | + Uses the native MSVC host if the host platform would need expensive |
| 194 | + emulation for x86. |
| 195 | +
|
| 196 | + >>> _get_vcvars_spec('win-arm64', 'win32') |
| 197 | + 'arm64_x86' |
| 198 | + >>> _get_vcvars_spec('win-arm64', 'win-amd64') |
| 199 | + 'arm64_amd64' |
| 200 | +
|
| 201 | + Otherwise, always cross-compile from x86 to work with the |
| 202 | + lighter-weight MSVC installs that do not include native 64-bit tools. |
| 203 | +
|
| 204 | + >>> _get_vcvars_spec('win32', 'win32') |
| 205 | + 'x86' |
| 206 | + >>> _get_vcvars_spec('win-arm32', 'win-arm32') |
| 207 | + 'x86_arm' |
| 208 | + >>> _get_vcvars_spec('win-amd64', 'win-arm64') |
| 209 | + 'x86_arm64' |
| 210 | + """ |
| 211 | + if host_platform != 'win-arm64': |
| 212 | + host_platform = 'win32' |
| 213 | + vc_hp = _vcvars_names[host_platform] |
| 214 | + vc_plat = _vcvars_names[platform] |
| 215 | + return vc_hp if vc_hp == vc_plat else f'{vc_hp}_{vc_plat}' |
| 216 | + |
| 217 | + |
192 | 218 | class MSVCCompiler(CCompiler):
|
193 | 219 | """Concrete class that implements an interface to Microsoft Visual C++,
|
194 | 220 | as defined by the CCompiler abstract class."""
|
@@ -242,13 +268,12 @@ def initialize(self, plat_name=None):
|
242 | 268 | if plat_name is None:
|
243 | 269 | plat_name = get_platform()
|
244 | 270 | # sanity check for platforms to prevent obscure errors later.
|
245 |
| - if plat_name not in PLAT_TO_VCVARS: |
| 271 | + if plat_name not in _vcvars_names: |
246 | 272 | raise DistutilsPlatformError(
|
247 |
| - f"--plat-name must be one of {tuple(PLAT_TO_VCVARS)}" |
| 273 | + f"--plat-name must be one of {tuple(_vcvars_names)}" |
248 | 274 | )
|
249 | 275 |
|
250 |
| - # Get the vcvarsall.bat spec for the requested platform. |
251 |
| - plat_spec = PLAT_TO_VCVARS[plat_name] |
| 276 | + plat_spec = _get_vcvars_spec(get_host_platform(), get_platform()) |
252 | 277 |
|
253 | 278 | vc_env = _get_vc_env(plat_spec)
|
254 | 279 | if not vc_env:
|
|
0 commit comments