diff options
-rwxr-xr-x | CHANGES.txt | 2 | ||||
-rwxr-xr-x | RELEASE.txt | 2 | ||||
-rw-r--r-- | SCons/Tool/MSCommon/vc.py | 42 | ||||
-rw-r--r-- | SCons/Tool/msvc.xml | 66 | ||||
-rw-r--r-- | test/MSVC/MSVC_USE_SETTINGS.py | 76 |
5 files changed, 187 insertions, 1 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index c1b3a88..e97da83 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -31,6 +31,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER determination when configuring the build environment. This could lead to build failures when only an MSVC Express instance is installed and the MSVC version is not explicitly specified (issue #2668 and issue #2697). + - 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. - The imported system environment variable names for MSVC 7.0 and 6.0 have been changed to the names set by their respective installers. Prior to this change, bypassing MSVC detection by specifying the MSVC 7.0 batch file directly would fail due to using an erroneous environment diff --git a/RELEASE.txt b/RELEASE.txt index 1096dbf..aa283fc 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -19,6 +19,8 @@ NEW FUNCTIONALITY - Added SHELL_ENV_GENERATOR construction variables. This variable allows the user to Define a function which will be called to generate or alter the execution environment which will 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. DEPRECATED FUNCTIONALITY diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 4368e57..dd37db2 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -84,6 +84,9 @@ class BatchFileExecutionError(VisualCException): class MSVCScriptNotFound(VisualCException): pass +class MSVCUseSettingsError(VisualCException): + pass + # Dict to 'canonalize' the arch _ARCH_TO_CANONICAL = { "amd64" : "amd64", @@ -1121,6 +1124,37 @@ def msvc_find_valid_batch_script(env, version): return d +_undefined = None + +def get_use_script_use_settings(env): + global _undefined + + if _undefined is None: + _undefined = object() + + # use_script use_settings return values action + # value ignored (value, None) use script or bypass detection + # undefined value not None (False, value) use dictionary + # undefined undefined/None (True, None) msvc detection + + # None (documentation) or evaluates False (code): bypass detection + # need to distinguish between undefined and None + use_script = env.get('MSVC_USE_SCRIPT', _undefined) + + if use_script != _undefined: + # use_script defined, use_settings ignored (not type checked) + return (use_script, None) + + # undefined or None: use_settings ignored + use_settings = env.get('MSVC_USE_SETTINGS', None) + + if use_settings is not None: + # use script undefined, use_settings defined and not None (type checked) + return (False, use_settings) + + # use script undefined, use_settings undefined or None + return (True, None) + def msvc_setup_env(env): debug('called') @@ -1138,7 +1172,7 @@ def msvc_setup_env(env): env['MSVS'] = {} - use_script = env.get('MSVC_USE_SCRIPT', True) + use_script, use_settings = get_use_script_use_settings(env) if SCons.Util.is_String(use_script): use_script = use_script.strip() if not os.path.exists(use_script): @@ -1151,6 +1185,12 @@ def msvc_setup_env(env): debug('use_script 2 %s', d) if not d: return d + elif use_settings is not None: + if not SCons.Util.is_Dict(use_settings): + error_msg = 'MSVC_USE_SETTINGS type error: expected a dictionary, found {}'.format(type(use_settings).__name__) + raise MSVCUseSettingsError(error_msg) + d = use_settings + debug('use_settings %s', d) else: debug('MSVC_USE_SCRIPT set to False') warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \ diff --git a/SCons/Tool/msvc.xml b/SCons/Tool/msvc.xml index f4d33f4..4a45d26 100644 --- a/SCons/Tool/msvc.xml +++ b/SCons/Tool/msvc.xml @@ -422,6 +422,72 @@ Provides arguments passed to the script &cv-link-MSVC_USE_SCRIPT;. </summary> </cvar> +<cvar name="MSVC_USE_SETTINGS"> +<summary> +<para> +Use a dictionary to set up the Microsoft Visual C++ compiler. +</para> + +<para> +&cv-MSVC_USE_SETTINGS; is ignored when &cv-link-MSVC_USE_SCRIPT; is defined +and/or when &cv-MSVC_USE_SETTINGS; is set to <constant>None</constant>. +</para> + +<para> +The dictionary is used to populate the environment with the relevant variables +(typically <envar>%INCLUDE%</envar>, <envar>%LIB%</envar>, and <envar>%PATH%</envar>) +for supplying to the build. This can be useful to force the use of a compiler environment +that &SCons; does not configure correctly. This is an alternative to manually configuring +the environment when bypassing Visual Studio autodetection entirely by setting +&cv-link-MSVC_USE_SCRIPT; to <constant>None</constant>. +</para> + +<para> +Here is an example of configuring a build environment using the Microsoft Visual C/C++ compiler +included in the Microsoft SDK on a 64-bit host and building for a 64-bit architecture: +<programlisting> +# Microsoft SDK 6.0 (MSVC 8.0): 64-bit host and 64-bit target +msvc_use_settings = { + "PATH": [ + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Bin\\x64", + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin\\x64", + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin", + "C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727", + "C:\\Windows\\system32", + "C:\\Windows", + "C:\\Windows\\System32\\Wbem", + "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\" + ], + "INCLUDE": [ + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Include", + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Include\\Sys", + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Include", + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Include\\gl", + ], + "LIB": [ + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Lib\\x64", + "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Lib\\x64", + ], + "LIBPATH": [], + "VSCMD_ARG_app_plat": [], + "VCINSTALLDIR": [], + "VCToolsInstallDir": [] +} + +# Specifying MSVC_VERSION is recommended +env = Environment(MSVC_VERSION='8.0', MSVC_USE_SETTINGS=msvc_use_settings) +</programlisting> +</para> + +<para> +Note: the dictionary content requirements are based on the internal msvc implementation and +therefore may change at any time. The burden is on the user to ensure the dictionary contents +are minimally sufficient to ensure successful builds. +</para> + +</summary> +</cvar> + <!-- This has moved to Platform/Platform.xml to avoid duplication <cvar name="HOST_ARCH"> <summary> diff --git a/test/MSVC/MSVC_USE_SETTINGS.py b/test/MSVC/MSVC_USE_SETTINGS.py new file mode 100644 index 0000000..97be59f --- /dev/null +++ b/test/MSVC/MSVC_USE_SETTINGS.py @@ -0,0 +1,76 @@ +# 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 +# "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. + +""" +Test the $MSVC_USE_SETTINGS construction variable. +""" + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +test.skip_if_not_msvc() + +test.write('SConstruct', """ +e1 = Environment() +cl1 = e1.WhereIs('cl.exe') + +e2 = Environment(tools=[]) + +d = {key: e1['ENV'][key] for key in e1['ENV'].keys() if key not in e2['ENV'] or e1['ENV'][key] != e2['ENV'][key]} +e3 = Environment(MSVC_USE_SETTINGS=d) +cl3 = e3.WhereIs('cl.exe') + +if cl1 == cl3: + print("CL.EXE PATHS MATCH") +""" % locals()) + +test.run(arguments = ".", status=0, stderr=None) + +test.must_contain_all(test.stdout(), "CL.EXE PATHS MATCH") + +test.write('SConstruct', """ +env = Environment(MSVC_USE_SETTINGS={}) +""" % locals()) + +test.run(arguments = "--warn=visual-c-missing .", status=0, stderr=None) + +test.must_contain_all(test.stderr(), "Could not find MSVC compiler 'cl'") + +test.write('SConstruct', """ +env = Environment(MSVC_USE_SETTINGS='dict or None') +""" % locals()) + +test.run(arguments = ".", status=2, stderr=None) + +test.must_contain_all(test.stderr(), "MSVCUseSettingsError: MSVC_USE_SETTINGS type error") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: |