From a34397a2951db73b24aae168cb4108791f9a3d69 Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sun, 25 Aug 2024 20:18:22 +0200 Subject: [PATCH 01/11] Use arm64 MSVC on arm64 Windows --- distutils/_msvccompiler.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index b0322410..2f098a44 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -33,7 +33,7 @@ LibError, LinkError, ) -from .util import get_platform +from .util import get_platform, get_host_platform def _find_vc2015(): @@ -250,6 +250,10 @@ def initialize(self, plat_name=None): # Get the vcvarsall.bat spec for the requested platform. plat_spec = PLAT_TO_VCVARS[plat_name] + # Use the native MSVC host if the host platform would need expensive emulation for x86. + if plat_name == get_host_platform() and plat_spec == 'x86_arm64': + plat_spec = plat_spec[4:] + vc_env = _get_vc_env(plat_spec) if not vc_env: raise DistutilsPlatformError( From 9c37a8ad7398c435cc2a84c1f7532f2cb9ad599c Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 26 Aug 2024 18:49:53 +0200 Subject: [PATCH 02/11] conditionally construct PLAT_TO_VCVARS --- distutils/_msvccompiler.py | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index 2f098a44..a66e5d5b 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -179,14 +179,25 @@ def _find_exe(exe, paths=None): # A map keyed by get_platform() return values to values accepted by -# 'vcvarsall.bat'. Always cross-compile from x86 to work with the -# lighter-weight MSVC installs that do not include native 64-bit tools. -PLAT_TO_VCVARS = { - 'win32': 'x86', - 'win-amd64': 'x86_amd64', - 'win-arm32': 'x86_arm', - 'win-arm64': 'x86_arm64', -} +# 'vcvarsall.bat'. +if get_platform() == get_host_platform() and get_host_platform() == "win-arm64": + # Use the native MSVC host if the host platform would need expensive + # emulation for x86. + PLAT_TO_VCVARS = { + 'win32': 'arm64_x86', + 'win-amd64': 'arm64_amd64', + 'win-arm32': 'arm64_arm', + 'win-arm64': 'arm64', + } +else: + # Always cross-compile from x86 to work with the lighter-weight MSVC + # installs that do not include native 64-bit tools. + PLAT_TO_VCVARS = { + 'win32': 'x86', + 'win-amd64': 'x86_amd64', + 'win-arm32': 'x86_arm', + 'win-arm64': 'x86_arm64', + } class MSVCCompiler(CCompiler): @@ -250,10 +261,6 @@ def initialize(self, plat_name=None): # Get the vcvarsall.bat spec for the requested platform. plat_spec = PLAT_TO_VCVARS[plat_name] - # Use the native MSVC host if the host platform would need expensive emulation for x86. - if plat_name == get_host_platform() and plat_spec == 'x86_arm64': - plat_spec = plat_spec[4:] - vc_env = _get_vc_env(plat_spec) if not vc_env: raise DistutilsPlatformError( From b55552e658789e714d572805ade271c91c94425b Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 26 Aug 2024 18:56:09 +0200 Subject: [PATCH 03/11] function-ify --- distutils/_msvccompiler.py | 45 +++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index a66e5d5b..28131a01 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -178,26 +178,31 @@ def _find_exe(exe, paths=None): return exe -# A map keyed by get_platform() return values to values accepted by -# 'vcvarsall.bat'. -if get_platform() == get_host_platform() and get_host_platform() == "win-arm64": - # Use the native MSVC host if the host platform would need expensive - # emulation for x86. - PLAT_TO_VCVARS = { - 'win32': 'arm64_x86', - 'win-amd64': 'arm64_amd64', - 'win-arm32': 'arm64_arm', - 'win-arm64': 'arm64', - } -else: - # Always cross-compile from x86 to work with the lighter-weight MSVC - # installs that do not include native 64-bit tools. - PLAT_TO_VCVARS = { - 'win32': 'x86', - 'win-amd64': 'x86_amd64', - 'win-arm32': 'x86_arm', - 'win-arm64': 'x86_arm64', - } +def _get_plat_to_vcvars(): + # A map keyed by get_platform() return values to values accepted by + # 'vcvarsall.bat'. + host_platform = get_host_platform() + if host_platform == get_platform() and get_host_platform() == "win-arm64": + # Use the native MSVC host if the host platform would need expensive + # emulation for x86. + return { + 'win32': 'arm64_x86', + 'win-amd64': 'arm64_amd64', + 'win-arm32': 'arm64_arm', + 'win-arm64': 'arm64', + } + else: + # Always cross-compile from x86 to work with the lighter-weight MSVC + # installs that do not include native 64-bit tools. + return { + 'win32': 'x86', + 'win-amd64': 'x86_amd64', + 'win-arm32': 'x86_arm', + 'win-arm64': 'x86_arm64', + } + + +PLAT_TO_VCVARS = _get_plat_to_vcvars() class MSVCCompiler(CCompiler): From a46c2401187c80b8647d3f3d049bed96c88b054d Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 26 Aug 2024 18:57:54 +0200 Subject: [PATCH 04/11] nit --- distutils/_msvccompiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index 28131a01..6f2d8cee 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -182,7 +182,7 @@ def _get_plat_to_vcvars(): # A map keyed by get_platform() return values to values accepted by # 'vcvarsall.bat'. host_platform = get_host_platform() - if host_platform == get_platform() and get_host_platform() == "win-arm64": + if host_platform == get_platform() and host_platform == "win-arm64": # Use the native MSVC host if the host platform would need expensive # emulation for x86. return { From 71dd4afed8c56ae99d49410054d8fb6a12ad6ecd Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 26 Aug 2024 19:00:14 +0200 Subject: [PATCH 05/11] python supports comparison chains --- distutils/_msvccompiler.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index 6f2d8cee..5a588890 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -181,8 +181,7 @@ def _find_exe(exe, paths=None): def _get_plat_to_vcvars(): # A map keyed by get_platform() return values to values accepted by # 'vcvarsall.bat'. - host_platform = get_host_platform() - if host_platform == get_platform() and host_platform == "win-arm64": + if get_platform() == get_host_platform() == "win-arm64": # Use the native MSVC host if the host platform would need expensive # emulation for x86. return { From c3c0f06e53e6571c579586855c0330c678e6985f Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 26 Aug 2024 20:22:06 +0200 Subject: [PATCH 06/11] apply feedback --- distutils/_msvccompiler.py | 42 ++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index 5a588890..e7a17684 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -178,30 +178,24 @@ def _find_exe(exe, paths=None): return exe -def _get_plat_to_vcvars(): - # A map keyed by get_platform() return values to values accepted by - # 'vcvarsall.bat'. - if get_platform() == get_host_platform() == "win-arm64": - # Use the native MSVC host if the host platform would need expensive - # emulation for x86. - return { - 'win32': 'arm64_x86', - 'win-amd64': 'arm64_amd64', - 'win-arm32': 'arm64_arm', - 'win-arm64': 'arm64', - } - else: - # Always cross-compile from x86 to work with the lighter-weight MSVC - # installs that do not include native 64-bit tools. - return { - 'win32': 'x86', - 'win-amd64': 'x86_amd64', - 'win-arm32': 'x86_arm', - 'win-arm64': 'x86_arm64', - } - - -PLAT_TO_VCVARS = _get_plat_to_vcvars() +if get_host_platform() == "win-arm64": + # Use the native MSVC host if the host platform would need expensive + # emulation for x86. + PLAT_TO_VCVARS = { + 'win32': 'arm64_x86', + 'win-amd64': 'arm64_amd64', + 'win-arm32': 'arm64_arm', + 'win-arm64': 'arm64', + } +else: + # Always cross-compile from x86 to work with the lighter-weight MSVC + # installs that do not include native 64-bit tools. + PLAT_TO_VCVARS = { + 'win32': 'x86', + 'win-amd64': 'x86_amd64', + 'win-arm32': 'x86_arm', + 'win-arm64': 'x86_arm64', + } class MSVCCompiler(CCompiler): From b413f919ce8b14fb14e6516475a2976ed4f33362 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Aug 2024 16:16:15 -0400 Subject: [PATCH 07/11] Sort imports --- distutils/_msvccompiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index e7a17684..faebb44b 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -33,7 +33,7 @@ LibError, LinkError, ) -from .util import get_platform, get_host_platform +from .util import get_host_platform, get_platform def _find_vc2015(): From 334a7fca2fcf216fdabf1adacc0c6ad04947daec Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Mon, 26 Aug 2024 22:31:15 +0200 Subject: [PATCH 08/11] restore the lost comment --- distutils/_msvccompiler.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index faebb44b..115a28f7 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -178,6 +178,8 @@ def _find_exe(exe, paths=None): return exe +# A map keyed by get_platform() return values to values accepted by +# 'vcvarsall.bat'. if get_host_platform() == "win-arm64": # Use the native MSVC host if the host platform would need expensive # emulation for x86. From 93a4dc928319e26466e2772f510374b57bc09bab Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Aug 2024 16:50:01 -0400 Subject: [PATCH 09/11] Define the variable in one place. --- distutils/_msvccompiler.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index faebb44b..cb10bd56 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -178,24 +178,28 @@ def _find_exe(exe, paths=None): return exe -if get_host_platform() == "win-arm64": - # Use the native MSVC host if the host platform would need expensive - # emulation for x86. - PLAT_TO_VCVARS = { +PLAT_TO_VCVARS = ( + { + # Use the native MSVC host if the host platform would need expensive + # emulation for x86. 'win32': 'arm64_x86', 'win-amd64': 'arm64_amd64', 'win-arm32': 'arm64_arm', 'win-arm64': 'arm64', } -else: - # Always cross-compile from x86 to work with the lighter-weight MSVC - # installs that do not include native 64-bit tools. - PLAT_TO_VCVARS = { + if get_host_platform() == "win-arm64" + else { + # Always cross-compile from x86 to work with the lighter-weight MSVC + # installs that do not include native 64-bit tools. 'win32': 'x86', 'win-amd64': 'x86_amd64', 'win-arm32': 'x86_arm', 'win-arm64': 'x86_arm64', } +) +""" +Maps get_platform() results to values expected by vcvarsall.bat. +""" class MSVCCompiler(CCompiler): From dde3ad3dfa5c04e1bf85c907a42b2efc0cb088f3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Aug 2024 17:10:16 -0400 Subject: [PATCH 10/11] Extract logic around the mappings into a function to compute the spec. --- distutils/_msvccompiler.py | 64 ++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index cb10bd56..9052f265 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -178,28 +178,41 @@ def _find_exe(exe, paths=None): return exe -PLAT_TO_VCVARS = ( - { - # Use the native MSVC host if the host platform would need expensive - # emulation for x86. - 'win32': 'arm64_x86', - 'win-amd64': 'arm64_amd64', - 'win-arm32': 'arm64_arm', - 'win-arm64': 'arm64', - } - if get_host_platform() == "win-arm64" - else { - # Always cross-compile from x86 to work with the lighter-weight MSVC - # installs that do not include native 64-bit tools. - 'win32': 'x86', - 'win-amd64': 'x86_amd64', - 'win-arm32': 'x86_arm', - 'win-arm64': 'x86_arm64', - } -) -""" -Maps get_platform() results to values expected by vcvarsall.bat. -""" +_vcvars_names = { + 'win32': 'x86', + 'win-amd64': 'amd64', + 'win-arm32': 'arm', + 'win-arm64': 'arm64', +} + + +def _get_vcvars_spec(host_platform, platform): + """ + Given a host platform and platform, determine the spec for vcvarsall. + + Uses the native MSVC host if the host platform would need expensive + emulation for x86. + + >>> _get_vcvars_spec('win-arm64', 'win32') + 'arm64_x86' + >>> _get_vcvars_spec('win-arm64', 'win-amd64') + 'arm64_amd64' + + Always cross-compile from x86 to work with the lighter-weight MSVC + installs that do not include native 64-bit tools. + + >>> _get_vcvars_spec('win32', 'win32') + 'x86' + >>> _get_vcvars_spec('win-arm32', 'win-arm32') + 'x86_arm' + >>> _get_vcvars_spec('win-amd64', 'win-arm64') + 'x86_arm64' + """ + if host_platform != 'win-arm64': + host_platform = 'win32' + vc_hp = _vcvars_names[host_platform] + vc_plat = _vcvars_names[platform] + return vc_hp if vc_hp == vc_plat else f'{vc_hp}_{vc_plat}' class MSVCCompiler(CCompiler): @@ -255,13 +268,12 @@ def initialize(self, plat_name=None): if plat_name is None: plat_name = get_platform() # sanity check for platforms to prevent obscure errors later. - if plat_name not in PLAT_TO_VCVARS: + if plat_name not in _vcvars_names: raise DistutilsPlatformError( - f"--plat-name must be one of {tuple(PLAT_TO_VCVARS)}" + f"--plat-name must be one of {tuple(_vcvars_names)}" ) - # Get the vcvarsall.bat spec for the requested platform. - plat_spec = PLAT_TO_VCVARS[plat_name] + plat_spec = _get_vcvars_spec(get_host_platform(), get_platform()) vc_env = _get_vc_env(plat_spec) if not vc_env: From 761162d7eb116db5d855f0ffda62768e1f35c42c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Aug 2024 17:16:34 -0400 Subject: [PATCH 11/11] Tweak docstring --- distutils/_msvccompiler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/distutils/_msvccompiler.py b/distutils/_msvccompiler.py index 9052f265..7400fbaa 100644 --- a/distutils/_msvccompiler.py +++ b/distutils/_msvccompiler.py @@ -198,8 +198,8 @@ def _get_vcvars_spec(host_platform, platform): >>> _get_vcvars_spec('win-arm64', 'win-amd64') 'arm64_amd64' - Always cross-compile from x86 to work with the lighter-weight MSVC - installs that do not include native 64-bit tools. + Otherwise, always cross-compile from x86 to work with the + lighter-weight MSVC installs that do not include native 64-bit tools. >>> _get_vcvars_spec('win32', 'win32') 'x86'