diff options
author | William Deegan <bill@baddogconsulting.com> | 2019-06-18 22:45:48 (GMT) |
---|---|---|
committer | William Deegan <bill@baddogconsulting.com> | 2019-06-18 22:45:48 (GMT) |
commit | 958fcfe1a37f2abea6104af3a2995cd714d13754 (patch) | |
tree | ce981caada71b5b659b899acc9872ed18dcb3441 /src | |
parent | 52d388e565873e1f532f9c36617f97aa58d78622 (diff) | |
download | SCons-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-x | src/CHANGES.txt | 10 | ||||
-rw-r--r-- | src/engine/SCons/Tool/MSCommon/vc.py | 42 | ||||
-rw-r--r-- | src/engine/SCons/Tool/MSCommon/vcTests.py | 180 |
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() |