From 8fca5898da15fe1b3f4f87fc35bed34c236e74cb Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 11 Apr 2022 09:29:41 -0400 Subject: Suppress warning for missing MSVC compiler for initial call to msvc_setup_env with undefined MSVC_VERSION (default tools). --- SCons/Tool/MSCommon/vc.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index fe31cb3..3373301 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -714,7 +714,9 @@ def get_installed_vcs(env=None): def reset_installed_vcs(): """Make it try again to find VC. This is just for the tests.""" global __INSTALLED_VCS_RUN + global __MSVC_SETUP_ENV_DEFAULT __INSTALLED_VCS_RUN = None + __MSVC_SETUP_ENV_DEFAULT = None # 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'" @@ -920,14 +922,18 @@ def msvc_find_valid_batch_script(env, version): return d +__MSVC_SETUP_ENV_DEFAULT = None def msvc_setup_env(env): + global __MSVC_SETUP_ENV_DEFAULT debug('called') version = get_default_version(env) if version is None: - warn_msg = "No version of Visual Studio compiler found - C/C++ " \ - "compilers most likely not set correctly" - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + if __MSVC_SETUP_ENV_DEFAULT: + warn_msg = "No version of Visual Studio compiler found - C/C++ " \ + "compilers most likely not set correctly" + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + __MSVC_SETUP_ENV_DEFAULT = True return None # XXX: we set-up both MSVS version for backward -- cgit v0.12 From f338fee76045f94e78f25f15fea1d4bf33786d6e Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Tue, 12 Apr 2022 10:20:49 -0400 Subject: Raise MSVCVersionNotFound exception instead of returning an empty/undefined dictionary when attempting to find a valid msvc batch script. Raise an MSVCVersionNotFound exception when the default msvc version is requested and there are no msvc versions installed. Suppress raising an MSVCVersionNotFound exception during default msvc tool initialization. Add additional tests. --- SCons/Tool/MSCommon/vc.py | 36 ++++++++++--- test/MSVC/msvc_badversion.py | 59 ++++++++++++++++++++++ test/MSVC/no_msvc.py | 26 ++++++++-- test/fixture/no_msvc/no_msvcs_sconstruct.py | 1 - test/fixture/no_msvc/no_msvcs_sconstruct_tools.py | 14 +++++ .../fixture/no_msvc/no_msvcs_sconstruct_version.py | 14 +++++ 6 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 test/MSVC/msvc_badversion.py create mode 100644 test/fixture/no_msvc/no_msvcs_sconstruct_tools.py create mode 100644 test/fixture/no_msvc/no_msvcs_sconstruct_version.py diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 3373301..d9a6e50 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -79,6 +79,9 @@ class BatchFileExecutionError(VisualCException): class MSVCScriptNotFound(VisualCException): pass +class MSVCVersionNotFound(VisualCException): + pass + # Dict to 'canonalize' the arch _ARCH_TO_CANONICAL = { "amd64" : "amd64", @@ -853,6 +856,7 @@ def msvc_find_valid_batch_script(env, version): debug("host_platform: %s, try_target_archs: %s", host_platform, try_target_archs) d = None + version_installed = False for tp in try_target_archs: # Set to current arch. env['TARGET_ARCH'] = tp @@ -869,14 +873,11 @@ def msvc_find_valid_batch_script(env, version): try: (vc_script, use_arg, sdk_script) = find_batch_file(env, version, host_platform, tp) debug('vc_script:%s sdk_script:%s', vc_script, sdk_script) + version_installed = True except VisualCException as e: msg = str(e) debug('Caught exception while looking for batch file (%s)', msg) - warn_msg = "VC version %s not installed. " + \ - "C/C++ compilers are most likely not set correctly.\n" + \ - " Installed versions are: %s" - warn_msg = warn_msg % (version, get_installed_vcs(env)) - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + version_installed = False continue # Try to use the located batch file for this host/target platform combo @@ -919,6 +920,25 @@ def msvc_find_valid_batch_script(env, version): # To it's initial value if not d: env['TARGET_ARCH']=req_target_platform + installed_vcs = get_installed_vcs(env) + if version_installed: + err_msg = "MSVC version {} working host/target script was not found.\n" \ + " Host = {}, Target = {}\n" \ + " Visual Studio C/C++ compilers may not be set correctly".format( + version, host_platform, target_platform + ) + elif version and installed_vcs: + err_msg = "MSVC version {} was not found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly.\n" \ + " Installed versions are: {}".format(version, installed_vcs) + elif version: + err_msg = "MSVC version {} was not found.\n" \ + " No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly".format(version) + else: + err_msg = "No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly" + raise MSVCVersionNotFound(err_msg) return d @@ -930,9 +950,9 @@ def msvc_setup_env(env): version = get_default_version(env) if version is None: if __MSVC_SETUP_ENV_DEFAULT: - warn_msg = "No version of Visual Studio compiler found - C/C++ " \ - "compilers most likely not set correctly" - SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) + err_msg = "No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly" + raise MSVCVersionNotFound(err_msg) __MSVC_SETUP_ENV_DEFAULT = True return None diff --git a/test/MSVC/msvc_badversion.py b/test/MSVC/msvc_badversion.py new file mode 100644 index 0000000..7af8ca5 --- /dev/null +++ b/test/MSVC/msvc_badversion.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# +# __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. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test scons with an invalid MSVC version when at least one MSVC is present. +""" + +import sys + +import TestSCons +import SCons.Tool.MSCommon.vc as msvc + +test = TestSCons.TestSCons() + +if sys.platform != 'win32': + test.skip_test("Not win32 platform. Skipping test\n") + +test.skip_if_not_msvc() + +installed_msvc_versions = msvc.get_installed_vcs() +# MSVC guaranteed to be at least one version on the system or else +# skip_if_not_msvc() function would have skipped the test + +test.write('SConstruct', """\ +env = Environment(MSVC_VERSION='12.9') +""") + +test.run(arguments='-Q -s', status=2, stderr=r"^.*MSVCVersionNotFound.+", match=TestSCons.match_re_dotall) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSVC/no_msvc.py b/test/MSVC/no_msvc.py index d1161c6..b6442e8 100644 --- a/test/MSVC/no_msvc.py +++ b/test/MSVC/no_msvc.py @@ -43,9 +43,29 @@ test.run(arguments='-Q -s', stdout='') # test no msvc's test.file_fixture('no_msvc/no_msvcs_sconstruct.py', 'SConstruct') +test.run(arguments='-Q -s', status=2, stderr=r"^.*MSVCVersionNotFound.+", match=TestSCons.match_re_dotall) + +# test msvc version number request with no msvc's +test.file_fixture('no_msvc/no_msvcs_sconstruct_version.py', 'SConstruct') +test.run(arguments='-Q -s', status=2, stderr=r"^.*MSVCVersionNotFound.+", match=TestSCons.match_re_dotall) + +# test that MSVCVersionNotFound is not raised for default msvc tools +# when a non-msvc tool list is used +test.subdir('site_scons', ['site_scons', 'site_tools']) + +test.write(['site_scons', 'site_tools', 'myignoredefaultmsvctool.py'], """ +import SCons.Tool +def generate(env): + env['MYIGNOREDEFAULTMSVCTOOL']='myignoredefaultmsvctool' +def exists(env): + return 1 +""") + +test.file_fixture('no_msvc/no_msvcs_sconstruct_tools.py', 'SConstruct') +test.run(arguments='-Q -s') + +test.file_fixture('no_msvc/no_msvcs_sconstruct_tools.py', 'SConstruct') test.run(arguments='-Q -s') -if 'MSVC_VERSION=None' not in test.stdout(): - test.fail_test() +test.pass_test() -test.pass_test() \ No newline at end of file diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct.py b/test/fixture/no_msvc/no_msvcs_sconstruct.py index 18366d8..590142b 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct.py @@ -12,4 +12,3 @@ SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere env = SCons.Environment.Environment() -print('MSVC_VERSION='+str(env.get('MSVC_VERSION'))) \ No newline at end of file diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py b/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py new file mode 100644 index 0000000..ca9b699 --- /dev/null +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py @@ -0,0 +1,14 @@ +import SCons +import SCons.Tool.MSCommon + +def DummyVsWhere(msvc_version, env): + # not testing versions with vswhere, so return none + return None + +for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + +SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere + +env = SCons.Environment.Environment(tools=['MYIGNOREDEFAULTMSVCTOOL']) + diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_version.py b/test/fixture/no_msvc/no_msvcs_sconstruct_version.py new file mode 100644 index 0000000..81d47cf --- /dev/null +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_version.py @@ -0,0 +1,14 @@ +import SCons +import SCons.Tool.MSCommon + +def DummyVsWhere(msvc_version, env): + # not testing versions with vswhere, so return none + return None + +for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: + SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR[key]=[(SCons.Util.HKEY_LOCAL_MACHINE, r'')] + +SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere + +env = SCons.Environment.Environment(MSVC_VERSION='14.3') + -- cgit v0.12 From b19e130873dbf44d4e3edb0d0cc47df12f99b865 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sun, 24 Apr 2022 06:12:26 -0400 Subject: Rework exception message construction when a specified msvc version is not found. Remove exception for default msvc version and adjust test accordingly. --- SCons/Tool/MSCommon/vc.py | 43 ++++++++++++++++++++++--------------------- test/MSVC/no_msvc.py | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index d9a6e50..cac1744 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -717,9 +717,7 @@ def get_installed_vcs(env=None): def reset_installed_vcs(): """Make it try again to find VC. This is just for the tests.""" global __INSTALLED_VCS_RUN - global __MSVC_SETUP_ENV_DEFAULT __INSTALLED_VCS_RUN = None - __MSVC_SETUP_ENV_DEFAULT = None # 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'" @@ -920,40 +918,43 @@ def msvc_find_valid_batch_script(env, version): # To it's initial value if not d: env['TARGET_ARCH']=req_target_platform - installed_vcs = get_installed_vcs(env) + if version_installed: err_msg = "MSVC version {} working host/target script was not found.\n" \ " Host = {}, Target = {}\n" \ " Visual Studio C/C++ compilers may not be set correctly".format( version, host_platform, target_platform ) - elif version and installed_vcs: - err_msg = "MSVC version {} was not found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly.\n" \ - " Installed versions are: {}".format(version, installed_vcs) - elif version: - err_msg = "MSVC version {} was not found.\n" \ - " No versions of the MSVC compiler were found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly".format(version) else: - err_msg = "No versions of the MSVC compiler were found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly" + installed_vcs = get_installed_vcs(env) + if version is not None: + if not installed_vcs: + err_msg = "MSVC version {} was not found.\n" \ + " No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly".format(version) + else: + err_msg = "MSVC version {} was not found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly.\n" \ + " Installed versions are: {}".format(version, installed_vcs) + else: + # should never get here due to early exit in msvc_setup_env + if not installed_vcs: + err_msg = "MSVC default version was not found.\n" \ + " No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly" + else: + # should be impossible: version is None and len(installed_vcs) > 0 + err_msg = "MSVC default version was not found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly.\n" \ + " Installed versions are: {}".format(installed_vcs) raise MSVCVersionNotFound(err_msg) return d -__MSVC_SETUP_ENV_DEFAULT = None - def msvc_setup_env(env): - global __MSVC_SETUP_ENV_DEFAULT debug('called') version = get_default_version(env) if version is None: - if __MSVC_SETUP_ENV_DEFAULT: - err_msg = "No versions of the MSVC compiler were found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly" - raise MSVCVersionNotFound(err_msg) - __MSVC_SETUP_ENV_DEFAULT = True return None # XXX: we set-up both MSVS version for backward diff --git a/test/MSVC/no_msvc.py b/test/MSVC/no_msvc.py index b6442e8..683951e 100644 --- a/test/MSVC/no_msvc.py +++ b/test/MSVC/no_msvc.py @@ -43,7 +43,7 @@ test.run(arguments='-Q -s', stdout='') # test no msvc's test.file_fixture('no_msvc/no_msvcs_sconstruct.py', 'SConstruct') -test.run(arguments='-Q -s', status=2, stderr=r"^.*MSVCVersionNotFound.+", match=TestSCons.match_re_dotall) +test.run(arguments='-Q -s', stdout='') # test msvc version number request with no msvc's test.file_fixture('no_msvc/no_msvcs_sconstruct_version.py', 'SConstruct') -- cgit v0.12 From 6f68a4fc1646be9ec4b1b6c5e8fbda031d239a0b Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sun, 24 Apr 2022 07:19:26 -0400 Subject: Simplify msvc version not found exception messages by removing impossible combinations. Update exception message formatting. --- SCons/Tool/MSCommon/vc.py | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index cac1744..0b25ed5 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -920,33 +920,21 @@ def msvc_find_valid_batch_script(env, version): env['TARGET_ARCH']=req_target_platform if version_installed: - err_msg = "MSVC version {} working host/target script was not found.\n" \ - " Host = {}, Target = {}\n" \ + err_msg = "MSVC version '{}' working host/target script was not found.\n" \ + " Host = '{}', Target = '{}'\n" \ " Visual Studio C/C++ compilers may not be set correctly".format( version, host_platform, target_platform ) else: installed_vcs = get_installed_vcs(env) - if version is not None: - if not installed_vcs: - err_msg = "MSVC version {} was not found.\n" \ - " No versions of the MSVC compiler were found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly".format(version) - else: - err_msg = "MSVC version {} was not found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly.\n" \ - " Installed versions are: {}".format(version, installed_vcs) + if installed_vcs: + err_msg = "MSVC version '{}' was not found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly.\n" \ + " Installed versions are: {}".format(version, installed_vcs) else: - # should never get here due to early exit in msvc_setup_env - if not installed_vcs: - err_msg = "MSVC default version was not found.\n" \ - " No versions of the MSVC compiler were found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly" - else: - # should be impossible: version is None and len(installed_vcs) > 0 - err_msg = "MSVC default version was not found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly.\n" \ - " Installed versions are: {}".format(installed_vcs) + err_msg = "MSVC version '{}' was not found.\n" \ + " No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly".format(version) raise MSVCVersionNotFound(err_msg) return d -- cgit v0.12 From 35d0a4621711902e9d8ee1ddb625fc782dff5de3 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Tue, 26 Apr 2022 12:39:54 -0400 Subject: Replace msvc_exists in tools exists functions for msvc tools with msvc_setup_env_tool that also registers the tool name. The new function may indicate that the tool should be included even when no instances of msvc are installed. This is necessary for some error checking. Add a tool name argument to msvc_setup_env_once as well. Add default msvc version detection. Add a global and environment local policy variable for handling warnings and/or exceptions: error, warn, ignore. By default warnings are produced. Update tests accordingly. --- SCons/Tool/MSCommon/__init__.py | 4 +- SCons/Tool/MSCommon/vc.py | 312 ++++++++++++++++++++- SCons/Tool/midl.py | 8 +- SCons/Tool/mslib.py | 8 +- SCons/Tool/mslink.py | 8 +- SCons/Tool/msvc.py | 8 +- SCons/Tool/msvs.py | 8 +- test/MSVC/msvc_badversion.py | 14 + test/MSVC/no_msvc.py | 8 +- test/fixture/no_msvc/no_msvcs_sconstruct.py | 1 + .../fixture/no_msvc/no_msvcs_sconstruct_version.py | 2 + 11 files changed, 349 insertions(+), 32 deletions(-) diff --git a/SCons/Tool/MSCommon/__init__.py b/SCons/Tool/MSCommon/__init__.py index 50eed73..9d8a8ff 100644 --- a/SCons/Tool/MSCommon/__init__.py +++ b/SCons/Tool/MSCommon/__init__.py @@ -34,10 +34,12 @@ from SCons.Tool.MSCommon.sdk import mssdk_exists, mssdk_setup_env from SCons.Tool.MSCommon.vc import ( msvc_exists, - msvc_setup_env, + msvc_setup_env_tool, msvc_setup_env_once, msvc_version_to_maj_min, msvc_find_vswhere, + set_msvc_notfound_policy, + get_msvc_notfound_policy, ) from SCons.Tool.MSCommon.vs import ( diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 0b25ed5..c100663 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -45,6 +45,7 @@ import os import platform from string import digits as string_digits from subprocess import PIPE +import re import SCons.Util import SCons.Warnings @@ -82,6 +83,27 @@ class MSVCScriptNotFound(VisualCException): class MSVCVersionNotFound(VisualCException): pass +# MSVC_NOTFOUND_POLICY: +# error: raise exception +# warn: issue warning and continue +# ignore: continue +_MSVC_NOTFOUND_POLICY_DEFAULT = False +_MSVC_NOTFOUND_POLICY = _MSVC_NOTFOUND_POLICY_DEFAULT + +_MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC = [] +_MSVC_NOTFOUND_POLICY_SYMBOLS_DICT = {} + +for value, symbol_list in [ + (True, ['Error', 'Exception']), + (False, ['Warn', 'Warning']), + (None, ['Ignore', 'Suppress']), +]: + for symbol in symbol_list: + _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC.append(symbol.lower()) + _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol] = value + _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol.lower()] = value + _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol.upper()] = value + # Dict to 'canonalize' the arch _ARCH_TO_CANONICAL = { "amd64" : "amd64", @@ -718,6 +740,7 @@ def reset_installed_vcs(): """Make it try again to find VC. This is just for the tests.""" global __INSTALLED_VCS_RUN __INSTALLED_VCS_RUN = None + _MSVCSetupEnvDefault.reset() # 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'" @@ -762,6 +785,248 @@ def script_env(script, args=None): return cache_data +def _msvc_notfound_policy_lookup(symbol): + + try: + notfound_policy = _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol] + except KeyError: + err_msg = "Value specified for MSVC_NOTFOUND_POLICY is not supported: {}.\n" \ + " Valid values are: {}".format( + repr(symbol), + ', '.join([repr(s) for s in _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC]) + ) + raise ValueError(err_msg) + + return notfound_policy + +def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): + global _MSVC_NOTFOUND_POLICY + + if MSVC_NOTFOUND_POLICY is not None: + _MSVC_NOTFOUND_POLICY = _msvc_notfound_policy_lookup(MSVC_NOTFOUND_POLICY) + + return _MSVC_NOTFOUND_POLICY + +def get_msvc_notfound_policy(): + return _MSVC_NOTFOUND_POLICY + +def _msvc_notfound_policy_handler(env, msg): + + if env and 'MSVC_NOTFOUND_POLICY' in env: + # use environment setting + notfound_policy = _msvc_notfound_policy_lookup(env['MSVC_NOTFOUND_POLICY']) + else: + # use active global setting + notfound_policy = _MSVC_NOTFOUND_POLICY + + if notfound_policy is None: + debug('notfound policy: ignore') + elif notfound_policy: + debug('notfound policy: exception') + raise MSVCVersionNotFound(msg) + else: + debug('notfound policy: warning') + SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) + +class _MSVCSetupEnvDefault: + + # Determine if and/or when an error/warning should be issued when there + # are no versions of msvc installed. If there is at least one version of + # msvc installed, these routines do (almost) nothing. + + # Notes: + # * When msvc is the default compiler because there are no compilers + # installed, a build may fail due to the cl.exe command not being + # recognized. Currently, there is no easy way to detect during + # msvc initialization if the default environment will be used later + # to build a program and/or library. There is no error/warning + # as there are legitimate SCons uses that do not require a c compiler. + # * As implemented, the default is that a warning is issued. This can + # be changed globally via the function set_msvc_notfound_policy and/or + # through the environment via the MSVC_NOTFOUND_POLICY variable. + + separator = r';' + + need_init = True + + @classmethod + def reset(cls): + cls.n_setup = 0 # number of calls to msvc_setup_env_once + cls.default_ismsvc = False # is msvc the default compiler + cls.default_tools_re_list = [] # list of default tools regular expressions + cls.msvc_tools_init = set() # tools registered via msvc_exists + cls.msvc_tools = None # tools registered via msvc_setup_env_once + cls.msvc_installed = False # is msvc installed (vcs_installed > 0) + cls.msvc_nodefault = False # is there a default version of msvc + cls.need_init = False # clear initialization indicator + + @classmethod + def _initialize(cls, env): + if cls.need_init: + cls.reset() + vcs = get_installed_vcs(env) + cls.msvc_installed = len(vcs) > 0 + debug('msvc default:initialize:msvc_installed=%s', cls.msvc_installed) + + @classmethod + def register_tool(cls, env, tool): + if cls.need_init: + cls._initialize(env) + if cls.msvc_installed: + return None + if not tool: + return None + if cls.n_setup == 0: + if tool not in cls.msvc_tools_init: + cls.msvc_tools_init.add(tool) + debug('msvc default:register tool:tool=%s msvc_tools_init=%s', tool, cls.msvc_tools_init) + return None + if tool not in cls.msvc_tools: + cls.msvc_tools.add(tool) + debug('msvc default:register tool:tool=%s msvc_tools=%s', tool, cls.msvc_tools) + + @classmethod + def register_setup(cls, env): + if cls.need_init: + cls._initialize(env) + cls.n_setup += 1 + if not cls.msvc_installed: + cls.msvc_tools = set(cls.msvc_tools_init) + if cls.n_setup == 1: + tool_list = env.get('TOOLS', None) + if tool_list and tool_list[0] == 'default': + if len(tool_list) > 1 and tool_list[1] in cls.msvc_tools: + # msvc tools are the default compiler + cls.default_ismsvc = True + cls.msvc_nodefault = False + debug( + 'msvc default:register setup:n=%d msvc_installed=%s default_ismsvc=%s', + cls.n_setup, cls.msvc_installed, cls.default_ismsvc + ) + + @classmethod + def set_nodefault(cls): + # default msvc version, msvc not installed + cls.msvc_nodefault = True + debug('msvc default:set nodefault:msvc_nodefault=%s', cls.msvc_nodefault) + + @classmethod + def register_iserror(cls, env, tool): + + cls.register_tool(env, tool) + + if cls.msvc_installed: + # msvc installed + return None + + if not cls.msvc_nodefault: + # msvc version specified + return None + + tool_list = env.get('TOOLS', None) + if not tool_list: + # tool list is empty + return None + + debug( + 'msvc default:register iserror:n=%s default_ismsvc=%s msvc_tools=%s tool_list=%s', + cls.n_setup, cls.default_ismsvc, cls.msvc_tools, tool_list + ) + + if not cls.default_ismsvc: + + # Summary: + # * msvc is not installed + # * msvc version not specified (default) + # * msvc is not the default compiler + + # construct tools set + tools_set = set(tool_list) + + else: + + if cls.n_setup == 1: + # first setup and msvc is default compiler: + # build default tools regex for current tool state + tools = cls.separator.join(tool_list) + tools_nchar = len(tools) + debug('msvc default:register iserror:add regex nchar=%d, tools=%s', tools_nchar, tools) + re_default_tools = re.compile(re.escape(tools)) + cls.default_tools_re_list.insert(0, (tools_nchar, re_default_tools)) + # early exit: no error for default environment when msvc is not installed + return None + + # Summary: + # * msvc is not installed + # * msvc version not specified (default) + # * environment tools list is not empty + # * default tools regex list constructed + # * msvc tools set constructed + # + # Algorithm using tools string and sets: + # * convert environment tools list to a string + # * iteratively remove default tools sequences via regex + # substition list built from longest sequence (first) + # to shortest sequence (last) + # * build environment tools set with remaining tools + # * compute intersection of environment tools and msvc tools sets + # * if the intersection is: + # empty - no error: default tools and/or no additional msvc tools + # not empty - error: user specified one or more msvc tool(s) + # + # This will not produce an error or warning when there are no + # msvc installed instances nor any other recognized compilers + # and the default environment is needed for a build. The msvc + # compiler is forcibly added to the environment tools list when + # there are no compilers installed on win32. In this case, cl.exe + # will not be found on the path resulting in a failed build. + + # construct tools string + tools = cls.separator.join(tool_list) + tools_nchar = len(tools) + + debug('msvc default:register iserror:nchar=%d tools=%s', tools_nchar, tools) + + # iteratively remove default tool sequences (longest to shortest) + re_nchar_min, re_tools_min = cls.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 cls.default_tools_re_list: + if tools_nchar < re_nchar: + # not enough characters for pattern + continue + tools = re_default_tool.sub('', tools).strip(cls.separator) + tools_nchar = len(tools) + debug('msvc default:register iserror: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(cls.separator) if msvc_tool} + + debug('msvc default:register iserror:tools=%s', tools_set) + if not tools_set: + return None + + # compute intersection of remaining tools set and msvc tools set + tools_found = cls.msvc_tools.intersection(tools_set) + debug('msvc default:register iserror:tools_exist=%s', tools_found) + if not tools_found: + return None + + # construct in same order as tools list + tools_found_list = [] + seen_tool = set() + for tool in tool_list: + if tool not in seen_tool: + seen_tool.add(tool) + if tool in tools_found: + tools_found_list.append(tool) + + # return tool list in order presented + return tools_found_list + def get_default_version(env): msvc_version = env.get('MSVC_VERSION') msvs_version = env.get('MSVS_VERSION') @@ -796,16 +1061,24 @@ def get_default_version(env): return msvc_version -def msvc_setup_env_once(env): +def msvc_setup_env_once(env, tool=None): try: has_run = env["MSVC_SETUP_RUN"] except KeyError: has_run = False if not has_run: + _MSVCSetupEnvDefault.register_setup(env) msvc_setup_env(env) env["MSVC_SETUP_RUN"] = True + req_tools = _MSVCSetupEnvDefault.register_iserror(env, tool) + if req_tools: + msg = "No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly.\n" \ + " Requested tool(s) are: {}".format(req_tools) + _msvc_notfound_policy_handler(env, msg) + def msvc_find_valid_batch_script(env, version): """Find and execute appropriate batch script to set up build env. @@ -920,22 +1193,23 @@ def msvc_find_valid_batch_script(env, version): env['TARGET_ARCH']=req_target_platform if version_installed: - err_msg = "MSVC version '{}' working host/target script was not found.\n" \ - " Host = '{}', Target = '{}'\n" \ - " Visual Studio C/C++ compilers may not be set correctly".format( - version, host_platform, target_platform - ) + msg = "MSVC version '{}' working host/target script was not found.\n" \ + " Host = '{}', Target = '{}'\n" \ + " Visual Studio C/C++ compilers may not be set correctly".format( + version, host_platform, target_platform + ) else: installed_vcs = get_installed_vcs(env) if installed_vcs: - err_msg = "MSVC version '{}' was not found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly.\n" \ - " Installed versions are: {}".format(version, installed_vcs) + msg = "MSVC version '{}' was not found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly.\n" \ + " Installed versions are: {}".format(version, installed_vcs) else: - err_msg = "MSVC version '{}' was not found.\n" \ - " No versions of the MSVC compiler were found.\n" \ - " Visual Studio C/C++ compilers may not be set correctly".format(version) - raise MSVCVersionNotFound(err_msg) + msg = "MSVC version '{}' was not found.\n" \ + " No versions of the MSVC compiler were found.\n" \ + " Visual Studio C/C++ compilers may not be set correctly".format(version) + + _msvc_notfound_policy_handler(env, msg) return d @@ -943,6 +1217,7 @@ def msvc_setup_env(env): debug('called') version = get_default_version(env) if version is None: + _MSVCSetupEnvDefault.set_nodefault() return None # XXX: we set-up both MSVS version for backward @@ -991,3 +1266,14 @@ def msvc_exists(env=None, version=None): if version is None: return len(vcs) > 0 return version in vcs + +def msvc_setup_env_tool(env=None, version=None, tool=None): + _MSVCSetupEnvDefault.register_tool(env, tool) + if msvc_exists(env, version): + return True + if env: + for key in ('MSVC_VERSION', 'MSVS_VERSION'): + if key in env: + return True + return False + diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py index 2757c34..22cdd85 100644 --- a/SCons/Tool/midl.py +++ b/SCons/Tool/midl.py @@ -33,13 +33,17 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +import os + import SCons.Action import SCons.Builder import SCons.Defaults import SCons.Scanner.IDL import SCons.Util -from .MSCommon import msvc_exists +from .MSCommon import msvc_setup_env_tool + +tool_name = os.path.splitext(os.path.basename(__file__))[0] def midl_emitter(target, source, env): """Produces a list of outputs from the MIDL compiler""" @@ -79,7 +83,7 @@ def generate(env): env['BUILDERS']['TypeLibrary'] = midl_builder def exists(env): - return msvc_exists(env) + return msvc_setup_env_tool(env, tool=tool_name) # Local Variables: # tab-width:4 diff --git a/SCons/Tool/mslib.py b/SCons/Tool/mslib.py index 354f5cf..cbeaa7f 100644 --- a/SCons/Tool/mslib.py +++ b/SCons/Tool/mslib.py @@ -41,14 +41,16 @@ import SCons.Tool.msvs import SCons.Tool.msvc import SCons.Util -from .MSCommon import msvc_exists, msvc_setup_env_once +from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once + +tool_name = os.path.splitext(os.path.basename(__file__))[0] def generate(env): """Add Builders and construction variables for lib to an Environment.""" SCons.Tool.createStaticLibBuilder(env) # Set-up ms tools paths - msvc_setup_env_once(env) + msvc_setup_env_once(env, tool=tool_name) env['AR'] = 'lib' env['ARFLAGS'] = SCons.Util.CLVar('/nologo') @@ -64,7 +66,7 @@ def generate(env): def exists(env): - return msvc_exists(env) + return msvc_setup_env_tool(env, tool=tool_name) # Local Variables: # tab-width:4 diff --git a/SCons/Tool/mslink.py b/SCons/Tool/mslink.py index 3dac7f0..1376020 100644 --- a/SCons/Tool/mslink.py +++ b/SCons/Tool/mslink.py @@ -43,9 +43,11 @@ import SCons.Tool.msvc import SCons.Tool.msvs import SCons.Util -from .MSCommon import msvc_setup_env_once, msvc_exists +from .MSCommon import msvc_setup_env_once, msvc_setup_env_tool from .MSCommon.common import get_pch_node +tool_name = os.path.splitext(os.path.basename(__file__))[0] + def pdbGenerator(env, target, source, for_signature): try: return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG'] @@ -307,7 +309,7 @@ def generate(env): env['_MANIFEST_SOURCES'] = None # _windowsManifestSources # Set-up ms tools paths - msvc_setup_env_once(env) + msvc_setup_env_once(env, tool=tool_name) # Loadable modules are on Windows the same as shared libraries, but they # are subject to different build parameters (LDMODULE* variables). @@ -330,7 +332,7 @@ def generate(env): env['TEMPFILEARGJOIN'] = os.linesep def exists(env): - return msvc_exists(env) + return msvc_setup_env_tool(env, tool=tool_name) # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msvc.py b/SCons/Tool/msvc.py index f2cd418..ee876ac 100644 --- a/SCons/Tool/msvc.py +++ b/SCons/Tool/msvc.py @@ -44,9 +44,11 @@ import SCons.Util import SCons.Warnings import SCons.Scanner.RC -from .MSCommon import msvc_exists, msvc_setup_env_once, msvc_version_to_maj_min, msvc_find_vswhere +from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once, msvc_version_to_maj_min, msvc_find_vswhere from .MSCommon.common import get_pch_node +tool_name = os.path.splitext(os.path.basename(__file__))[0] + CSuffixes = ['.c', '.C'] CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] @@ -293,7 +295,7 @@ def generate(env): env['VSWHERE'] = env.get('VSWHERE', msvc_find_vswhere()) # Set-up ms tools paths - msvc_setup_env_once(env) + msvc_setup_env_once(env, tool=tool_name) env['CFILESUFFIX'] = '.c' env['CXXFILESUFFIX'] = '.cc' @@ -319,7 +321,7 @@ def generate(env): def exists(env): - return msvc_exists(env) + return msvc_setup_env_tool(env, tool=tool_name) # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index 887cb59..2eae8ee 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -45,7 +45,9 @@ import SCons.Util import SCons.Warnings from SCons.Defaults import processDefines from SCons.compat import PICKLE_PROTOCOL -from .MSCommon import msvc_exists, msvc_setup_env_once +from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once + +tool_name = os.path.splitext(os.path.basename(__file__))[0] ############################################################################## # Below here are the classes and functions for generation of @@ -2077,7 +2079,7 @@ def generate(env): env['MSVSCLEANCOM'] = '$MSVSSCONSCOM -c "$MSVSBUILDTARGET"' # Set-up ms tools paths for default version - msvc_setup_env_once(env) + msvc_setup_env_once(env, tool=tool_name) if 'MSVS_VERSION' in env: version_num, suite = msvs_parse_version(env['MSVS_VERSION']) @@ -2107,7 +2109,7 @@ def generate(env): env['SCONS_HOME'] = os.environ.get('SCONS_HOME') def exists(env): - return msvc_exists(env) + return msvc_setup_env_tool(env, tool=tool_name) # Local Variables: # tab-width:4 diff --git a/test/MSVC/msvc_badversion.py b/test/MSVC/msvc_badversion.py index 7af8ca5..ce419a8 100644 --- a/test/MSVC/msvc_badversion.py +++ b/test/MSVC/msvc_badversion.py @@ -47,7 +47,21 @@ installed_msvc_versions = msvc.get_installed_vcs() test.write('SConstruct', """\ env = Environment(MSVC_VERSION='12.9') """) +test.run(arguments='-Q -s', stdout='') +test.write('SConstruct', """\ +env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='ignore') +""") +test.run(arguments='-Q -s', stdout='') + +test.write('SConstruct', """\ +env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='warning') +""") +test.run(arguments='-Q -s', stdout='') + +test.write('SConstruct', """\ +env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='error') +""") test.run(arguments='-Q -s', status=2, stderr=r"^.*MSVCVersionNotFound.+", match=TestSCons.match_re_dotall) test.pass_test() diff --git a/test/MSVC/no_msvc.py b/test/MSVC/no_msvc.py index 683951e..4ab7dd8 100644 --- a/test/MSVC/no_msvc.py +++ b/test/MSVC/no_msvc.py @@ -43,7 +43,10 @@ test.run(arguments='-Q -s', stdout='') # test no msvc's test.file_fixture('no_msvc/no_msvcs_sconstruct.py', 'SConstruct') -test.run(arguments='-Q -s', stdout='') +test.run(arguments='-Q -s') + +if 'MSVC_VERSION=None' not in test.stdout(): + test.fail_test() # test msvc version number request with no msvc's test.file_fixture('no_msvc/no_msvcs_sconstruct_version.py', 'SConstruct') @@ -64,8 +67,5 @@ def exists(env): test.file_fixture('no_msvc/no_msvcs_sconstruct_tools.py', 'SConstruct') test.run(arguments='-Q -s') -test.file_fixture('no_msvc/no_msvcs_sconstruct_tools.py', 'SConstruct') -test.run(arguments='-Q -s') - test.pass_test() diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct.py b/test/fixture/no_msvc/no_msvcs_sconstruct.py index 590142b..18366d8 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct.py @@ -12,3 +12,4 @@ SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere env = SCons.Environment.Environment() +print('MSVC_VERSION='+str(env.get('MSVC_VERSION'))) \ No newline at end of file diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_version.py b/test/fixture/no_msvc/no_msvcs_sconstruct_version.py index 81d47cf..f5cabf7 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_version.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_version.py @@ -10,5 +10,7 @@ for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere +SCons.Tool.MSCommon.set_msvc_notfound_policy('error') + env = SCons.Environment.Environment(MSVC_VERSION='14.3') -- cgit v0.12 From 51aadabc68d29c0f5ef2c782c3573092e2606ec0 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Fri, 29 Apr 2022 12:38:35 -0400 Subject: Return previous policy when setting msvc notfound policy --- SCons/Tool/MSCommon/vc.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index c100663..57e44ee 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -802,10 +802,12 @@ def _msvc_notfound_policy_lookup(symbol): def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): global _MSVC_NOTFOUND_POLICY + prev_policy = _MSVC_NOTFOUND_POLICY + if MSVC_NOTFOUND_POLICY is not None: _MSVC_NOTFOUND_POLICY = _msvc_notfound_policy_lookup(MSVC_NOTFOUND_POLICY) - return _MSVC_NOTFOUND_POLICY + return prev_policy def get_msvc_notfound_policy(): return _MSVC_NOTFOUND_POLICY -- cgit v0.12 From 7572fe5e0a721c7e85d0d3681c8f50bfcb09b944 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 2 May 2022 09:29:54 -0400 Subject: Fix set/get notfound policy to return policy symbol instead of internal policy, fix initialization state, rework debug statements. --- SCons/Tool/MSCommon/vc.py | 90 +++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 57e44ee..4c417f2 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -90,14 +90,16 @@ class MSVCVersionNotFound(VisualCException): _MSVC_NOTFOUND_POLICY_DEFAULT = False _MSVC_NOTFOUND_POLICY = _MSVC_NOTFOUND_POLICY_DEFAULT +_MSVC_NOTFOUND_POLICY_REVERSE_DICT = {} _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC = [] _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT = {} for value, symbol_list in [ - (True, ['Error', 'Exception']), - (False, ['Warn', 'Warning']), - (None, ['Ignore', 'Suppress']), + (True, ['Error', 'Exception']), + (False, ['Warning', 'Warn']), + (None, ['Ignore', 'Suppress']), ]: + _MSVC_NOTFOUND_POLICY_REVERSE_DICT[value] = symbol_list[0].lower() for symbol in symbol_list: _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC.append(symbol.lower()) _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol] = value @@ -802,15 +804,19 @@ def _msvc_notfound_policy_lookup(symbol): def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): global _MSVC_NOTFOUND_POLICY - prev_policy = _MSVC_NOTFOUND_POLICY + prev_policy = _MSVC_NOTFOUND_POLICY_REVERSE_DICT[_MSVC_NOTFOUND_POLICY] - if MSVC_NOTFOUND_POLICY is not None: - _MSVC_NOTFOUND_POLICY = _msvc_notfound_policy_lookup(MSVC_NOTFOUND_POLICY) + policy = MSVC_NOTFOUND_POLICY + if policy is not None: + _MSVC_NOTFOUND_POLICY = _msvc_notfound_policy_lookup(policy) + debug('prev_policy=%s, policy=%s, internal_policy=%s', repr(prev_policy), repr(policy), _MSVC_NOTFOUND_POLICY) return prev_policy def get_msvc_notfound_policy(): - return _MSVC_NOTFOUND_POLICY + policy = _MSVC_NOTFOUND_POLICY_REVERSE_DICT[_MSVC_NOTFOUND_POLICY] + debug('policy=%s, internal_policy=%s', repr(policy), _MSVC_NOTFOUND_POLICY) + return policy def _msvc_notfound_policy_handler(env, msg): @@ -821,13 +827,14 @@ def _msvc_notfound_policy_handler(env, msg): # use active global setting notfound_policy = _MSVC_NOTFOUND_POLICY + debug('policy=%s, internal_policy=%s', _MSVC_NOTFOUND_POLICY_REVERSE_DICT[notfound_policy], repr(notfound_policy)) + if notfound_policy is None: - debug('notfound policy: ignore') + # ignore + pass elif notfound_policy: - debug('notfound policy: exception') raise MSVCVersionNotFound(msg) else: - debug('notfound policy: warning') SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) class _MSVCSetupEnvDefault: @@ -853,6 +860,7 @@ class _MSVCSetupEnvDefault: @classmethod def reset(cls): + debug('msvc default:init') cls.n_setup = 0 # number of calls to msvc_setup_env_once cls.default_ismsvc = False # is msvc the default compiler cls.default_tools_re_list = [] # list of default tools regular expressions @@ -860,18 +868,20 @@ class _MSVCSetupEnvDefault: cls.msvc_tools = None # tools registered via msvc_setup_env_once cls.msvc_installed = False # is msvc installed (vcs_installed > 0) cls.msvc_nodefault = False # is there a default version of msvc - cls.need_init = False # clear initialization indicator + cls.need_init = True # reset initialization indicator @classmethod def _initialize(cls, env): if cls.need_init: cls.reset() + cls.need_init = False vcs = get_installed_vcs(env) cls.msvc_installed = len(vcs) > 0 - debug('msvc default:initialize:msvc_installed=%s', cls.msvc_installed) + debug('msvc default:msvc_installed=%s', cls.msvc_installed) @classmethod def register_tool(cls, env, tool): + debug('msvc default:tool=%s', tool) if cls.need_init: cls._initialize(env) if cls.msvc_installed: @@ -881,14 +891,15 @@ class _MSVCSetupEnvDefault: if cls.n_setup == 0: if tool not in cls.msvc_tools_init: cls.msvc_tools_init.add(tool) - debug('msvc default:register tool:tool=%s msvc_tools_init=%s', tool, cls.msvc_tools_init) + debug('msvc default:tool=%s, msvc_tools_init=%s', tool, cls.msvc_tools_init) return None if tool not in cls.msvc_tools: cls.msvc_tools.add(tool) - debug('msvc default:register tool:tool=%s msvc_tools=%s', tool, cls.msvc_tools) + debug('msvc default:tool=%s, msvc_tools=%s', tool, cls.msvc_tools) @classmethod def register_setup(cls, env): + debug('msvc default') if cls.need_init: cls._initialize(env) cls.n_setup += 1 @@ -902,7 +913,7 @@ class _MSVCSetupEnvDefault: cls.default_ismsvc = True cls.msvc_nodefault = False debug( - 'msvc default:register setup:n=%d msvc_installed=%s default_ismsvc=%s', + 'msvc default:n_setup=%d, msvc_installed=%s, default_ismsvc=%s', cls.n_setup, cls.msvc_installed, cls.default_ismsvc ) @@ -910,7 +921,7 @@ class _MSVCSetupEnvDefault: def set_nodefault(cls): # default msvc version, msvc not installed cls.msvc_nodefault = True - debug('msvc default:set nodefault:msvc_nodefault=%s', cls.msvc_nodefault) + debug('msvc default:msvc_nodefault=%s', cls.msvc_nodefault) @classmethod def register_iserror(cls, env, tool): @@ -931,7 +942,7 @@ class _MSVCSetupEnvDefault: return None debug( - 'msvc default:register iserror:n=%s default_ismsvc=%s msvc_tools=%s tool_list=%s', + 'msvc default:n_setup=%s, default_ismsvc=%s, msvc_tools=%s, tool_list=%s', cls.n_setup, cls.default_ismsvc, cls.msvc_tools, tool_list ) @@ -952,7 +963,7 @@ class _MSVCSetupEnvDefault: # build default tools regex for current tool state tools = cls.separator.join(tool_list) tools_nchar = len(tools) - debug('msvc default:register iserror:add regex nchar=%d, tools=%s', tools_nchar, tools) + debug('msvc default:add regex:nchar=%d, tools=%s', tools_nchar, tools) re_default_tools = re.compile(re.escape(tools)) cls.default_tools_re_list.insert(0, (tools_nchar, re_default_tools)) # early exit: no error for default environment when msvc is not installed @@ -987,7 +998,7 @@ class _MSVCSetupEnvDefault: tools = cls.separator.join(tool_list) tools_nchar = len(tools) - debug('msvc default:register iserror:nchar=%d tools=%s', tools_nchar, tools) + 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 = cls.default_tools_re_list[-1] @@ -999,7 +1010,7 @@ class _MSVCSetupEnvDefault: continue tools = re_default_tool.sub('', tools).strip(cls.separator) tools_nchar = len(tools) - debug('msvc default:register iserror:nchar=%d tools=%s', tools_nchar, 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 @@ -1007,13 +1018,13 @@ class _MSVCSetupEnvDefault: # construct non-default list(s) tools set tools_set = {msvc_tool for msvc_tool in tools.split(cls.separator) if msvc_tool} - debug('msvc default:register iserror:tools=%s', tools_set) + debug('msvc default:tools=%s', tools_set) if not tools_set: return None # compute intersection of remaining tools set and msvc tools set tools_found = cls.msvc_tools.intersection(tools_set) - debug('msvc default:register iserror:tools_exist=%s', tools_found) + debug('msvc default:tools_exist=%s', tools_found) if not tools_found: return None @@ -1070,6 +1081,7 @@ def msvc_setup_env_once(env, tool=None): has_run = False if not has_run: + debug('tool=%s', repr(tool)) _MSVCSetupEnvDefault.register_setup(env) msvc_setup_env(env) env["MSVC_SETUP_RUN"] = True @@ -1264,18 +1276,34 @@ def msvc_setup_env(env): SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) def msvc_exists(env=None, version=None): + debug('version=%s', repr(version)) vcs = get_installed_vcs(env) if version is None: - return len(vcs) > 0 - return version in vcs + rval = len(vcs) > 0 + else: + rval = version in vcs + debug('version=%s, return=%s', repr(version), rval) + return rval -def msvc_setup_env_tool(env=None, version=None, tool=None): - _MSVCSetupEnvDefault.register_tool(env, tool) - if msvc_exists(env, version): - return True +def msvc_setup_env_user(env=None): + rval = False if env: - for key in ('MSVC_VERSION', 'MSVS_VERSION'): + for key in ('MSVC_VERSION', 'MSVS_VERSION', 'MSVC_USE_SCRIPT'): if key in env: - return True - return False + rval = True + debug('key=%s, return=%s', repr(key), rval) + return rval + debug('return=%s', rval) + return rval + +def msvc_setup_env_tool(env=None, version=None, tool=None): + debug('tool=%s, version=%s', repr(tool), repr(version)) + _MSVCSetupEnvDefault.register_tool(env, tool) + rval = False + if not rval and msvc_exists(env, version): + rval = True + if not rval and msvc_setup_env_user(env): + rval = True + debug('tool=%s, version=%s, return=%s', repr(tool), repr(version), rval) + return rval -- cgit v0.12 From 6d7bf1ec0efac43c2158ed21653a8070fba91f35 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 2 May 2022 11:29:41 -0400 Subject: Rename internal notfound policy dictionary. --- SCons/Tool/MSCommon/vc.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 4c417f2..ec81eaf 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -90,7 +90,7 @@ class MSVCVersionNotFound(VisualCException): _MSVC_NOTFOUND_POLICY_DEFAULT = False _MSVC_NOTFOUND_POLICY = _MSVC_NOTFOUND_POLICY_DEFAULT -_MSVC_NOTFOUND_POLICY_REVERSE_DICT = {} +_MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL = {} _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC = [] _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT = {} @@ -99,7 +99,7 @@ for value, symbol_list in [ (False, ['Warning', 'Warn']), (None, ['Ignore', 'Suppress']), ]: - _MSVC_NOTFOUND_POLICY_REVERSE_DICT[value] = symbol_list[0].lower() + _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[value] = symbol_list[0].lower() for symbol in symbol_list: _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC.append(symbol.lower()) _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol] = value @@ -804,7 +804,7 @@ def _msvc_notfound_policy_lookup(symbol): def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): global _MSVC_NOTFOUND_POLICY - prev_policy = _MSVC_NOTFOUND_POLICY_REVERSE_DICT[_MSVC_NOTFOUND_POLICY] + prev_policy = _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[_MSVC_NOTFOUND_POLICY] policy = MSVC_NOTFOUND_POLICY if policy is not None: @@ -814,7 +814,7 @@ def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): return prev_policy def get_msvc_notfound_policy(): - policy = _MSVC_NOTFOUND_POLICY_REVERSE_DICT[_MSVC_NOTFOUND_POLICY] + policy = _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[_MSVC_NOTFOUND_POLICY] debug('policy=%s, internal_policy=%s', repr(policy), _MSVC_NOTFOUND_POLICY) return policy @@ -827,7 +827,7 @@ def _msvc_notfound_policy_handler(env, msg): # use active global setting notfound_policy = _MSVC_NOTFOUND_POLICY - debug('policy=%s, internal_policy=%s', _MSVC_NOTFOUND_POLICY_REVERSE_DICT[notfound_policy], repr(notfound_policy)) + debug('policy=%s, internal_policy=%s', _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[notfound_policy], repr(notfound_policy)) if notfound_policy is None: # ignore -- cgit v0.12 From cc81a44b0095ad2e9df68e20aa9d3e4ce6f4dff9 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sun, 15 May 2022 16:08:38 -0400 Subject: Hard-code tool name instead of deriving from file name --- SCons/Tool/midl.py | 2 +- SCons/Tool/mslib.py | 2 +- SCons/Tool/mslink.py | 2 +- SCons/Tool/msvc.py | 2 +- SCons/Tool/msvs.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py index 22cdd85..72d7696 100644 --- a/SCons/Tool/midl.py +++ b/SCons/Tool/midl.py @@ -43,7 +43,7 @@ import SCons.Util from .MSCommon import msvc_setup_env_tool -tool_name = os.path.splitext(os.path.basename(__file__))[0] +tool_name = 'midl' def midl_emitter(target, source, env): """Produces a list of outputs from the MIDL compiler""" diff --git a/SCons/Tool/mslib.py b/SCons/Tool/mslib.py index cbeaa7f..be4088b 100644 --- a/SCons/Tool/mslib.py +++ b/SCons/Tool/mslib.py @@ -43,7 +43,7 @@ import SCons.Util from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once -tool_name = os.path.splitext(os.path.basename(__file__))[0] +tool_name = 'mslib' def generate(env): """Add Builders and construction variables for lib to an Environment.""" diff --git a/SCons/Tool/mslink.py b/SCons/Tool/mslink.py index 1376020..2a90e17 100644 --- a/SCons/Tool/mslink.py +++ b/SCons/Tool/mslink.py @@ -46,7 +46,7 @@ import SCons.Util from .MSCommon import msvc_setup_env_once, msvc_setup_env_tool from .MSCommon.common import get_pch_node -tool_name = os.path.splitext(os.path.basename(__file__))[0] +tool_name = 'mslink' def pdbGenerator(env, target, source, for_signature): try: diff --git a/SCons/Tool/msvc.py b/SCons/Tool/msvc.py index ae47fdd..191d2cc 100644 --- a/SCons/Tool/msvc.py +++ b/SCons/Tool/msvc.py @@ -47,7 +47,7 @@ import SCons.Scanner.RC from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once, msvc_version_to_maj_min, msvc_find_vswhere from .MSCommon.common import get_pch_node -tool_name = os.path.splitext(os.path.basename(__file__))[0] +tool_name = 'msvc' CSuffixes = ['.c', '.C'] CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index 2eae8ee..86df1ef 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -47,7 +47,7 @@ from SCons.Defaults import processDefines from SCons.compat import PICKLE_PROTOCOL from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once -tool_name = os.path.splitext(os.path.basename(__file__))[0] +tool_name = 'msvs' ############################################################################## # Below here are the classes and functions for generation of -- cgit v0.12 From a90c14216220dcdf1112da7c3aff52b795c3b8a1 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sun, 15 May 2022 16:12:46 -0400 Subject: Update test script header with template/test.py header --- test/MSVC/msvc_badversion.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/MSVC/msvc_badversion.py b/test/MSVC/msvc_badversion.py index ce419a8..a36bd2b 100644 --- a/test/MSVC/msvc_badversion.py +++ b/test/MSVC/msvc_badversion.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # 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. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test scons with an invalid MSVC version when at least one MSVC is present. -- cgit v0.12 From 053f220e789a42e104faa29b467fb224fc1468e5 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sun, 15 May 2022 20:29:20 -0400 Subject: Fix tool name in test fixture --- test/fixture/no_msvc/no_msvcs_sconstruct_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py b/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py index ca9b699..9aa924b 100644 --- a/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py +++ b/test/fixture/no_msvc/no_msvcs_sconstruct_tools.py @@ -10,5 +10,5 @@ for key in SCons.Tool.MSCommon.vc._VCVER_TO_PRODUCT_DIR: SCons.Tool.MSCommon.vc.find_vc_pdir_vswhere = DummyVsWhere -env = SCons.Environment.Environment(tools=['MYIGNOREDEFAULTMSVCTOOL']) +env = SCons.Environment.Environment(tools=['myignoredefaultmsvctool']) -- cgit v0.12 From 85159b73248da753504440d0fc39e868096ce770 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sun, 15 May 2022 20:56:04 -0400 Subject: Remove unnecessary import --- SCons/Tool/midl.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py index 72d7696..3def928 100644 --- a/SCons/Tool/midl.py +++ b/SCons/Tool/midl.py @@ -33,8 +33,6 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import os - import SCons.Action import SCons.Builder import SCons.Defaults -- cgit v0.12 From 2efe7d108823f528bdfc162ea9aae572914ae383 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 18 May 2022 16:10:03 -0700 Subject: [ci skip] fix sider complaint. Reformat. Update file header to current standard --- SCons/Tool/midl.py | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py index 72d7696..c25ce69 100644 --- a/SCons/Tool/midl.py +++ b/SCons/Tool/midl.py @@ -1,15 +1,6 @@ -"""SCons.Tool.midl - -Tool-specific initialization for midl (Microsoft IDL compiler). - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,11 +20,16 @@ selection method. # 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. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""SCons.Tool.midl -import os +Tool-specific initialization for midl (Microsoft IDL compiler). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" import SCons.Action import SCons.Builder @@ -45,6 +41,7 @@ from .MSCommon import msvc_setup_env_tool tool_name = 'midl' + def midl_emitter(target, source, env): """Produces a list of outputs from the MIDL compiler""" base, _ = SCons.Util.splitext(str(target[0])) @@ -62,26 +59,29 @@ def midl_emitter(target, source, env): dlldata = base + '_data.c' targets.append(dlldata) - return (targets, source) + return targets, source + idl_scanner = SCons.Scanner.IDL.IDLScan() midl_action = SCons.Action.Action('$MIDLCOM', '$MIDLCOMSTR') -midl_builder = SCons.Builder.Builder(action = midl_action, - src_suffix = '.idl', +midl_builder = SCons.Builder.Builder(action=midl_action, + src_suffix='.idl', suffix='.tlb', - emitter = midl_emitter, - source_scanner = idl_scanner) + emitter=midl_emitter, + source_scanner=idl_scanner) + def generate(env): """Add Builders and construction variables for midl to an Environment.""" - env['MIDL'] = 'MIDL.EXE' - env['MIDLFLAGS'] = SCons.Util.CLVar('/nologo') - env['MIDLCOM'] = '$MIDL $MIDLFLAGS /tlb ${TARGETS[0]} /h ${TARGETS[1]} /iid ${TARGETS[2]} /proxy ${TARGETS[3]} /dlldata ${TARGETS[4]} $SOURCE 2> NUL' + env['MIDL'] = 'MIDL.EXE' + env['MIDLFLAGS'] = SCons.Util.CLVar('/nologo') + env['MIDLCOM'] = '$MIDL $MIDLFLAGS /tlb ${TARGETS[0]} /h ${TARGETS[1]} /iid ${TARGETS[2]} /proxy ${TARGETS[3]} /dlldata ${TARGETS[4]} $SOURCE 2> NUL' env['BUILDERS']['TypeLibrary'] = midl_builder + def exists(env): return msvc_setup_env_tool(env, tool=tool_name) -- cgit v0.12 From 0e51fe4467417350bc969c498698999b6f3b946e Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Thu, 19 May 2022 08:46:16 -0400 Subject: Change notfound policy parallel variables to namedtuple. Rework debug statement contents and formatting for notfound policy. Make comment for internal class a docstring per request. --- SCons/Tool/MSCommon/vc.py | 117 +++++++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 48 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 2dd28de..33faca2 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -91,28 +91,36 @@ class MSVCUseSettingsError(VisualCException): class MSVCVersionNotFound(VisualCException): pass -# MSVC_NOTFOUND_POLICY: -# error: raise exception -# warn: issue warning and continue -# ignore: continue -_MSVC_NOTFOUND_POLICY_DEFAULT = False -_MSVC_NOTFOUND_POLICY = _MSVC_NOTFOUND_POLICY_DEFAULT - -_MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL = {} -_MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC = [] -_MSVC_NOTFOUND_POLICY_SYMBOLS_DICT = {} - -for value, symbol_list in [ +# MSVC_NOTFOUND_POLICY definition: +# error: raise exception +# warning: issue warning and continue +# ignore: continue + +_MSVC_NOTFOUND_POLICY_DEFINITION = namedtuple('MSVCNotFoundPolicyDefinition', [ + 'value', + 'symbol', +]) + +_MSVC_NOTFOUND_POLICY_INTERNAL = {} +_MSVC_NOTFOUND_POLICY_EXTERNAL = {} + +for policy_value, policy_symbol_list in [ (True, ['Error', 'Exception']), (False, ['Warning', 'Warn']), (None, ['Ignore', 'Suppress']), ]: - _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[value] = symbol_list[0].lower() - for symbol in symbol_list: - _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC.append(symbol.lower()) - _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol] = value - _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol.lower()] = value - _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol.upper()] = value + + policy_symbol = policy_symbol_list[0].lower() + policy_def = _MSVC_NOTFOUND_POLICY_DEFINITION(policy_value, policy_symbol) + + _MSVC_NOTFOUND_POLICY_INTERNAL[policy_symbol] = policy_def + + for policy_symbol in policy_symbol_list: + _MSVC_NOTFOUND_POLICY_EXTERNAL[policy_symbol.lower()] = policy_def + _MSVC_NOTFOUND_POLICY_EXTERNAL[policy_symbol] = policy_def + _MSVC_NOTFOUND_POLICY_EXTERNAL[policy_symbol.upper()] = policy_def + +_MSVC_NOTFOUND_POLICY_DEF = _MSVC_NOTFOUND_POLICY_INTERNAL['warning'] # Dict to 'canonalize' the arch _ARCH_TO_CANONICAL = { @@ -1050,69 +1058,82 @@ def script_env(script, args=None): def _msvc_notfound_policy_lookup(symbol): try: - notfound_policy = _MSVC_NOTFOUND_POLICY_SYMBOLS_DICT[symbol] + notfound_policy_def = _MSVC_NOTFOUND_POLICY_EXTERNAL[symbol] except KeyError: err_msg = "Value specified for MSVC_NOTFOUND_POLICY is not supported: {}.\n" \ " Valid values are: {}".format( repr(symbol), - ', '.join([repr(s) for s in _MSVC_NOTFOUND_POLICY_SYMBOLS_PUBLIC]) + ', '.join([repr(s) for s in _MSVC_NOTFOUND_POLICY_EXTERNAL.keys()]) ) raise ValueError(err_msg) - return notfound_policy + return notfound_policy_def def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): - global _MSVC_NOTFOUND_POLICY + global _MSVC_NOTFOUND_POLICY_DEF - prev_policy = _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[_MSVC_NOTFOUND_POLICY] + prev_policy = _MSVC_NOTFOUND_POLICY_DEF.symbol policy = MSVC_NOTFOUND_POLICY if policy is not None: - _MSVC_NOTFOUND_POLICY = _msvc_notfound_policy_lookup(policy) + _MSVC_NOTFOUND_POLICY_DEF = _msvc_notfound_policy_lookup(policy) + + debug( + 'prev_policy=%s, set_policy=%s, policy.symbol=%s, policy.value=%s', + repr(prev_policy), repr(policy), + repr(_MSVC_NOTFOUND_POLICY_DEF.symbol), repr(_MSVC_NOTFOUND_POLICY_DEF.value) + ) - debug('prev_policy=%s, policy=%s, internal_policy=%s', repr(prev_policy), repr(policy), _MSVC_NOTFOUND_POLICY) return prev_policy def get_msvc_notfound_policy(): - policy = _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[_MSVC_NOTFOUND_POLICY] - debug('policy=%s, internal_policy=%s', repr(policy), _MSVC_NOTFOUND_POLICY) - return policy + debug( + 'policy.symbol=%s, policy.value=%s', + repr(_MSVC_NOTFOUND_POLICY_DEF.symbol), repr(_MSVC_NOTFOUND_POLICY_DEF.value) + ) + return _MSVC_NOTFOUND_POLICY_DEF.symbol def _msvc_notfound_policy_handler(env, msg): if env and 'MSVC_NOTFOUND_POLICY' in env: # use environment setting - notfound_policy = _msvc_notfound_policy_lookup(env['MSVC_NOTFOUND_POLICY']) + notfound_policy_def = _msvc_notfound_policy_lookup(env['MSVC_NOTFOUND_POLICY']) + notfound_policy_src = 'environment' else: # use active global setting - notfound_policy = _MSVC_NOTFOUND_POLICY + notfound_policy_def = _MSVC_NOTFOUND_POLICY_DEF + notfound_policy_src = 'default' - debug('policy=%s, internal_policy=%s', _MSVC_NOTFOUND_POLICY_INTERNAL_SYMBOL[notfound_policy], repr(notfound_policy)) + debug( + 'source=%s, policy.symbol=%s, policy.value=%s', + notfound_policy_src, repr(notfound_policy_def.symbol), repr(notfound_policy_def.value) + ) - if notfound_policy is None: + if notfound_policy_def.value is None: # ignore pass - elif notfound_policy: + elif notfound_policy_def.value: raise MSVCVersionNotFound(msg) else: SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) class _MSVCSetupEnvDefault: - - # Determine if and/or when an error/warning should be issued when there - # are no versions of msvc installed. If there is at least one version of - # msvc installed, these routines do (almost) nothing. - - # Notes: - # * When msvc is the default compiler because there are no compilers - # installed, a build may fail due to the cl.exe command not being - # recognized. Currently, there is no easy way to detect during - # msvc initialization if the default environment will be used later - # to build a program and/or library. There is no error/warning - # as there are legitimate SCons uses that do not require a c compiler. - # * As implemented, the default is that a warning is issued. This can - # be changed globally via the function set_msvc_notfound_policy and/or - # through the environment via the MSVC_NOTFOUND_POLICY variable. + """ + Determine if and/or when an error/warning should be issued when there + are no versions of msvc installed. If there is at least one version of + msvc installed, these routines do (almost) nothing. + + Notes: + * When msvc is the default compiler because there are no compilers + installed, a build may fail due to the cl.exe command not being + recognized. Currently, there is no easy way to detect during + msvc initialization if the default environment will be used later + to build a program and/or library. There is no error/warning + as there are legitimate SCons uses that do not require a c compiler. + * As implemented, the default is that a warning is issued. This can + be changed globally via the function set_msvc_notfound_policy and/or + through the environment via the MSVC_NOTFOUND_POLICY variable. + """ separator = r';' -- cgit v0.12 From 479b123c6177fca85990b0d6890d9737a49016e2 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Thu, 19 May 2022 10:25:42 -0400 Subject: Treat environment notfound policy set to None the same as if undefined (default global setting) --- SCons/Tool/MSCommon/vc.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 33faca2..32d0e61 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -1096,17 +1096,24 @@ def get_msvc_notfound_policy(): def _msvc_notfound_policy_handler(env, msg): if env and 'MSVC_NOTFOUND_POLICY' in env: - # use environment setting - notfound_policy_def = _msvc_notfound_policy_lookup(env['MSVC_NOTFOUND_POLICY']) + # environment setting notfound_policy_src = 'environment' + policy = env['MSVC_NOTFOUND_POLICY'] + if policy is not None: + # user policy request + notfound_policy_def = _msvc_notfound_policy_lookup(policy) + else: + # active global setting + notfound_policy_def = _MSVC_NOTFOUND_POLICY_DEF else: - # use active global setting - notfound_policy_def = _MSVC_NOTFOUND_POLICY_DEF + # active global setting notfound_policy_src = 'default' + policy = None + notfound_policy_def = _MSVC_NOTFOUND_POLICY_DEF debug( - 'source=%s, policy.symbol=%s, policy.value=%s', - notfound_policy_src, repr(notfound_policy_def.symbol), repr(notfound_policy_def.value) + 'source=%s, set_policy=%s, policy.symbol=%s, policy.value=%s', + notfound_policy_src, repr(policy), repr(notfound_policy_def.symbol), repr(notfound_policy_def.value) ) if notfound_policy_def.value is None: -- cgit v0.12 From 6848757227a6b9e605be699d6f0b28445b3deede Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Sat, 21 May 2022 11:08:03 -0400 Subject: Update CHANGES.txt and RELEASE.txt. [ci skip] --- CHANGES.txt | 19 +++++++++++++++++++ RELEASE.txt | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 17121f4..3978b5b 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -48,6 +48,25 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER require delayed expansion to be enabled which is currently not supported and is typically not enabled by default on the host system. The batch files may also require environment variables that are not included by default in the msvc environment. + - Suppress issuing a warning when there are no installed Visual Studio instances for the default + tools configuration (issue #2813). When msvc is the default compiler because there are no + compilers installed, a build may fail due to the cl.exe command not being recognized. At + present, there is no easy way to detect during msvc initialization if the default environment + will be used later to build a program and/or library. There is no error/warning issued for the + default tools as there are legitimate SCons uses that do not require a c compiler. + - Added a global policy setting and an environment policy variable for specifying the action to + be taken when an msvc request cannot be satisfied. The available options are "error", + "exception", "warning", "warn", "ignore", and "suppress". The global policy variable may be + set and retrieved via the functions set_msvc_notfound_policy and get_msvc_notfound_policy, + respectively. These two methods may be imported from SCons.Tool.MSCommon. The environment + policy variable introduced is MSVC_NOTFOUND_POLICY. When defined, the environment policy + variable overrides the global policy setting for a given environment. When the active policy + is "error" or "exception", an MSVCVersionNotFound exception is raised. When the active policy + is "warning" or "warn", a VisualCMissingWarning warning is issued and the constructed + environment is likely incomplete. When the active policy is "ignore" or "suppress", no action + is taken and the constructed environment is likely incomplete. As implemented, the default + global policy is "warning". The ability to set the global policy via an SCons command-line + option may be added in a future enhancement. From William Deegan: - Fix check for unsupported Python version. It was broken. Also now the error message diff --git a/RELEASE.txt b/RELEASE.txt index 1a00d02..94bedaf 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -21,6 +21,19 @@ NEW FUNCTIONALITY be used in the shell command of some Action. - Added MSVC_USE_SETTINGS variable to pass a dictionary to configure the msvc compiler system environment as an alternative to bypassing Visual Studio autodetection entirely. +- Added a global policy setting and an environment policy variable for specifying the action to + be taken when an msvc request cannot be satisfied. The available options are "error", + "exception", "warning", "warn", "ignore", and "suppress". The global policy variable may be + set and retrieved via the functions set_msvc_notfound_policy and get_msvc_notfound_policy, + respectively. These two methods may be imported from SCons.Tool.MSCommon. The environment + policy variable introduced is MSVC_NOTFOUND_POLICY. When defined, the environment policy + variable overrides the global policy setting for a given environment. When the active policy + is "error" or "exception", an MSVCVersionNotFound exception is raised. When the active policy + is "warning" or "warn", a VisualCMissingWarning warning is issued and the constructed + environment is likely incomplete. When the active policy is "ignore" or "suppress", no action + is taken and the constructed environment is likely incomplete. As implemented, the default + global policy is "warning". The ability to set the global policy via an SCons command-line + option may be added in a future enhancement. DEPRECATED FUNCTIONALITY @@ -120,6 +133,12 @@ FIXES - The system environment variable names imported for MSVC 7.0 and 6.0 were updated to be consistent with the variables names defined by their respective installers. This fixes an error caused when bypassing MSVC detection by specifying the MSVC 7.0 batch file directly. +- Suppress issuing a warning when there are no installed Visual Studio instances for the default + tools configuration (issue #2813). When msvc is the default compiler because there are no + compilers installed, a build may fail due to the cl.exe command not being recognized. At + present, there is no easy way to detect during msvc initialization if the default environment + will be used later to build a program and/or library. There is no error/warning issued for the + default tools as there are legitimate SCons uses that do not require a c compiler. IMPROVEMENTS ------------ -- cgit v0.12 From eed3b5845a6a1258cd979d39b3f47b7133053552 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 5 Jun 2022 18:23:01 -0700 Subject: Added test for invalid env['MSVC_NOTFOUND_POLICY'] value --- test/MSVC/msvc_badversion.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/MSVC/msvc_badversion.py b/test/MSVC/msvc_badversion.py index a36bd2b..65dc789 100644 --- a/test/MSVC/msvc_badversion.py +++ b/test/MSVC/msvc_badversion.py @@ -44,25 +44,35 @@ installed_msvc_versions = msvc.get_installed_vcs() # skip_if_not_msvc() function would have skipped the test test.write('SConstruct', """\ +DefaultEnvironment(tools=[]) env = Environment(MSVC_VERSION='12.9') """) test.run(arguments='-Q -s', stdout='') test.write('SConstruct', """\ +DefaultEnvironment(tools=[]) env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='ignore') """) test.run(arguments='-Q -s', stdout='') test.write('SConstruct', """\ +DefaultEnvironment(tools=[]) env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='warning') """) test.run(arguments='-Q -s', stdout='') test.write('SConstruct', """\ +DefaultEnvironment(tools=[]) env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='error') """) test.run(arguments='-Q -s', status=2, stderr=r"^.*MSVCVersionNotFound.+", match=TestSCons.match_re_dotall) +test.write('SConstruct', """\ +env = Environment(MSVC_VERSION='12.9', MSVC_NOTFOUND_POLICY='bad_value') +""") +test.run(arguments='-Q -s', status=2, stderr=r"^.* Value specified for MSVC_NOTFOUND_POLICY.+", match=TestSCons.match_re_dotall) + + test.pass_test() # Local Variables: -- cgit v0.12 From de86183d3307c32b7b917e8b2dc989921b632ec7 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 5 Jun 2022 18:29:46 -0700 Subject: Add Blurb for MSVC_NOTFOUND_POLICY --- SCons/Tool/msvc.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index 4a45d26..59a285e 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -74,6 +74,7 @@ Sets construction variables for the Microsoft Visual C/C++ compiler. PCH PCHSTOP PDB +MSVC_NOTFOUND_POLICY @@ -578,5 +579,28 @@ and also before &f-link-env-Tool; is called to ininitialize any of those tools: + + + +Specify how to handle missing MSVC. + + + + The MSVC_NOTFOUND_POLICY specifies how &scons; should handle when there is no installed + MSVC or if a specific version is requested, that version is not available. + + + +Valid values for MSVC_NOTFOUND_POLICY are listed here. Note that each group below is equivalent. + + +'error', 'Error', 'ERROR', 'exception', 'Exception', 'EXCEPTION' +'warning', 'Warning', 'WARNING', 'warn', 'Warn', 'WARN' +'suppress', 'Suppress', 'SUPPRESS' + + + + + -- cgit v0.12 From 294629587a8cadfa1b6e409d2a4751a7be4880bf Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 6 Jun 2022 09:55:50 -0400 Subject: Update MSVC_NOTFOUND_POLICY documentation --- SCons/Tool/msvc.xml | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index 59a285e..84c0e90 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -582,22 +582,48 @@ and also before &f-link-env-Tool; is called to ininitialize any of those tools: -Specify how to handle missing MSVC. +Specify the &scons; action to take when an msvc installation is not found. - The MSVC_NOTFOUND_POLICY specifies how &scons; should handle when there is no installed - MSVC or if a specific version is requested, that version is not available. + The MSVC_NOTFOUND_POLICY specifies the action &scons; should take when there are no + msvc versions installed or when the requested msvc version is not installed. -Valid values for MSVC_NOTFOUND_POLICY are listed here. Note that each group below is equivalent. +The valid values for MSVC_NOTFOUND_POLICY and the corresponding &scons; action taken are: - -'error', 'Error', 'ERROR', 'exception', 'Exception', 'EXCEPTION' -'warning', 'Warning', 'WARNING', 'warn', 'Warn', 'WARN' -'suppress', 'Suppress', 'SUPPRESS' - + + + + +'error', 'Error', 'ERROR', 'exception', 'Exception', 'EXCEPTION' + + +Raise an exception when there are no msvc versions installed or when the requested msvc version is not installed. + + + + + +'warning', 'Warning', 'WARNING', 'warn', 'Warn', 'WARN' + + +Issue a warning when there are no msvc versions installed or when the requested msvc version is not installed. + + + + + +'ignore', 'Ignore', 'IGNORE', 'suppress', 'Suppress', 'SUPPRESS' + + +Take no action and continue when there are no msvc versions installed or when the requested msvc version is not installed. Depending on usage, this could result in build failure(s). + + + + + -- cgit v0.12 From 69d6b9acceeda73780592d1b8e09b3aa4f2c3813 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 6 Jun 2022 10:11:51 -0400 Subject: Update MSVC_NOTFOUND_POLICY documentation --- SCons/Tool/msvc.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index 84c0e90..bb484c5 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -582,11 +582,11 @@ and also before &f-link-env-Tool; is called to ininitialize any of those tools: -Specify the &scons; action to take when an msvc installation is not found. +Specify the action taken when the Microsoft Visual C/C++ compiler is not found. - The MSVC_NOTFOUND_POLICY specifies the action &scons; should take when there are no + The MSVC_NOTFOUND_POLICY specifies the &scons; action taken when there are no msvc versions installed or when the requested msvc version is not installed. -- cgit v0.12 From e7c4d5bb062d979da2a27560db7a658cdef9c262 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 6 Jun 2022 11:56:37 -0400 Subject: Update MSVC_NOTFOUND_POLICY documentation --- SCons/Tool/msvc.xml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index bb484c5..187f3b5 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -597,7 +597,7 @@ The valid values for MSVC_NOTFOUND_POLICY and the corresponding & -'error', 'Error', 'ERROR', 'exception', 'Exception', 'EXCEPTION' +'Error' or 'Exception' Raise an exception when there are no msvc versions installed or when the requested msvc version is not installed. @@ -606,25 +606,36 @@ Raise an exception when there are no msvc versions installed or when the request -'warning', 'Warning', 'WARNING', 'warn', 'Warn', 'WARN' +'Warning' or 'Warn' -Issue a warning when there are no msvc versions installed or when the requested msvc version is not installed. +Issue a warning and continue when there are no msvc versions installed or when the requested msvc version is not installed. +Depending on usage, this could result in build failure(s). -'ignore', 'Ignore', 'IGNORE', 'suppress', 'Suppress', 'SUPPRESS' +'Ignore' or 'Suppress' -Take no action and continue when there are no msvc versions installed or when the requested msvc version is not installed. Depending on usage, this could result in build failure(s). +Take no action and continue when there are no msvc versions installed or when the requested msvc version is not installed. +Depending on usage, this could result in build failure(s). + +Note: in addition to the camel case values shown above, lower case and upper case values are accepted as well. + + + +The default scons action taken when there are no msvc versions installed or when the requested msvc version is +not installed is to issue a warning and continue. This may change in the future. + + -- cgit v0.12 From 1d3e0e3b0edd4b723d868434c49997215da45fc1 Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Mon, 6 Jun 2022 13:00:20 -0400 Subject: Update MSVC_NOTFOUND_POLICY documentation --- SCons/Tool/msvc.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index 187f3b5..59b8944 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -582,16 +582,16 @@ and also before &f-link-env-Tool; is called to ininitialize any of those tools: -Specify the action taken when the Microsoft Visual C/C++ compiler is not found. +Specify the scons behavior when the Microsoft Visual C/C++ compiler is not detected. - The MSVC_NOTFOUND_POLICY specifies the &scons; action taken when there are no - msvc versions installed or when the requested msvc version is not installed. + The MSVC_NOTFOUND_POLICY specifies the &scons; behavior when no msvc versions are detected or + when the requested msvc version is not detected. -The valid values for MSVC_NOTFOUND_POLICY and the corresponding &scons; action taken are: +The valid values for MSVC_NOTFOUND_POLICY and the corresponding &scons; behavior are: @@ -600,7 +600,7 @@ The valid values for MSVC_NOTFOUND_POLICY and the corresponding & 'Error' or 'Exception' -Raise an exception when there are no msvc versions installed or when the requested msvc version is not installed. +Raise an exception when no msvc versions are detected or when the requested msvc version is not detected. @@ -609,7 +609,7 @@ Raise an exception when there are no msvc versions installed or when the request 'Warning' or 'Warn' -Issue a warning and continue when there are no msvc versions installed or when the requested msvc version is not installed. +Issue a warning and continue when no msvc versions are detected or when the requested msvc version is not detected. Depending on usage, this could result in build failure(s). @@ -619,7 +619,7 @@ Depending on usage, this could result in build failure(s). 'Ignore' or 'Suppress' -Take no action and continue when there are no msvc versions installed or when the requested msvc version is not installed. +Take no action and continue when no msvc versions are detected or when the requested msvc version is not detected. Depending on usage, this could result in build failure(s). @@ -632,8 +632,8 @@ Note: in addition to the camel case values shown above, lower case and upper cas -The default scons action taken when there are no msvc versions installed or when the requested msvc version is -not installed is to issue a warning and continue. This may change in the future. +The default scons behavior when no msvc versions are detected or when the requested msvc version is not detected +is to issue a warning and continue. This may change in the future. -- cgit v0.12 From 719ad105165e942ee39f42749ee48d06e7567c90 Mon Sep 17 00:00:00 2001 From: Daniel Moody Date: Tue, 7 Jun 2022 15:05:42 -0500 Subject: Added command line variable to pass ninja args through scons. --- CHANGES.txt | 2 ++ RELEASE.txt | 1 + SCons/Tool/ninja/__init__.py | 12 +++++++++++- SCons/Tool/ninja/ninja.xml | 11 ++++++++++- test/ninja/generate_and_build.py | 3 ++- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 03692d6..90e2d4e 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -116,6 +116,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Note that these are called for every build command run by SCons. It could have considerable performance impact if not used carefully. to connect to the server during start up. + - Ninja: Added command line variable NINJA_CMD_ARGS that allows to pass through ninja command line args. + From Mats Wichmann: - Tweak the way default site_scons paths on Windows are expressed to diff --git a/RELEASE.txt b/RELEASE.txt index cfa8afc..699e51e 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -24,6 +24,7 @@ NEW FUNCTIONALITY performance impact if not used carefully. - Added MSVC_USE_SETTINGS variable to pass a dictionary to configure the msvc compiler system environment as an alternative to bypassing Visual Studio autodetection entirely. +- Ninja: Added command line variable NINJA_CMD_ARGS that allows to pass through ninja command line args. DEPRECATED FUNCTIONALITY diff --git a/SCons/Tool/ninja/__init__.py b/SCons/Tool/ninja/__init__.py index 04a7abb..27a2957 100644 --- a/SCons/Tool/ninja/__init__.py +++ b/SCons/Tool/ninja/__init__.py @@ -33,6 +33,7 @@ import sys import SCons import SCons.Script import SCons.Tool.ninja.Globals +from SCons.Script import Variables from SCons.Script import GetOption from .Globals import NINJA_RULES, NINJA_POOLS, NINJA_CUSTOM_HANDLERS, NINJA_DEFAULT_TARGETS, NINJA_CMDLINE_TARGETS @@ -87,7 +88,7 @@ def ninja_builder(env, target, source): if str(env.get("NINJA_DISABLE_AUTO_RUN")).lower() not in ['1', 'true']: num_jobs = env.get('NINJA_MAX_JOBS', env.GetOption("num_jobs")) - cmd += ['-j' + str(num_jobs)] + NINJA_CMDLINE_TARGETS + cmd += ['-j' + str(num_jobs)] + env.get('NINJA_CMD_ARGS', '').split() + NINJA_CMDLINE_TARGETS print(f"ninja will be run with command line targets: {' '.join(NINJA_CMDLINE_TARGETS)}") print("Executing:", str(' '.join(cmd))) @@ -185,6 +186,15 @@ def generate(env): env["NINJA_DISABLE_AUTO_RUN"] = env.get("NINJA_DISABLE_AUTO_RUN", GetOption('disable_execute_ninja')) env["NINJA_FILE_NAME"] = env.get("NINJA_FILE_NAME", "build.ninja") + if env.get("NINJA_CMD_ARGS") is not None: + env["NINJA_CMD_ARGS"] = env.get("NINJA_CMD_ARGS") + else: + vars = Variables() + vars.Add("NINJA_CMD_ARGS") + var_env = env.Clone() + vars.Update(var_env) + env["NINJA_CMD_ARGS"] = var_env.get("NINJA_CMD_ARGS", '') + # Add the Ninja builder. always_exec_ninja_action = AlwaysExecAction(ninja_builder, {}) ninja_builder_obj = SCons.Builder.Builder(action=always_exec_ninja_action, diff --git a/SCons/Tool/ninja/ninja.xml b/SCons/Tool/ninja/ninja.xml index 6b247d0..0929684 100644 --- a/SCons/Tool/ninja/ninja.xml +++ b/SCons/Tool/ninja/ninja.xml @@ -77,7 +77,7 @@ See its __doc__ string for a discussion of the format. IMPLICIT_COMMAND_DEPENDENCIES NINJA_SCONS_DAEMON_KEEP_ALIVE NINJA_SCONS_DAEMON_PORT - + NINJA_CMD_ARGS @@ -395,5 +395,14 @@ python -m pip install ninja + + + + A string which will pass arguments through SCons to the ninja command when scons executes ninja. + Has no effect if &cv-NINJA_DISABLE_AUTO_RUN; is set. + + + + diff --git a/test/ninja/generate_and_build.py b/test/ninja/generate_and_build.py index 91be108..83b7387 100644 --- a/test/ninja/generate_and_build.py +++ b/test/ninja/generate_and_build.py @@ -49,10 +49,11 @@ test.dir_fixture('ninja-fixture') test.file_fixture('ninja_test_sconscripts/sconstruct_generate_and_build', 'SConstruct') # generate simple build -test.run(stdout=None) +test.run(stdout=None, arguments='NINJA_CMD_ARGS=-v') test.must_contain_all_lines(test.stdout(), ['Generating: build.ninja']) test.must_contain_all(test.stdout(), 'Executing:') test.must_contain_all(test.stdout(), 'ninja%(_exe)s -f' % locals()) +test.must_contain_all(test.stdout(), ' -j1 -v') test.run(program=test.workpath('foo' + _exe), stdout="foo.c") # clean build and ninja files -- cgit v0.12 From e30a6efe2cbf887a501b2a18be854ea0346e299d Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Wed, 8 Jun 2022 12:29:04 -0400 Subject: Update MSVC_NOTFOUND_POLICY documentation --- SCons/Tool/msvc.xml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index 59b8944..d99bcef 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -632,10 +632,28 @@ Note: in addition to the camel case values shown above, lower case and upper cas -The default scons behavior when no msvc versions are detected or when the requested msvc version is not detected -is to issue a warning and continue. This may change in the future. +The MSVC_NOTFOUND_POLICY is enforced if any of the following conditions are satisfied: + +&cv-MSVC_VERSION; is specified, the default tools list is implicitly defined (i.e., the tools list is not specified), and the default tools list contains one or more of the msvc tools. +&cv-MSVC_VERSION; is specified, the default tools list is explicitly specified (e.g., tools=['default']), and the default tools list contains one or more of the msvc tools. +A non-default tools list is specified that contains one or more of the msvc tools (e.g., tools=['msvc', 'mslink']). + + +The MSVC_NOTFOUND_POLICY is ignored if any of the following conditions are satisfied: + +&cv-MSVC_VERSION; is not specified and the default tools list is implicitly defined (i.e., the tools list is not specified). +&cv-MSVC_VERSION; is not specified and the default tools list is explicitly specified (e.g., tools=['default']). +A non-default tool list is specified that does not contain any of the msvc tools (e.g., tools=['mingw']). + + + + +When MSVC_NOTFOUND_POLICY is not specified, the default &scons; behavior is to issue a warning and continue subject to the enforcement conditions listed above. The default &scons; behavior may change in the future. + + + -- cgit v0.12 From be45d8d5f77d15bbca6cee1108f2d7dbfe5ef79b Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Wed, 8 Jun 2022 12:44:27 -0400 Subject: Add preliminary docstrings for set_msvc_notfound_policy and get_msvc_notfound_policy --- SCons/Tool/MSCommon/vc.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 32d0e61..f0c286a 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -1070,6 +1070,19 @@ def _msvc_notfound_policy_lookup(symbol): return notfound_policy_def def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): + """ Set the default policy when MSVC is not found. + + Args: + MSVC_NOTFOUND_POLICY: + string representing the policy behavior + when MSVC is not found or None + + Returns: + The previous policy is returned when the MSVC_NOTFOUND_POLICY argument + is not None. The active policy is returned when the MSVC_NOTFOUND_POLICY + argument is None. + + """ global _MSVC_NOTFOUND_POLICY_DEF prev_policy = _MSVC_NOTFOUND_POLICY_DEF.symbol @@ -1087,6 +1100,7 @@ def set_msvc_notfound_policy(MSVC_NOTFOUND_POLICY=None): return prev_policy def get_msvc_notfound_policy(): + """Return the active policy when MSVC is not found.""" debug( 'policy.symbol=%s, policy.value=%s', repr(_MSVC_NOTFOUND_POLICY_DEF.symbol), repr(_MSVC_NOTFOUND_POLICY_DEF.value) -- cgit v0.12 From 609b79f538dc025a2b2d4dfd4d8814f96481949e Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Wed, 8 Jun 2022 14:12:59 -0400 Subject: Update MSVC_NOTFOUND_POLICY documentation --- SCons/Tool/msvc.xml | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index d99bcef..e8df128 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -632,25 +632,40 @@ Note: in addition to the camel case values shown above, lower case and upper cas -The MSVC_NOTFOUND_POLICY is enforced if any of the following conditions are satisfied: +The MSVC_NOTFOUND_POLICY is applied when any of the following conditions are satisfied: -&cv-MSVC_VERSION; is specified, the default tools list is implicitly defined (i.e., the tools list is not specified), and the default tools list contains one or more of the msvc tools. -&cv-MSVC_VERSION; is specified, the default tools list is explicitly specified (e.g., tools=['default']), and the default tools list contains one or more of the msvc tools. -A non-default tools list is specified that contains one or more of the msvc tools (e.g., tools=['msvc', 'mslink']). + +&cv-MSVC_VERSION; is specified, the default tools list is implicitly defined (i.e., the tools list is not specified), +and the default tools list contains one or more of the msvc tools. + + +&cv-MSVC_VERSION; is specified, the default tools list is explicitly specified (e.g., tools=['default']), +and the default tools list contains one or more of the msvc tools. + + +A non-default tools list is specified that contains one or more of the msvc tools (e.g., tools=['msvc', 'mslink']). + -The MSVC_NOTFOUND_POLICY is ignored if any of the following conditions are satisfied: +The MSVC_NOTFOUND_POLICY is ignored when any of the following conditions are satisfied: -&cv-MSVC_VERSION; is not specified and the default tools list is implicitly defined (i.e., the tools list is not specified). -&cv-MSVC_VERSION; is not specified and the default tools list is explicitly specified (e.g., tools=['default']). -A non-default tool list is specified that does not contain any of the msvc tools (e.g., tools=['mingw']). + +&cv-MSVC_VERSION; is not specified and the default tools list is implicitly defined (i.e., the tools list is not specified). + + +&cv-MSVC_VERSION; is not specified and the default tools list is explicitly specified (e.g., tools=['default']). + + +A non-default tool list is specified that does not contain any of the msvc tools (e.g., tools=['mingw']). + -When MSVC_NOTFOUND_POLICY is not specified, the default &scons; behavior is to issue a warning and continue subject to the enforcement conditions listed above. The default &scons; behavior may change in the future. +When MSVC_NOTFOUND_POLICY is not specified, the default &scons; behavior is to issue a warning and continue +subject to the conditions listed above. The default &scons; behavior may change in the future. -- cgit v0.12 From 3d9345e2d086f3b39a419452c9b74f763698dd04 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 9 Jun 2022 09:03:58 -0600 Subject: doc: FORTRANCOM doesn't include cpp vars [skip appveyor] FORTRANCOM and SHFORTRANCOM don't add the C preprocessor variables by default, the docs suggest they do. The PP variants, which run through the preprocessor, do add these. Adjust docs. Fixes #2128 Signed-off-by: Mats Wichmann --- SCons/Tool/fortran.xml | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/SCons/Tool/fortran.xml b/SCons/Tool/fortran.xml index a4f0cec..4f0517b 100644 --- a/SCons/Tool/fortran.xml +++ b/SCons/Tool/fortran.xml @@ -1,6 +1,6 @@