From 7082c53ff6bc7454e4cd306123b2de8516a56c2d Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Tue, 14 Mar 2023 10:25:52 -0400
Subject: Fix #4312 and Windows on ARM64 support.
Changes for #4312:
* The installed VCS list is cached but has an indirect dependency on the value of the environment's TARGET_ARCH during construction. For the initial construction, force the env['TARGET_ARCH'] to be undefined and then restore the value after construction.
* Protect against an empty regular expression list when iteratively removing default tool sequences.
Changes for ARM64 host support:
* Add configuration data structures to support ARM64 hosts and ARM64 native tools for VS2022. Update the tests for the renamed data structures.
* Evaluate the PROCESSOR_ARCHITECTURE value from the windows registry before evaluating the os environment values for host architecture determination on Windows.
* Set VSCMD_SKIP_SENDTELEMETRY=1 for arm32 process on arm64 host if not already defined to prevent powershell dll not found error.
* The os environment variable value for PROCESSOR_ARCHITECTURE is AMD64 for Windows ARM64 hosts when using a python built for AMD64.
Related MSVC changes for #4312 and ARM64 hosts:
* Check that cl.exe exists in find_batch_file for VS6 to VS2015. Move the sdk batch file query code to its own function. Query for the sdk batch file only when all of the vc script host/target combinations have been exhausted and a valid script has not been found.
* Hoist the query for the vc product directory outside the current vc script host/target loop. Catch the internal exceptions as before.
* Clear the sdk batch file path for VCForPython as the sdk batch files do not appear to be updated during installation and do not point to the VCForPython installation location.
* Move the sdk batch file determination to its own function. Defer evaluation of candidate sdk batch files until after all host/target combinations of the vc scripts have been evaluated.
* Always check that cl.exe is found in vc script environment path.
Miscellaneous:
* Reorder and group exception definitions in Tool\MSCommon\vc.py by external exceptions and internal exceptions.
* Adjust debug messages.
* Convert the floating point msvc version to an integer version number for product range comparisons (e.g., 14.3 is 143). Adjust the comparison ranges accordingly.
---
SCons/Platform/win32.py | 20 +-
SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py | 29 +-
SCons/Tool/MSCommon/common.py | 36 ++-
SCons/Tool/MSCommon/vc.py | 429 ++++++++++++++++++++++------
SCons/Tool/MSCommon/vcTests.py | 48 +++-
5 files changed, 440 insertions(+), 122 deletions(-)
diff --git a/SCons/Platform/win32.py b/SCons/Platform/win32.py
index 990794f..e815913 100644
--- a/SCons/Platform/win32.py
+++ b/SCons/Platform/win32.py
@@ -299,6 +299,11 @@ SupportedArchitectureList = [
),
ArchDefinition(
+ 'arm64',
+ ['ARM64', 'aarch64', 'AARCH64', 'AArch64'],
+ ),
+
+ ArchDefinition(
'ia64',
['IA64'],
),
@@ -315,10 +320,21 @@ def get_architecture(arch=None):
"""Returns the definition for the specified architecture string.
If no string is specified, the system default is returned (as defined
- by the PROCESSOR_ARCHITEW6432 or PROCESSOR_ARCHITECTURE environment
- variables).
+ by the registry PROCESSOR_ARCHITECTURE value, PROCESSOR_ARCHITEW6432
+ environment variable, PROCESSOR_ARCHITECTURE environment variable, or
+ the platform machine).
"""
if arch is None:
+ if SCons.Util.can_read_reg:
+ try:
+ k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
+ 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
+ val, tok = SCons.Util.RegQueryValueEx(k, 'PROCESSOR_ARCHITECTURE')
+ except SCons.Util.RegError:
+ val = ''
+ if val and val in SupportedArchitectureMap:
+ arch = val
+ if arch is None:
arch = os.environ.get('PROCESSOR_ARCHITEW6432')
if not arch:
arch = os.environ.get('PROCESSOR_ARCHITECTURE')
diff --git a/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py b/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py
index e1c05bc..7d0f0e4 100644
--- a/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py
+++ b/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py
@@ -188,19 +188,22 @@ def register_iserror(env, tool, msvc_exists_func):
debug('msvc default:check tools:nchar=%d, tools=%s', tools_nchar, tools)
# iteratively remove default tool sequences (longest to shortest)
- re_nchar_min, re_tools_min = _Data.default_tools_re_list[-1]
- if tools_nchar >= re_nchar_min and re_tools_min.search(tools):
- # minimum characters satisfied and minimum pattern exists
- for re_nchar, re_default_tool in _Data.default_tools_re_list:
- if tools_nchar < re_nchar:
- # not enough characters for pattern
- continue
- tools = re_default_tool.sub('', tools).strip(_Data.separator)
- tools_nchar = len(tools)
- debug('msvc default:check tools:nchar=%d, tools=%s', tools_nchar, tools)
- if tools_nchar < re_nchar_min or not re_tools_min.search(tools):
- # less than minimum characters or minimum pattern does not exist
- break
+ if not _Data.default_tools_re_list:
+ debug('default_tools_re_list=%s', _Data.default_tools_re_list)
+ else:
+ re_nchar_min, re_tools_min = _Data.default_tools_re_list[-1]
+ if tools_nchar >= re_nchar_min and re_tools_min.search(tools):
+ # minimum characters satisfied and minimum pattern exists
+ for re_nchar, re_default_tool in _Data.default_tools_re_list:
+ if tools_nchar < re_nchar:
+ # not enough characters for pattern
+ continue
+ tools = re_default_tool.sub('', tools).strip(_Data.separator)
+ tools_nchar = len(tools)
+ debug('msvc default:check tools:nchar=%d, tools=%s', tools_nchar, tools)
+ if tools_nchar < re_nchar_min or not re_tools_min.search(tools):
+ # less than minimum characters or minimum pattern does not exist
+ break
# construct non-default list(s) tools set
tools_set = {msvc_tool for msvc_tool in tools.split(_Data.separator) if msvc_tool}
diff --git a/SCons/Tool/MSCommon/common.py b/SCons/Tool/MSCommon/common.py
index ad4c827..df8e6c8 100644
--- a/SCons/Tool/MSCommon/common.py
+++ b/SCons/Tool/MSCommon/common.py
@@ -209,6 +209,17 @@ def has_reg(value):
# Functions for fetching environment variable settings from batch files.
+def _force_vscmd_skip_sendtelemetry(env):
+
+ if 'VSCMD_SKIP_SENDTELEMETRY' in env['ENV']:
+ return False
+
+ env['ENV']['VSCMD_SKIP_SENDTELEMETRY'] = '1'
+ debug("force env['ENV']['VSCMD_SKIP_SENDTELEMETRY']=%s", env['ENV']['VSCMD_SKIP_SENDTELEMETRY'])
+
+ return True
+
+
def normalize_env(env, keys, force=False):
"""Given a dictionary representing a shell environment, add the variables
from os.environ needed for the processing of .bat files; the keys are
@@ -257,7 +268,7 @@ def normalize_env(env, keys, force=False):
return normenv
-def get_output(vcbat, args=None, env=None):
+def get_output(vcbat, args=None, env=None, skip_sendtelemetry=False):
"""Parse the output of given bat file, with given args."""
if env is None:
@@ -296,20 +307,23 @@ def get_output(vcbat, args=None, env=None):
]
env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False)
+ if skip_sendtelemetry:
+ _force_vscmd_skip_sendtelemetry(env)
+
if args:
debug("Calling '%s %s'", vcbat, args)
- popen = SCons.Action._subproc(env,
- '"%s" %s & set' % (vcbat, args),
- stdin='devnull',
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ cmd_str = '"%s" %s & set' % (vcbat, args)
else:
debug("Calling '%s'", vcbat)
- popen = SCons.Action._subproc(env,
- '"%s" & set' % vcbat,
- stdin='devnull',
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ cmd_str = '"%s" & set' % vcbat
+
+ popen = SCons.Action._subproc(
+ env,
+ cmd_str,
+ stdin='devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
# Use the .stdout and .stderr attributes directly because the
# .communicate() method uses the threading module on Windows
diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py
index 7871940..64b4cde 100644
--- a/SCons/Tool/MSCommon/vc.py
+++ b/SCons/Tool/MSCommon/vc.py
@@ -43,6 +43,7 @@ import SCons.compat
import subprocess
import os
import platform
+import sysconfig
from pathlib import Path
from string import digits as string_digits
from subprocess import PIPE
@@ -69,8 +70,7 @@ from .MSVC.Exceptions import (
MSVCToolsetVersionNotFound,
)
-class UnsupportedVersion(VisualCException):
- pass
+# external exceptions
class MSVCUnsupportedHostArch(VisualCException):
pass
@@ -78,21 +78,35 @@ class MSVCUnsupportedHostArch(VisualCException):
class MSVCUnsupportedTargetArch(VisualCException):
pass
-class MissingConfiguration(VisualCException):
+class MSVCScriptNotFound(MSVCUserError):
pass
-class NoVersionFound(VisualCException):
+class MSVCUseSettingsError(MSVCUserError):
pass
-class BatchFileExecutionError(VisualCException):
+# internal exceptions
+
+class UnsupportedVersion(VisualCException):
pass
-class MSVCScriptNotFound(MSVCUserError):
+class MissingConfiguration(VisualCException):
pass
-class MSVCUseSettingsError(MSVCUserError):
+class BatchFileExecutionError(VisualCException):
pass
+# undefined object for dict.get() in case key exists and value is None
+UNDEFINED = object()
+
+# powershell error sending telemetry for arm32 process on arm64 host (VS2019+):
+# True: force VSCMD_SKIP_SENDTELEMETRY=1 (if necessary)
+# False: do nothing
+_ARM32_ON_ARM64_SKIP_SENDTELEMETRY = True
+
+# MSVC 9.0 preferred query order:
+# True: VCForPython, VisualStudio
+# FAlse: VisualStudio, VCForPython
+_VC90_Prefer_VCForPython = True
# Dict to 'canonalize' the arch
_ARCH_TO_CANONICAL = {
@@ -282,7 +296,9 @@ def _host_target_config_factory(*, label, host_all_hosts, host_all_targets, host
# The cl path fragment under the toolset version folder is the second value of
# the stored tuple.
-_GE2017_HOST_TARGET_BATCHFILE_CLPATHCOMPS = {
+# 14.3 (VS2022) and later
+
+_GE2022_HOST_TARGET_BATCHFILE_CLPATHCOMPS = {
('amd64', 'amd64') : ('vcvars64.bat', ('bin', 'Hostx64', 'x64')),
('amd64', 'x86') : ('vcvarsamd64_x86.bat', ('bin', 'Hostx64', 'x86')),
@@ -294,11 +310,66 @@ _GE2017_HOST_TARGET_BATCHFILE_CLPATHCOMPS = {
('x86', 'arm') : ('vcvarsx86_arm.bat', ('bin', 'Hostx86', 'arm')),
('x86', 'arm64') : ('vcvarsx86_arm64.bat', ('bin', 'Hostx86', 'arm64')),
+ ('arm64', 'amd64') : ('vcvarsarm64_amd64.bat', ('bin', 'Hostarm64', 'arm64_amd64')),
+ ('arm64', 'x86') : ('vcvarsarm64_x86.bat', ('bin', 'Hostarm64', 'arm64_x86')),
+ ('arm64', 'arm') : ('vcvarsarm64_arm.bat', ('bin', 'Hostarm64', 'arm64_arm')),
+ ('arm64', 'arm64') : ('vcvarsarm64.bat', ('bin', 'Hostarm64', 'arm64')),
+
}
-_GE2017_HOST_TARGET_CFG = _host_target_config_factory(
+_GE2022_HOST_TARGET_CFG = _host_target_config_factory(
- label = 'GE2017',
+ label = 'GE2022',
+
+ host_all_hosts = OrderedDict([
+ ('amd64', ['amd64', 'x86']),
+ ('x86', ['x86']),
+ ('arm64', ['arm64', 'amd64', 'x86']),
+ ('arm', ['x86']),
+ ]),
+
+ host_all_targets = {
+ 'amd64': ['amd64', 'x86', 'arm64', 'arm'],
+ 'x86': ['x86', 'amd64', 'arm', 'arm64'],
+ 'arm64': ['arm64', 'amd64', 'arm', 'x86'],
+ 'arm': [],
+ },
+
+ host_def_targets = {
+ 'amd64': ['amd64', 'x86'],
+ 'x86': ['x86'],
+ 'arm64': ['arm64', 'amd64', 'arm', 'x86'],
+ 'arm': ['arm'],
+ },
+
+)
+
+# debug("_GE2022_HOST_TARGET_CFG: %s", _GE2022_HOST_TARGET_CFG)
+
+# 14.2 (VS2019) to 14.1 (VS2017)
+
+_LE2019_HOST_TARGET_BATCHFILE_CLPATHCOMPS = {
+
+ ('amd64', 'amd64') : ('vcvars64.bat', ('bin', 'Hostx64', 'x64')),
+ ('amd64', 'x86') : ('vcvarsamd64_x86.bat', ('bin', 'Hostx64', 'x86')),
+ ('amd64', 'arm') : ('vcvarsamd64_arm.bat', ('bin', 'Hostx64', 'arm')),
+ ('amd64', 'arm64') : ('vcvarsamd64_arm64.bat', ('bin', 'Hostx64', 'arm64')),
+
+ ('x86', 'amd64') : ('vcvarsx86_amd64.bat', ('bin', 'Hostx86', 'x64')),
+ ('x86', 'x86') : ('vcvars32.bat', ('bin', 'Hostx86', 'x86')),
+ ('x86', 'arm') : ('vcvarsx86_arm.bat', ('bin', 'Hostx86', 'arm')),
+ ('x86', 'arm64') : ('vcvarsx86_arm64.bat', ('bin', 'Hostx86', 'arm64')),
+
+ ('arm64', 'amd64') : ('vcvars64.bat', ('bin', 'Hostx64', 'x64')),
+ ('arm64', 'x86') : ('vcvarsamd64_x86.bat', ('bin', 'Hostx64', 'x86')),
+ ('arm64', 'arm') : ('vcvarsamd64_arm.bat', ('bin', 'Hostx64', 'arm')),
+ ('arm64', 'arm64') : ('vcvarsamd64_arm64.bat', ('bin', 'Hostx64', 'arm64')),
+
+}
+
+_LE2019_HOST_TARGET_CFG = _host_target_config_factory(
+
+ label = 'LE2019',
host_all_hosts = OrderedDict([
('amd64', ['amd64', 'x86']),
@@ -310,20 +381,20 @@ _GE2017_HOST_TARGET_CFG = _host_target_config_factory(
host_all_targets = {
'amd64': ['amd64', 'x86', 'arm64', 'arm'],
'x86': ['x86', 'amd64', 'arm', 'arm64'],
- 'arm64': [],
+ 'arm64': ['arm64', 'amd64', 'arm', 'x86'],
'arm': [],
},
host_def_targets = {
'amd64': ['amd64', 'x86'],
'x86': ['x86'],
- 'arm64': ['arm64', 'arm'],
+ 'arm64': ['arm64', 'amd64', 'arm', 'x86'],
'arm': ['arm'],
},
)
-# debug("_GE2017_HOST_TARGET_CFG: %s", _GE2017_HOST_TARGET_CFG)
+# debug("_LE2019_HOST_TARGET_CFG: %s", _LE2019_HOST_TARGET_CFG)
# 14.0 (VS2015) to 8.0 (VS2005)
@@ -345,6 +416,10 @@ _LE2015_HOST_TARGET_BATCHARG_CLPATHCOMPS = {
('x86', 'arm') : ('x86_arm', ('bin', 'x86_arm')),
('x86', 'ia64') : ('x86_ia64', ('bin', 'x86_ia64')),
+ ('arm64', 'amd64') : ('amd64', ('bin', 'amd64')),
+ ('arm64', 'x86') : ('amd64_x86', ('bin', 'amd64_x86')),
+ ('arm64', 'arm') : ('amd64_arm', ('bin', 'amd64_arm')),
+
('arm', 'arm') : ('arm', ('bin', 'arm')),
('ia64', 'ia64') : ('ia64', ('bin', 'ia64')),
@@ -357,6 +432,7 @@ _LE2015_HOST_TARGET_CFG = _host_target_config_factory(
host_all_hosts = OrderedDict([
('amd64', ['amd64', 'x86']),
('x86', ['x86']),
+ ('arm64', ['amd64', 'x86']),
('arm', ['arm']),
('ia64', ['ia64']),
]),
@@ -364,6 +440,7 @@ _LE2015_HOST_TARGET_CFG = _host_target_config_factory(
host_all_targets = {
'amd64': ['amd64', 'x86', 'arm'],
'x86': ['x86', 'amd64', 'arm', 'ia64'],
+ 'arm64': ['amd64', 'x86', 'arm'],
'arm': ['arm'],
'ia64': ['ia64'],
},
@@ -371,6 +448,7 @@ _LE2015_HOST_TARGET_CFG = _host_target_config_factory(
host_def_targets = {
'amd64': ['amd64', 'x86'],
'x86': ['x86'],
+ 'arm64': ['amd64', 'arm', 'x86'],
'arm': ['arm'],
'ia64': ['ia64'],
},
@@ -391,16 +469,19 @@ _LE2003_HOST_TARGET_CFG = _host_target_config_factory(
host_all_hosts = OrderedDict([
('amd64', ['x86']),
('x86', ['x86']),
+ ('arm64', ['x86']),
]),
host_all_targets = {
'amd64': ['x86'],
'x86': ['x86'],
+ 'arm64': ['x86'],
},
host_def_targets = {
'amd64': ['x86'],
'x86': ['x86'],
+ 'arm64': ['x86'],
},
)
@@ -444,28 +525,54 @@ def get_host_platform(host_platform):
return host
+_native_host_architecture = None
+
+def get_native_host_architecture():
+ """Return the native host architecture."""
+ global _native_host_architecture
+
+ if _native_host_architecture is None:
+
+ try:
+ arch = common.read_reg(
+ r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE'
+ )
+ except OSError:
+ arch = None
+
+ if not arch:
+ arch = platform.machine()
+
+ _native_host_architecture = arch
+
+ return _native_host_architecture
+
_native_host_platform = None
def get_native_host_platform():
global _native_host_platform
if _native_host_platform is None:
-
- _native_host_platform = get_host_platform(platform.machine())
+ arch = get_native_host_architecture()
+ _native_host_platform = get_host_platform(arch)
return _native_host_platform
def get_host_target(env, msvc_version, all_host_targets=False):
vernum = float(get_msvc_version_numeric(msvc_version))
-
- if vernum > 14:
- # 14.1 (VS2017) and later
- host_target_cfg = _GE2017_HOST_TARGET_CFG
- elif 14 >= vernum >= 8:
+ vernum_int = int(vernum * 10)
+
+ if vernum_int >= 143:
+ # 14.3 (VS2022) and later
+ host_target_cfg = _GE2022_HOST_TARGET_CFG
+ elif 143 > vernum_int >= 141:
+ # 14.2 (VS2019) to 14.1 (VS2017)
+ host_target_cfg = _LE2019_HOST_TARGET_CFG
+ elif 141 > vernum_int >= 80:
# 14.0 (VS2015) to 8.0 (VS2005)
host_target_cfg = _LE2015_HOST_TARGET_CFG
- else:
+ else: # 80 > vernum_int
# 7.1 (VS2003) and earlier
host_target_cfg = _LE2003_HOST_TARGET_CFG
@@ -520,6 +627,53 @@ def get_host_target(env, msvc_version, all_host_targets=False):
return host_platform, target_platform, host_target_list
+_arm32_process_arm64_host = None
+
+def is_arm32_process_arm64_host():
+ global _arm32_process_arm64_host
+
+ if _arm32_process_arm64_host is None:
+
+ host = get_native_host_architecture()
+ host = _ARCH_TO_CANONICAL.get(host.lower(),'')
+ host_isarm64 = host == 'arm64'
+
+ process = sysconfig.get_platform()
+ process_isarm32 = process == 'win-arm32'
+
+ _arm32_process_arm64_host = host_isarm64 and process_isarm32
+
+ return _arm32_process_arm64_host
+
+_check_skip_sendtelemetry = None
+
+def _skip_sendtelemetry(env):
+ global _check_skip_sendtelemetry
+
+ if _check_skip_sendtelemetry is None:
+
+ if _ARM32_ON_ARM64_SKIP_SENDTELEMETRY and is_arm32_process_arm64_host():
+ _check_skip_sendtelemetry = True
+ else:
+ _check_skip_sendtelemetry = False
+
+ if not _check_skip_sendtelemetry:
+ return False
+
+ msvc_version = env.get('MSVC_VERSION') if env else None
+ if not msvc_version:
+ msvc_version = msvc_default_version(env)
+
+ if not msvc_version:
+ return False
+
+ vernum = float(get_msvc_version_numeric(msvc_version))
+ if vernum < 14.2: # VS2019
+ return False
+
+ # arm32 process, arm64 host, VS2019+
+ return True
+
# If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the
# MSVC_VERSION documentation in Tool/msvc.xml.
_VCVER = [
@@ -589,6 +743,9 @@ _VCVER_TO_PRODUCT_DIR = {
'9.0': [
(SCons.Util.HKEY_CURRENT_USER, r'Microsoft\DevDiv\VCForPython\9.0\installdir',),
(SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',),
+ ] if _VC90_Prefer_VCForPython else [
+ (SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',),
+ (SCons.Util.HKEY_CURRENT_USER, r'Microsoft\DevDiv\VCForPython\9.0\installdir',),
],
'9.0Exp': [
(SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir'),
@@ -763,7 +920,7 @@ def find_vc_pdir(env, msvc_version):
raise MissingConfiguration("registry dir {} not found on the filesystem".format(comps))
return None
-def find_batch_file(env, msvc_version, host_arch, target_arch):
+def find_batch_file(msvc_version, host_arch, target_arch, pdir):
"""
Find the location of the batch script which should set up the compiler
for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
@@ -772,52 +929,73 @@ def find_batch_file(env, msvc_version, host_arch, target_arch):
scripts named with a host_target pair that calls vcvarsall.bat properly,
so use that and return an empty argument.
"""
- pdir = find_vc_pdir(env, msvc_version)
- if pdir is None:
- raise NoVersionFound("No version of Visual Studio found")
- debug('looking in %s', pdir)
# filter out e.g. "Exp" from the version name
- msvc_ver_numeric = get_msvc_version_numeric(msvc_version)
- vernum = float(msvc_ver_numeric)
+ vernum = float(get_msvc_version_numeric(msvc_version))
+ vernum_int = int(vernum * 10)
+
+ sdk_pdir = pdir
arg = ''
vcdir = None
+ clexe = None
- if vernum > 14:
- # 14.1 (VS2017) and later
+ if vernum_int >= 143:
+ # 14.3 (VS2022) and later
+ batfiledir = os.path.join(pdir, "Auxiliary", "Build")
+ batfile, _ = _GE2022_HOST_TARGET_BATCHFILE_CLPATHCOMPS[(host_arch, target_arch)]
+ batfilename = os.path.join(batfiledir, batfile)
+ vcdir = pdir
+ elif 143 > vernum_int >= 141:
+ # 14.2 (VS2019) to 14.1 (VS2017)
batfiledir = os.path.join(pdir, "Auxiliary", "Build")
- batfile, _ = _GE2017_HOST_TARGET_BATCHFILE_CLPATHCOMPS[(host_arch, target_arch)]
+ batfile, _ = _LE2019_HOST_TARGET_BATCHFILE_CLPATHCOMPS[(host_arch, target_arch)]
batfilename = os.path.join(batfiledir, batfile)
vcdir = pdir
- elif 14 >= vernum >= 8:
+ elif 141 > vernum_int >= 80:
# 14.0 (VS2015) to 8.0 (VS2005)
- arg, _ = _LE2015_HOST_TARGET_BATCHARG_CLPATHCOMPS[(host_arch, target_arch)]
+ arg, cl_path_comps = _LE2015_HOST_TARGET_BATCHARG_CLPATHCOMPS[(host_arch, target_arch)]
batfilename = os.path.join(pdir, "vcvarsall.bat")
if msvc_version == '9.0' and not os.path.exists(batfilename):
# Visual C++ for Python batch file is in installdir (root) not productdir (vc)
batfilename = os.path.normpath(os.path.join(pdir, os.pardir, "vcvarsall.bat"))
- else:
+ # Visual C++ for Python sdk batch files do not point to the VCForPython installation
+ sdk_pdir = None
+ clexe = os.path.join(pdir, *cl_path_comps, _CL_EXE_NAME)
+ else: # 80 > vernum_int
# 7.1 (VS2003) and earlier
pdir = os.path.join(pdir, "Bin")
batfilename = os.path.join(pdir, "vcvars32.bat")
+ clexe = os.path.join(pdir, _CL_EXE_NAME)
if not os.path.exists(batfilename):
- debug("Not found: %s", batfilename)
+ debug("batch file not found: %s", batfilename)
batfilename = None
+ if clexe and not os.path.exists(clexe):
+ debug("cl.exe not found: %s", clexe)
+ batfilename = None
+
+ return batfilename, arg, vcdir, sdk_pdir
+
+def find_batch_file_sdk(host_arch, target_arch, sdk_pdir):
+ """
+ Find the location of the sdk batch script which should set up the compiler
+ for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
+ """
+
installed_sdks = get_installed_sdks()
for _sdk in installed_sdks:
sdk_bat_file = _sdk.get_sdk_vc_script(host_arch, target_arch)
if not sdk_bat_file:
- debug("batch file not found:%s", _sdk)
+ debug("sdk batch file not found:%s", _sdk)
else:
- sdk_bat_file_path = os.path.join(pdir, sdk_bat_file)
+ sdk_bat_file_path = os.path.join(sdk_pdir, sdk_bat_file)
if os.path.exists(sdk_bat_file_path):
debug('sdk_bat_file_path:%s', sdk_bat_file_path)
- return batfilename, arg, vcdir, sdk_bat_file_path
+ return sdk_bat_file_path
- return batfilename, arg, vcdir, None
+ return None
__INSTALLED_VCS_RUN = None
_VC_TOOLS_VERSION_FILE_PATH = ['Auxiliary', 'Build', 'Microsoft.VCToolsVersion.default.txt']
@@ -852,9 +1030,10 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
host_platform, target_platform, host_target_list = platforms
vernum = float(get_msvc_version_numeric(msvc_version))
+ vernum_int = int(vernum * 10)
# make sure the cl.exe exists meaning the tool is installed
- if vernum > 14:
+ if vernum_int >= 141:
# 14.1 (VS2017) and later
# 2017 and newer allowed multiple versions of the VC toolset to be
# installed at the same time. This changes the layout.
@@ -871,11 +1050,18 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
debug('failed to find MSVC version in %s', default_toolset_file)
return False
+ if vernum_int >= 143:
+ # 14.3 (VS2022) and later
+ host_target_batchfile_clpathcomps = _GE2022_HOST_TARGET_BATCHFILE_CLPATHCOMPS
+ else:
+ # 14.2 (VS2019) to 14.1 (VS2017)
+ host_target_batchfile_clpathcomps = _LE2019_HOST_TARGET_BATCHFILE_CLPATHCOMPS
+
for host_platform, target_platform in host_target_list:
debug('host platform %s, target platform %s for version %s', host_platform, target_platform, msvc_version)
- batchfile_clpathcomps = _GE2017_HOST_TARGET_BATCHFILE_CLPATHCOMPS.get((host_platform, target_platform), None)
+ batchfile_clpathcomps = host_target_batchfile_clpathcomps.get((host_platform, target_platform), None)
if batchfile_clpathcomps is None:
debug('unsupported host/target platform combo: (%s,%s)', host_platform, target_platform)
continue
@@ -888,7 +1074,7 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
debug('found %s!', _CL_EXE_NAME)
return True
- elif 14 >= vernum >= 8:
+ elif 141 > vernum_int >= 80:
# 14.0 (VS2015) to 8.0 (VS2005)
for host_platform, target_platform in host_target_list:
@@ -908,7 +1094,7 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
debug('found %s', _CL_EXE_NAME)
return True
- elif 8 > vernum >= 6:
+ elif 80 > vernum_int >= 60:
# 7.1 (VS2003) to 6.0 (VS6)
# quick check for vc_dir/bin and vc_dir/ before walk
@@ -928,7 +1114,7 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
return False
else:
- # version not support return false
+ # version not supported return false
debug('unsupported MSVC version: %s', str(vernum))
return False
@@ -939,6 +1125,13 @@ def get_installed_vcs(env=None):
if __INSTALLED_VCS_RUN is not None:
return __INSTALLED_VCS_RUN
+ save_target_arch = env.get('TARGET_ARCH', UNDEFINED) if env else None
+ force_target = env and save_target_arch and save_target_arch != UNDEFINED
+
+ if force_target:
+ del env['TARGET_ARCH']
+ debug("delete env['TARGET_ARCH']")
+
installed_versions = []
for ver in _VCVER:
@@ -960,7 +1153,12 @@ def get_installed_vcs(env=None):
except VisualCException as e:
debug('did not find VC %s: caught exception %s', ver, str(e))
+ if force_target:
+ env['TARGET_ARCH'] = save_target_arch
+ debug("restore env['TARGET_ARCH']=%s", save_target_arch)
+
__INSTALLED_VCS_RUN = installed_versions
+ debug("__INSTALLED_VCS_RUN=%s", __INSTALLED_VCS_RUN)
return __INSTALLED_VCS_RUN
def reset_installed_vcs():
@@ -982,6 +1180,19 @@ def get_installed_vcs_components(env=None):
msvc_version_component_defs = [MSVC.Util.msvc_version_components(vcver) for vcver in vcs]
return msvc_version_component_defs
+def _check_cl_exists_in_script_env(data):
+ """Find cl.exe in the script environment path."""
+ cl_path = None
+ if data and 'PATH' in data:
+ for p in data['PATH']:
+ cl_exe = os.path.join(p, _CL_EXE_NAME)
+ if os.path.exists(cl_exe):
+ cl_path = cl_exe
+ break
+ have_cl = True if cl_path else False
+ debug('have_cl: %s, cl_path: %s', have_cl, cl_path)
+ return have_cl, cl_path
+
# Running these batch files isn't cheap: most of the time spent in
# msvs.generate() is due to vcvars*.bat. In a build that uses "tools='msvs'"
# in multiple environments, for example:
@@ -1027,7 +1238,8 @@ def script_env(env, script, args=None):
cache_data = None
if cache_data is None:
- stdout = common.get_output(script, args)
+ skip_sendtelemetry = _skip_sendtelemetry(env)
+ stdout = common.get_output(script, args, skip_sendtelemetry=skip_sendtelemetry)
cache_data = common.parse_output(stdout)
# debug(stdout)
@@ -1044,12 +1256,7 @@ def script_env(env, script, args=None):
if script_errlog:
script_errmsg = '\n'.join(script_errlog)
- have_cl = False
- if cache_data and 'PATH' in cache_data:
- for p in cache_data['PATH']:
- if os.path.exists(os.path.join(p, _CL_EXE_NAME)):
- have_cl = True
- break
+ have_cl, _ = _check_cl_exists_in_script_env(cache_data)
debug(
'script=%s args=%s have_cl=%s, errors=%s',
@@ -1130,6 +1337,18 @@ def msvc_find_valid_batch_script(env, version):
get it right.
"""
+ # Find the product directory
+ pdir = None
+ try:
+ pdir = find_vc_pdir(env, version)
+ except UnsupportedVersion:
+ # Unsupported msvc version (raise MSVCArgumentError?)
+ pass
+ except MissingConfiguration:
+ # Found version, directory missing
+ pass
+ debug('product directory: version=%s, pdir=%s', version, pdir)
+
# Find the host, target, and all candidate (host, target) platform combinations:
platforms = get_host_target(env, version)
debug("host_platform %s, target_platform %s host_target_list %s", *platforms)
@@ -1137,48 +1356,81 @@ def msvc_find_valid_batch_script(env, version):
d = None
version_installed = False
- for host_arch, target_arch, in host_target_list:
- # Set to current arch.
- env['TARGET_ARCH'] = target_arch
- arg = ''
- # Try to locate a batch file for this host/target platform combo
- try:
- (vc_script, arg, vc_dir, sdk_script) = find_batch_file(env, version, host_arch, target_arch)
- debug('vc_script:%s vc_script_arg:%s sdk_script:%s', vc_script, arg, sdk_script)
- version_installed = True
- except VisualCException as e:
- msg = str(e)
- debug('Caught exception while looking for batch file (%s)', msg)
- version_installed = False
- continue
+ if pdir:
+
+ # Query all candidate sdk (host, target, sdk_pdir) after vc_script pass if necessary
+ sdk_queries = []
+
+ for host_arch, target_arch, in host_target_list:
+ # Set to current arch.
+ env['TARGET_ARCH'] = target_arch
+ arg = ''
+
+ # Try to locate a batch file for this host/target platform combo
+ try:
+ (vc_script, arg, vc_dir, sdk_pdir) = find_batch_file(version, host_arch, target_arch, pdir)
+ debug('vc_script:%s vc_script_arg:%s', vc_script, arg)
+ version_installed = True
+ except VisualCException as e:
+ msg = str(e)
+ debug('Caught exception while looking for batch file (%s)', msg)
+ version_installed = False
+ continue
+
+ # Save (host, target, sdk_pdir) platform combo for sdk queries
+ if sdk_pdir:
+ sdk_query = (host_arch, target_arch, sdk_pdir)
+ if sdk_query not in sdk_queries:
+ debug('save sdk_query host=%s, target=%s, sdk_pdir=%s', host_arch, target_arch, sdk_pdir)
+ sdk_queries.append(sdk_query)
+
+ if not vc_script:
+ continue
- # Try to use the located batch file for this host/target platform combo
- debug('use_script 2 %s, args:%s', repr(vc_script), arg)
- found = None
- if vc_script:
+ # Try to use the located batch file for this host/target platform combo
arg = MSVC.ScriptArguments.msvc_script_arguments(env, version, vc_dir, arg)
+ debug('trying vc_script:%s, vc_script_args:%s', repr(vc_script), arg)
try:
d = script_env(env, vc_script, args=arg)
- found = vc_script
except BatchFileExecutionError as e:
- debug('use_script 3: failed running VC script %s: %s: Error:%s', repr(vc_script), arg, e)
- vc_script=None
+ debug('failed vc_script:%s, vc_script_args:%s, error:%s', repr(vc_script), arg, e)
+ vc_script = None
continue
- if not vc_script and sdk_script:
- debug('use_script 4: trying sdk script: %s', sdk_script)
- try:
- d = script_env(env, sdk_script)
- found = sdk_script
- except BatchFileExecutionError as e:
- debug('use_script 5: failed running SDK script %s: Error:%s', repr(sdk_script), e)
+
+ have_cl, _ = _check_cl_exists_in_script_env(d)
+ if not have_cl:
+ debug('skip cl.exe not found vc_script:%s, vc_script_args:%s', repr(vc_script), arg)
continue
- elif not vc_script and not sdk_script:
- debug('use_script 6: Neither VC script nor SDK script found')
- continue
- debug("Found a working script/target: %s/%s", repr(found), arg)
- break # We've found a working target_platform, so stop looking
+ debug("Found a working script/target: %s/%s", repr(vc_script), arg)
+ break # We've found a working target_platform, so stop looking
+
+ if not d:
+ for host_arch, target_arch, sdk_pdir in sdk_queries:
+ # Set to current arch.
+ env['TARGET_ARCH'] = target_arch
+
+ sdk_script = find_batch_file_sdk(host_arch, target_arch, sdk_pdir)
+ if not sdk_script:
+ continue
+
+ # Try to use the sdk batch file for this (host, target, sdk_pdir) combo
+ debug('trying sdk_script:%s', repr(sdk_script))
+ try:
+ d = script_env(env, sdk_script)
+ version_installed = True
+ except BatchFileExecutionError as e:
+ debug('failed sdk_script:%s, error=%s', repr(sdk_script), e)
+ continue
+
+ have_cl, _ = _check_cl_exists_in_script_env(d)
+ if not have_cl:
+ debug('skip cl.exe not found sdk_script:%s', repr(sdk_script))
+ continue
+
+ debug("Found a working script/target: %s", repr(sdk_script))
+ break # We've found a working script, so stop looking
# If we cannot find a viable installed compiler, reset the TARGET_ARCH
# To it's initial value
@@ -1206,8 +1458,6 @@ def msvc_find_valid_batch_script(env, version):
return d
-_UNDEFINED = object()
-
def get_use_script_use_settings(env):
# use_script use_settings return values action
@@ -1217,9 +1467,9 @@ def get_use_script_use_settings(env):
# None (documentation) or evaluates False (code): bypass detection
# need to distinguish between undefined and None
- use_script = env.get('MSVC_USE_SCRIPT', _UNDEFINED)
+ use_script = env.get('MSVC_USE_SCRIPT', UNDEFINED)
- if use_script != _UNDEFINED:
+ if use_script != UNDEFINED:
# use_script defined, use_settings ignored (not type checked)
return use_script, None
@@ -1293,8 +1543,7 @@ def msvc_exists(env=None, version=None):
rval = len(vcs) > 0
else:
rval = version in vcs
- if not rval:
- debug('version=%s, return=%s', repr(version), rval)
+ debug('version=%s, return=%s', repr(version), rval)
return rval
def msvc_setup_env_user(env=None):
diff --git a/SCons/Tool/MSCommon/vcTests.py b/SCons/Tool/MSCommon/vcTests.py
index 3e37def..a8b139a 100644
--- a/SCons/Tool/MSCommon/vcTests.py
+++ b/SCons/Tool/MSCommon/vcTests.py
@@ -132,12 +132,48 @@ class MSVcTestCase(unittest.TestCase):
print("Failed trying to write :%s :%s" % (tools_version_file, e))
- # Now walk all the valid combinations of host/target for 14.1 (VS2017) and later
- vc_ge2017_list = SCons.Tool.MSCommon.vc._GE2017_HOST_TARGET_CFG.all_pairs
+ # Test 14.3 (VS2022) and later
+ vc_ge2022_list = SCons.Tool.MSCommon.vc._GE2022_HOST_TARGET_CFG.all_pairs
- for host, target in vc_ge2017_list:
- batfile, clpathcomps = SCons.Tool.MSCommon.vc._GE2017_HOST_TARGET_BATCHFILE_CLPATHCOMPS[(host,target)]
- # print("GT 14 Got: (%s, %s) -> (%s, %s)"%(host,target,batfile,clpathcomps))
+ for host, target in vc_ge2022_list:
+ batfile, clpathcomps = SCons.Tool.MSCommon.vc._GE2022_HOST_TARGET_BATCHFILE_CLPATHCOMPS[(host,target)]
+ # print("GE 14.3 Got: (%s, %s) -> (%s, %s)"%(host,target,batfile,clpathcomps))
+
+ env={'TARGET_ARCH':target, 'HOST_ARCH':host}
+ path = os.path.join('.', 'Tools', 'MSVC', MS_TOOLS_VERSION, *clpathcomps)
+ MSVcTestCase._createDummyCl(path, add_bin=False)
+ result=check(env, '.', '14.3')
+ # print("for:(%s, %s) got :%s"%(host, target, result))
+ self.assertTrue(result, "Checking host: %s target: %s" % (host, target))
+
+ # Now test bogus value for HOST_ARCH
+ env={'TARGET_ARCH':'x86', 'HOST_ARCH':'GARBAGE'}
+ try:
+ result=check(env, '.', '14.3')
+ # print("for:%s got :%s"%(env, result))
+ self.assertFalse(result, "Did not fail with bogus HOST_ARCH host: %s target: %s" % (env['HOST_ARCH'], env['TARGET_ARCH']))
+ except MSVCUnsupportedHostArch:
+ pass
+ else:
+ self.fail('Did not fail when HOST_ARCH specified as: %s' % env['HOST_ARCH'])
+
+ # Now test bogus value for TARGET_ARCH
+ env={'TARGET_ARCH':'GARBAGE', 'HOST_ARCH':'x86'}
+ try:
+ result=check(env, '.', '14.3')
+ # print("for:%s got :%s"%(env, result))
+ self.assertFalse(result, "Did not fail with bogus TARGET_ARCH host: %s target: %s" % (env['HOST_ARCH'], env['TARGET_ARCH']))
+ except MSVCUnsupportedTargetArch:
+ pass
+ else:
+ self.fail('Did not fail when TARGET_ARCH specified as: %s' % env['TARGET_ARCH'])
+
+ # Test 14.2 (VS2019) to 14.1 (VS2017) versions
+ vc_le2019_list = SCons.Tool.MSCommon.vc._LE2019_HOST_TARGET_CFG.all_pairs
+
+ for host, target in vc_le2019_list:
+ batfile, clpathcomps = SCons.Tool.MSCommon.vc._LE2019_HOST_TARGET_BATCHFILE_CLPATHCOMPS[(host,target)]
+ # print("LE 14.2 Got: (%s, %s) -> (%s, %s)"%(host,target,batfile,clpathcomps))
env={'TARGET_ARCH':target, 'HOST_ARCH':host}
path = os.path.join('.', 'Tools', 'MSVC', MS_TOOLS_VERSION, *clpathcomps)
@@ -173,7 +209,7 @@ class MSVcTestCase(unittest.TestCase):
for host, target in vc_le2015_list:
batarg, clpathcomps = SCons.Tool.MSCommon.vc._LE2015_HOST_TARGET_BATCHARG_CLPATHCOMPS[(host, target)]
- # print("LE 14 Got: (%s, %s) -> (%s, %s)"%(host,target,batarg,clpathcomps))
+ # print("LE 14.0 Got: (%s, %s) -> (%s, %s)"%(host,target,batarg,clpathcomps))
env={'TARGET_ARCH':target, 'HOST_ARCH':host}
path = os.path.join('.', *clpathcomps)
MSVcTestCase._createDummyCl(path, add_bin=False)
--
cgit v0.12
From d352fa50095102ab1f81adb720e905967fd38b3d Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Wed, 15 Mar 2023 09:19:19 -0400
Subject: Refactor MSCommon/common.py logging filter class due to SConfTests
module reset when debug logging is enabled.
---
SCons/Tool/MSCommon/common.py | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)
diff --git a/SCons/Tool/MSCommon/common.py b/SCons/Tool/MSCommon/common.py
index df8e6c8..dca43bf 100644
--- a/SCons/Tool/MSCommon/common.py
+++ b/SCons/Tool/MSCommon/common.py
@@ -46,30 +46,31 @@ LOGFILE = os.environ.get('SCONS_MSCOMMON_DEBUG')
if LOGFILE:
import logging
- modulelist = (
- # root module and parent/root module
- 'MSCommon', 'Tool',
- # python library and below: correct iff scons does not have a lib folder
- 'lib',
- # scons modules
- 'SCons', 'test', 'scons'
- )
+ class _Debug_Filter(logging.Filter):
+ # custom filter for module relative filename
- def get_relative_filename(filename, module_list):
- if not filename:
+ modulelist = (
+ # root module and parent/root module
+ 'MSCommon', 'Tool',
+ # python library and below: correct iff scons does not have a lib folder
+ 'lib',
+ # scons modules
+ 'SCons', 'test', 'scons'
+ )
+
+ def get_relative_filename(self, filename, module_list):
+ if not filename:
+ return filename
+ for module in module_list:
+ try:
+ ind = filename.rindex(module)
+ return filename[ind:]
+ except ValueError:
+ pass
return filename
- for module in module_list:
- try:
- ind = filename.rindex(module)
- return filename[ind:]
- except ValueError:
- pass
- return filename
- class _Debug_Filter(logging.Filter):
- # custom filter for module relative filename
def filter(self, record):
- relfilename = get_relative_filename(record.pathname, modulelist)
+ relfilename = self.get_relative_filename(record.pathname, self.modulelist)
relfilename = relfilename.replace('\\', '/')
record.relfilename = relfilename
return True
--
cgit v0.12
From 4eca02072d7a39ef158d4d6aca1ec8845965568f Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Sat, 18 Mar 2023 10:48:48 -0400
Subject: Update CHANGES.txt [skip ci]
---
CHANGES.txt | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/CHANGES.txt b/CHANGES.txt
index 8bb3c21..82e6d0a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,31 @@ NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer suppo
RELEASE VERSION/DATE TO BE FILLED IN LATER
+ From Joseph Brill:
+ - Fix issue #4312: the cached installed msvc list had an indirect dependency
+ on the target architecture in the environment dictionary. The first call
+ to construct the installed msvc list now forces the target architecture to be
+ undefined, constructs the installed msvc list, and then restores the original
+ target architecture.
+ Note: an indirect dependency on the VSWHERE construction variable in the
+ environment remains.
+ - Fix issue #4312: explicitly guard against an empty regular expression list
+ when msvc is not installed.
+ - When trying to find a valid msvc batch file, check that the compiler executable
+ (cl.exe) exists for VS6 to VS2015 to avoid executing the msvc batch file. Always
+ check that the compiler executable is found on the msvc script environment path
+ after running the msvc batch file. Only use the sdk batch files when all of the
+ msvc script host/target combinations have been exhausted and a valid script was
+ not found.
+ - Add ARM64 host configurations for windows and msvc.
+ Note: VS2013 and earlier has not been tested on ARM64.
+ - If necessary, automatically define VSCMD_SKIP_SENDTELEMETRY for VS2019 and later
+ on ARM64 hosts when using an arm32 build of python to prevent a powershell dll
+ not found error pop-up window.
+ - Fix an issue where test SConfTests.py would fail when mscommon debugging
+ was enabled. The mscommon debug filter class registered with the logging
+ module was refactored.
+
From Michał Górny:
- Remove the redundant `wheel` dependency from `pyproject.toml`,
as it is added automatically by the setuptools PEP517 backend.
--
cgit v0.12
From 26dbadd82605e797b1151e04ba945b176ab1dfab Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Sun, 19 Mar 2023 09:32:08 -0400
Subject: Add arm64 to the MSVS supported architectures list for VS2017 and
later to be consistent with the current documentation of MSVS_ARCH. Update
the documentation for HOST_ARCH.
---
CHANGES.txt | 2 ++
SCons/Platform/Platform.xml | 4 ++--
SCons/Tool/MSCommon/vs.py | 8 ++++----
doc/generated/variables.gen | 4 ++--
4 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 82e6d0a..614aebe 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -33,6 +33,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
- Fix an issue where test SConfTests.py would fail when mscommon debugging
was enabled. The mscommon debug filter class registered with the logging
module was refactored.
+ - Add arm64 to the MSVS supported architectures list for VS2017 and later to be
+ consistent with the current documentation of MSVS_ARCH.
From Michał Górny:
- Remove the redundant `wheel` dependency from `pyproject.toml`,
diff --git a/SCons/Platform/Platform.xml b/SCons/Platform/Platform.xml
index 08199f4..c449fa5 100644
--- a/SCons/Platform/Platform.xml
+++ b/SCons/Platform/Platform.xml
@@ -173,8 +173,8 @@ else:
Valid host arch values are
x86 and arm
for 32-bit hosts and
- amd64 and x86_64
- for 64-bit hosts.
+ amd64, arm64,
+ and x86_64 for 64-bit hosts.
Should be considered immutable.
diff --git a/SCons/Tool/MSCommon/vs.py b/SCons/Tool/MSCommon/vs.py
index 08c3cf5..07fcdc4 100644
--- a/SCons/Tool/MSCommon/vs.py
+++ b/SCons/Tool/MSCommon/vs.py
@@ -207,7 +207,7 @@ SupportedVSList = [
executable_path=r'Common7\IDE\devenv.com',
# should be a fallback, prefer use vswhere installationPath
batch_file_path=r'Common7\Tools\VsDevCmd.bat',
- supported_arch=['x86', 'amd64', "arm"],
+ supported_arch=['x86', 'amd64', "arm", 'arm64'],
),
# Visual Studio 2019
@@ -219,7 +219,7 @@ SupportedVSList = [
executable_path=r'Common7\IDE\devenv.com',
# should be a fallback, prefer use vswhere installationPath
batch_file_path=r'Common7\Tools\VsDevCmd.bat',
- supported_arch=['x86', 'amd64', "arm"],
+ supported_arch=['x86', 'amd64', "arm", 'arm64'],
),
# Visual Studio 2017
@@ -231,7 +231,7 @@ SupportedVSList = [
executable_path=r'Common7\IDE\devenv.com',
# should be a fallback, prefer use vswhere installationPath
batch_file_path=r'Common7\Tools\VsDevCmd.bat',
- supported_arch=['x86', 'amd64', "arm"],
+ supported_arch=['x86', 'amd64', "arm", 'arm64'],
),
# Visual C++ 2017 Express Edition (for Desktop)
@@ -243,7 +243,7 @@ SupportedVSList = [
executable_path=r'Common7\IDE\WDExpress.exe',
# should be a fallback, prefer use vswhere installationPath
batch_file_path=r'Common7\Tools\VsDevCmd.bat',
- supported_arch=['x86', 'amd64', "arm"],
+ supported_arch=['x86', 'amd64', "arm", 'arm64'],
),
# Visual Studio 2015
diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen
index 42935a3..86395a7 100644
--- a/doc/generated/variables.gen
+++ b/doc/generated/variables.gen
@@ -3179,8 +3179,8 @@ is -dNOPAUSE -dBATCH -sDEVICE=pdfwrite
Valid host arch values are
x86 and arm
for 32-bit hosts and
- amd64 and x86_64
- for 64-bit hosts.
+ amd64, arm64,
+ and x86_64 for 64-bit hosts.
Should be considered immutable.
--
cgit v0.12
From c50f65668f3cb1470685a1379b75039e11ae94b2 Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Sun, 19 Mar 2023 12:00:37 -0400
Subject: Update RELEASE.txt. [skip ci]
---
RELEASE.txt | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/RELEASE.txt b/RELEASE.txt
index 4e25b95..b3e8c1a 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -18,6 +18,11 @@ NEW FUNCTIONALITY
- List new features (presumably why a checkpoint is being released)
+- MSVC: If available, native arm64 tools will be used on arm64 hosts for VS2022.
+- MSVC: If necessary, automatically define VSCMD_SKIP_TELEMETRY for VS2019 and later
+ on arm64 hosts when using an arm (32-bit) build of python to prevent a powershell
+ error pop-up window (powershell dll not found).
+
DEPRECATED FUNCTIONALITY
------------------------
@@ -29,11 +34,37 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
- List modifications to existing features, where the previous behavior
wouldn't actually be considered a bug
+- MSVC: When trying to find a valid msvc batch file, the existence of the msvc compiler
+ executable is verified for VS6 to VS2015 to avoid executing the msvc batch file when
+ the host/target tool is known not to be present. Always check that the msvc compiler
+ executable is found on the msvc script environment path after running the msvc batch
+ file. The is predominately needed for recent versions of Visual Studio where the msvc
+ batch file exists but an individual msvc toolset may not support the host/target
+ architecture combination. For example, when using VS2022 on arm64, the arm64 native
+ tools are only installed for the 14.3x toolsets.
+
FIXES
-----
- List fixes of outright bugs
+- MSVC: The installed msvc list is calculated once and cached. There was an indirect
+ dependency on the target architecture when determining if each version of msvc
+ was installed based on the initial invocation. It was possible that an msvc instance
+ would not be considered installed due to the tools for the requested target
+ architecture not being installed. The initial call to construct the installed msvc
+ list now uses an undefined target architecture to evaluate all potential host/target
+ combinations when evaluating if the msvc tools are installed for a given Visual Studio
+ installation.
+- MSVC: Erroneous construction of the installed msvc list (as described above) caused an
+ index error in the msvc support code. An explicit check was added to prevent indexing
+ into an empty list.
+- MSCommon: Test SConsTests.py would fail when mscommon debugging was enabled via the
+ MSVC_MSCOMMON_DEBUG environment variable. The mscommon logging filter class registered
+ with the python logging module was refactored to prevent test failure.
+- MSVS: Add arm64 to the MSVS supported architectures list for VS2017 and later to be
+ consistent with the current documentation of MSVS_ARCH.
+
IMPROVEMENTS
------------
@@ -54,6 +85,8 @@ DOCUMENTATION
typo fixes, even if they're mentioned in src/CHANGES.txt to give
the contributor credit)
+- HOST_ARCH: Add arm64 to the valid win32 host architectures.
+
DEVELOPMENT
-----------
--
cgit v0.12
From 4bdb9de39d98288c564e6e1fd5eefcbe2de5803a Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Sun, 19 Mar 2023 13:39:37 -0400
Subject: Fix typographical error in RELEASE.txt [skip ci]
---
RELEASE.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASE.txt b/RELEASE.txt
index b3e8c1a..a73919c 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -59,7 +59,7 @@ FIXES
- MSVC: Erroneous construction of the installed msvc list (as described above) caused an
index error in the msvc support code. An explicit check was added to prevent indexing
into an empty list.
-- MSCommon: Test SConsTests.py would fail when mscommon debugging was enabled via the
+- MSCommon: Test SConfTests.py would fail when mscommon debugging was enabled via the
MSVC_MSCOMMON_DEBUG environment variable. The mscommon logging filter class registered
with the python logging module was refactored to prevent test failure.
- MSVS: Add arm64 to the MSVS supported architectures list for VS2017 and later to be
--
cgit v0.12
From 11ec1b43128c7eebddb93028d2e38c97af884ebb Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Sun, 19 Mar 2023 16:22:18 -0400
Subject: Fix typographical error in RELEASE.txt [skip ci]
---
RELEASE.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASE.txt b/RELEASE.txt
index a73919c..0acf502 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -19,7 +19,7 @@ NEW FUNCTIONALITY
- List new features (presumably why a checkpoint is being released)
- MSVC: If available, native arm64 tools will be used on arm64 hosts for VS2022.
-- MSVC: If necessary, automatically define VSCMD_SKIP_TELEMETRY for VS2019 and later
+- MSVC: If necessary, automatically define VSCMD_SKIP_SENDTELEMETRY for VS2019 and later
on arm64 hosts when using an arm (32-bit) build of python to prevent a powershell
error pop-up window (powershell dll not found).
--
cgit v0.12
From db58ed9a3be634a766399435e32456baf66fb970 Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Mon, 20 Mar 2023 05:55:43 -0400
Subject: Fix typographical error in RELEASE.txt [skip ci]
---
RELEASE.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/RELEASE.txt b/RELEASE.txt
index 0acf502..43519d7 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -38,7 +38,7 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
executable is verified for VS6 to VS2015 to avoid executing the msvc batch file when
the host/target tool is known not to be present. Always check that the msvc compiler
executable is found on the msvc script environment path after running the msvc batch
- file. The is predominately needed for recent versions of Visual Studio where the msvc
+ file. This is predominately needed for recent versions of Visual Studio where the msvc
batch file exists but an individual msvc toolset may not support the host/target
architecture combination. For example, when using VS2022 on arm64, the arm64 native
tools are only installed for the 14.3x toolsets.
--
cgit v0.12
From 6e69fddde42825e831c0aa282c30424041b5adf8 Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Fri, 24 Mar 2023 12:08:06 -0400
Subject: Update the host architecture query function in the MSVS test
framework.
First query the windows registry for the processor architecture and then fallback to the platform machine architecture. The platform.machine() architecture return value for an amd64 build of python (3.6.8) on arm64 is amd64.
Update the _ARCH_TO_CANONICAL dictionary from Tool\MSCommon\vc.py.
---
testing/framework/TestSConsMSVS.py | 45 ++++++++++++++++++++++++++++----------
1 file changed, 34 insertions(+), 11 deletions(-)
diff --git a/testing/framework/TestSConsMSVS.py b/testing/framework/TestSConsMSVS.py
index b001d79..b00af32 100644
--- a/testing/framework/TestSConsMSVS.py
+++ b/testing/framework/TestSConsMSVS.py
@@ -40,6 +40,10 @@ import sys
import platform
import traceback
from xml.etree import ElementTree
+try:
+ import winreg
+except ImportError:
+ winreg = None
import SCons.Errors
from TestSCons import *
@@ -763,23 +767,42 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions()))
return result
def get_vs_host_arch(self):
- """ Returns an MSVS, SDK , and/or MSVS acceptable platform arch. """
+ """ Returns an MSVS, SDK, and/or MSVS acceptable platform arch. """
- # Dict to 'canonalize' the arch
+ # Dict to 'canonicalize' the arch (synchronize with MSCommon\vc.py)
_ARCH_TO_CANONICAL = {
- "x86": "x86",
- "amd64": "amd64",
- "i386": "x86",
- "emt64": "amd64",
- "x86_64": "amd64",
- "itanium": "ia64",
- "ia64": "ia64",
+ "amd64" : "amd64",
+ "emt64" : "amd64",
+ "i386" : "x86",
+ "i486" : "x86",
+ "i586" : "x86",
+ "i686" : "x86",
+ "ia64" : "ia64", # deprecated
+ "itanium" : "ia64", # deprecated
+ "x86" : "x86",
+ "x86_64" : "amd64",
+ "arm" : "arm",
+ "arm64" : "arm64",
+ "aarch64" : "arm64",
}
- host_platform = platform.machine()
+ host_platform = None
+
+ if winreg:
+ try:
+ winkey = winreg.OpenKeyEx(
+ winreg.HKEY_LOCAL_MACHINE,
+ r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
+ )
+ host_platform, _ = winreg.QueryValueEx(winkey, 'PROCESSOR_ARCHITECTURE')
+ except OSError:
+ pass
+
+ if not host_platform:
+ host_platform = platform.machine()
try:
- host = _ARCH_TO_CANONICAL[host_platform]
+ host = _ARCH_TO_CANONICAL[host_platform.lower()]
except KeyError as e:
# Default to x86 for all other platforms
host = 'x86'
--
cgit v0.12
From d3d42299c50b1249a71deccc76d89ada335939b7 Mon Sep 17 00:00:00 2001
From: Joseph Brill <48932340+jcbrill@users.noreply.github.com>
Date: Fri, 31 Mar 2023 09:09:20 -0400
Subject: Remove placeholders from added text in RELEASE.txt
---
RELEASE.txt | 7 -------
1 file changed, 7 deletions(-)
diff --git a/RELEASE.txt b/RELEASE.txt
index dde85e9..a15fa7f 100644
--- a/RELEASE.txt
+++ b/RELEASE.txt
@@ -16,8 +16,6 @@ Here is a summary of the changes since 4.5.2:
NEW FUNCTIONALITY
-----------------
-- List new features (presumably why a checkpoint is being released)
-
- MSVC: If available, native arm64 tools will be used on arm64 hosts for VS2022.
- MSVC: If necessary, automatically define VSCMD_SKIP_SENDTELEMETRY for VS2019 and later
on arm64 hosts when using an arm (32-bit) build of python to prevent a powershell
@@ -48,7 +46,6 @@ FIXES
embedded in a sequence, or by itself. The conditional C scanner thus
did not always properly apply the defines. The regular C scanner does
not use these, so was not affected. [fixes #4193]
-
- MSVC: The installed msvc list is calculated once and cached. There was an indirect
dependency on the target architecture when determining if each version of msvc
was installed based on the initial invocation. It was possible that an msvc instance
@@ -81,10 +78,6 @@ PACKAGING
DOCUMENTATION
-------------
-- List any significant changes to the documentation (not individual
- typo fixes, even if they're mentioned in src/CHANGES.txt to give
- the contributor credit)
-
- HOST_ARCH: Add arm64 to the valid win32 host architectures.
DEVELOPMENT
--
cgit v0.12