summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2019-06-18 22:45:48 (GMT)
committerWilliam Deegan <bill@baddogconsulting.com>2019-06-18 22:45:48 (GMT)
commit958fcfe1a37f2abea6104af3a2995cd714d13754 (patch)
treece981caada71b5b659b899acc9872ed18dcb3441 /src
parent52d388e565873e1f532f9c36617f97aa58d78622 (diff)
downloadSCons-958fcfe1a37f2abea6104af3a2995cd714d13754.zip
SCons-958fcfe1a37f2abea6104af3a2995cd714d13754.tar.gz
SCons-958fcfe1a37f2abea6104af3a2995cd714d13754.tar.bz2
Added tests to logic changes by mhqtronic PR #3375
Diffstat (limited to 'src')
-rwxr-xr-xsrc/CHANGES.txt10
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py42
-rw-r--r--src/engine/SCons/Tool/MSCommon/vcTests.py180
3 files changed, 215 insertions, 17 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 846d860..cd73140 100755
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -5,6 +5,8 @@
Change Log
+**PLEASE ADD YOUR NAME IN ALPHABETICAL ORDER TO AVOID NEEDED TO REORDER BELOW**
+
RELEASE VERSION/DATE TO BE FILLED IN LATER
From Peter Diener:
@@ -40,6 +42,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
which specifies what character to join all the argements output into the tempfile. The default remains a space
when mslink, msvc, or mslib tools are loaded they change the TEMPFILEARGJOIN to be a line separator (\r\n on win32)
+ From Michael Hartmann:
+ - Fix handling of Visual Studio Compilers to properly reject any unknown HOST_PLATFORM or TARGET_PLATFORM
+
+
From Mats Wichmann:
- scons-time takes more care closing files and uses safer mkdtemp to avoid
possible races on multi-job runs.
@@ -66,6 +72,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
ParseFlags: -iquote and -idirafter.
- Fix more re patterns that contain \ but not specified as raw strings
(affects scanners for D, LaTeX, swig)
+<<<<<<< Updated upstream
+=======
+
+>>>>>>> Stashed changes
From Mathew Robinson:
- Update cache debug output to include cache hit rate.
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py
index c8fb19d..e43d0bb 100644
--- a/src/engine/SCons/Tool/MSCommon/vc.py
+++ b/src/engine/SCons/Tool/MSCommon/vc.py
@@ -60,7 +60,10 @@ class VisualCException(Exception):
class UnsupportedVersion(VisualCException):
pass
-class UnsupportedArch(VisualCException):
+class MSVCUnsupportedHostArch(VisualCException):
+ pass
+
+class MSVCUnsupportedTargetArch(VisualCException):
pass
class MissingConfiguration(VisualCException):
@@ -89,17 +92,15 @@ _ARCH_TO_CANONICAL = {
"aarch64" : "arm64",
}
-# get path to the cl.exe dir for newer VS versions
-# based off a tuple of (host, target) platforms
_HOST_TARGET_TO_CL_DIR_GREATER_THAN_14 = {
- ("amd64","amd64") : "Hostx64\\x64",
- ("amd64","x86") : "Hostx64\\x86",
- ("amd64","arm") : "Hostx64\\arm",
- ("amd64","arm64") : "Hostx64\\arm64",
- ("x86","amd64") : "Hostx86\\x64",
- ("x86","x86") : "Hostx86\\x86",
- ("x86","arm") : "Hostx86\\arm",
- ("x86","arm64") : "Hostx86\\arm64",
+ ("amd64","amd64") : ("Hostx64","x64"),
+ ("amd64","x86") : ("Hostx64","x86"),
+ ("amd64","arm") : ("Hostx64","arm"),
+ ("amd64","arm64") : ("Hostx64","arm64"),
+ ("x86","amd64") : ("Hostx86","x64"),
+ ("x86","x86") : ("Hostx86","x86"),
+ ("x86","arm") : ("Hostx86","arm"),
+ ("x86","arm64") : ("Hostx86","arm64"),
}
# get path to the cl.exe dir for older VS versions
@@ -174,15 +175,15 @@ def get_host_target(env):
try:
host = _ARCH_TO_CANONICAL[host_platform.lower()]
- except KeyError as e:
+ except KeyError:
msg = "Unrecognized host architecture %s"
- raise ValueError(msg % repr(host_platform))
+ raise MSVCUnsupportedHostArch(msg % repr(host_platform))
try:
target = _ARCH_TO_CANONICAL[target_platform.lower()]
- except KeyError as e:
+ except KeyError:
all_archs = str(list(_ARCH_TO_CANONICAL.keys()))
- raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
+ raise MSVCUnsupportedTargetArch("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
return (host, target,req_target_platform)
@@ -425,6 +426,8 @@ def find_batch_file(env,msvc_version,host_arch,target_arch):
__INSTALLED_VCS_RUN = None
+_VC_TOOLS_VERSION_FILE_PATH = ['Auxiliary', 'Build', 'Microsoft.VCToolsVersion.default.txt']
+_VC_TOOLS_VERSION_FILE = os.sep.join(_VC_TOOLS_VERSION_FILE_PATH)
def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
"""Find the cl.exe on the filesystem in the vc_dir depending on
@@ -468,7 +471,7 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
# 2017 and newer allowed multiple versions of the VC toolset to be installed at the same time.
# Just get the default tool version for now
#TODO: support setting a specific minor VC version
- default_toolset_file = os.path.join(vc_dir, r'Auxiliary\Build\Microsoft.VCToolsVersion.default.txt')
+ default_toolset_file = os.path.join(vc_dir, _VC_TOOLS_VERSION_FILE)
try:
with open(default_toolset_file) as f:
vc_specific_version = f.readlines()[0].strip()
@@ -480,11 +483,16 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
return False
host_trgt_dir = _HOST_TARGET_TO_CL_DIR_GREATER_THAN_14.get((host_platform, target_platform), None)
+<<<<<<< Updated upstream
if not host_trgt_dir:
debug('_check_cl_exists_in_vc_dir(): unsupported host/target platform combo')
+=======
+ if host_trgt_dir is None:
+ debug('_check_cl_exists_in_vc_dir(): unsupported host/target platform combo: (%s,%s)'%(host_platform, target_platform))
+>>>>>>> Stashed changes
return False
- cl_path = os.path.join(vc_dir, r'Tools\MSVC', vc_specific_version, 'bin', host_trgt_dir, _CL_EXE_NAME)
+ cl_path = os.path.join(vc_dir, 'Tools','MSVC', vc_specific_version, 'bin', host_trgt_dir[0], host_trgt_dir[1], _CL_EXE_NAME)
debug('_check_cl_exists_in_vc_dir(): checking for ' + _CL_EXE_NAME + ' at ' + cl_path)
if os.path.exists(cl_path):
debug('_check_cl_exists_in_vc_dir(): found ' + _CL_EXE_NAME + '!')
diff --git a/src/engine/SCons/Tool/MSCommon/vcTests.py b/src/engine/SCons/Tool/MSCommon/vcTests.py
new file mode 100644
index 0000000..09991f5
--- /dev/null
+++ b/src/engine/SCons/Tool/MSCommon/vcTests.py
@@ -0,0 +1,180 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# from typing import Dict, Any
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import os
+import os.path
+import unittest
+
+import SCons.Node.FS
+import SCons.Warnings
+import SCons.Tool.MSCommon.vc
+
+import TestCmd
+
+original = os.getcwd()
+
+test = TestCmd.TestCmd(workdir='')
+
+os.chdir(test.workpath(''))
+
+MSVCUnsupportedHostArch = SCons.Tool.MSCommon.vc.MSVCUnsupportedHostArch
+MSVCUnsupportedTargetArch = SCons.Tool.MSCommon.vc.MSVCUnsupportedTargetArch
+
+MS_TOOLS_VERSION='1.1.1'
+
+class MSVcTestCase(unittest.TestCase):
+
+ @staticmethod
+ def _createDummyCl(path, add_bin=True):
+ """
+ Creates a dummy cl.ex in the correct directory.
+ It will create all missing parent directories as well
+
+ Args:
+ path: Relative path to cl.exe for the version about to be tested.
+ """
+
+ # print("PATH:%s"%path)
+
+ path = path.replace('\\', os.sep)
+ if add_bin:
+ create_path = os.path.join(path,'bin')
+ else:
+ create_path = path
+ if create_path and not os.path.isdir(create_path):
+ os.makedirs(create_path)
+
+ create_this = os.path.join(create_path,'cl.exe')
+
+ # print("Creating: %s"%create_this)
+ with open(create_this,'w') as ct:
+ ct.write('created')
+
+
+
+
+ def runTest(self):
+ """
+ Check that all proper HOST_PLATFORM and TARGET_PLATFORM are handled.
+ Verify that improper HOST_PLATFORM and/or TARGET_PLATFORM are properly handled.
+ by SCons.Tool.MSCommon.vc._check_cl_exists_in_vc_dir()
+ """
+
+ check = SCons.Tool.MSCommon.vc._check_cl_exists_in_vc_dir
+
+ env={'TARGET_ARCH':'x86'}
+ p = SCons.Tool.MSCommon.vc._HOST_TARGET_TO_CL_DIR[('x86','x86')]
+ MSVcTestCase._createDummyCl(p)
+
+ # print("retval:%s"%check(env, '.', '8.0'))
+
+
+ # Setup for VC 14+ tests
+
+ # Create the VC minor/major version file
+ tools_version_file = SCons.Tool.MSCommon.vc._VC_TOOLS_VERSION_FILE
+ tools_dir = os.path.dirname(tools_version_file)
+ if not os.path.isdir(tools_dir):
+ os.makedirs(tools_dir)
+ try:
+ with open(tools_version_file, 'w') as tf:
+ tf.write(MS_TOOLS_VERSION)
+ except IOError as e:
+ print("Failed trying to write :%s :%s"%(tools_version_file, e))
+
+
+ # Now walk all the valid combinations of host/target for VC 14 +
+ vc_gt_14_map = SCons.Tool.MSCommon.vc._HOST_TARGET_TO_CL_DIR_GREATER_THAN_14
+
+ for key, value in vc_gt_14_map.items():
+ # print("GT 14 Got: %s -> %s"%(key,value))
+
+ env={'TARGET_ARCH':key[1], 'HOST_ARCH':key[0]}
+ path = os.path.join('.','Tools','MSVC', MS_TOOLS_VERSION, 'bin', value[0], value[1])
+ MSVcTestCase._createDummyCl(path, add_bin=False)
+ result=check(env, '.', '14.1')
+ # print("for:%s got :%s"%(key[1], result))
+ self.assertTrue(result, "Checking host: %s target: %s"%(value[0], value[1]))
+
+ # Now test bogus value for HOST_ARCH
+ env={'TARGET_ARCH':'x86', 'HOST_ARCH':'GARBAGE'}
+ try:
+ result=check(env, '.', '14.1')
+ # print("for:%s got :%s"%(env, result))
+ self.assertFalse(result, "Did not fail with bogus HOST_ARCH host: %s target: %s"%(value[0], value[1]))
+ 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.1')
+ # print("for:%s got :%s"%(env, result))
+ self.assertFalse(result, "Did not fail with bogus TARGET_ARCH host: %s target: %s"%(value[0], value[1]))
+ except MSVCUnsupportedTargetArch:
+ pass
+ else:
+ self.fail('Did not fail when HOST_ARCH specified as: %s'%env['TARGET_ARCH'])
+
+ # Test >8 < 14 VC versions
+ vc_map = SCons.Tool.MSCommon.vc._HOST_TARGET_TO_CL_DIR
+ for key,value in vc_map.items():
+ # print("LT 14 Got: %s -> %s"%(key,value))
+ env={'TARGET_ARCH':key[1], 'HOST_ARCH':key[0]}
+ path = os.path.join('.', 'bin', value )
+ MSVcTestCase._createDummyCl(path, add_bin=False)
+ result=check(env, '.', '9.0')
+ # print("for:%s got :%s"%(key[1], result))
+ self.assertTrue(result, "Checking host: %s target: %s"%(key[0], key[1]))
+
+ # Now test bogus value for HOST_ARCH
+ env={'TARGET_ARCH':'x86', 'HOST_ARCH':'GARBAGE'}
+ try:
+ result=check(env, '.', '9.0')
+ # 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, '.', '9.0')
+ # 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 HOST_ARCH specified as: %s'%env['TARGET_ARCH'])
+
+
+
+if __name__ == "__main__":
+ unittest.main()