diff options
-rwxr-xr-x | src/CHANGES.txt | 3 | ||||
-rw-r--r-- | src/engine/SCons/Tool/MSCommon/common.py | 80 |
2 files changed, 56 insertions, 27 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index ac8a3ac..efe5464 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -93,6 +93,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Fixed bug where changing TEXTFILESUFFIX would cause Substfile() to rebuild. (Github Issue #3540) - Script/Main.py now uses importlib instead of imp module. - Drop some Python 2-isms. + - MSVC updates: pass on VSCMD_DEBUG and VSCMD_SKIP_SENDTELEMETRY to msvc + tool setup if set in environment. Add powershell to default env + (used to call telemetry script). - Docbook builder provides a fallback if lxml fails to generate a document with tostring(). diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index 7f832c6..b2b5de9 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -156,15 +156,14 @@ def normalize_env(env, keys, force=False): if k in os.environ and (force or k not in normenv): normenv[k] = os.environ[k] - # This shouldn't be necessary, since the default environment should include system32, - # but keep this here to be safe, since it's needed to find reg.exe which the MSVC - # bat scripts use. - sys32_dir = os.path.join(os.environ.get("SystemRoot", - os.environ.get("windir", r"C:\Windows\system32")), - "System32") - - if sys32_dir not in normenv['PATH']: - normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_dir + # add some things to PATH to prevent problems: + # Shouldn't be necessary to add system32, since the default environment + # should include it, but keep this here to be safe (needed for reg.exe) + sys32_dir = os.path.join( + os.environ.get("SystemRoot", os.environ.get("windir", r"C:\Windows")), "System32" +) + if sys32_dir not in normenv["PATH"]: + normenv["PATH"] = normenv["PATH"] + os.pathsep + sys32_dir # Without Wbem in PATH, vcvarsall.bat has a "'wmic' is not recognized" # error starting with Visual Studio 2017, although the script still @@ -173,8 +172,14 @@ def normalize_env(env, keys, force=False): if sys32_wbem_dir not in normenv['PATH']: normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir - debug("PATH: %s" % normenv['PATH']) + # Without Powershell in PATH, an internal call to a telemetry + # function (starting with a VS2019 update) can fail + # Note can also set VSCMD_SKIP_SENDTELEMETRY to avoid this. + sys32_ps_dir = os.path.join(sys32_dir, r'WindowsPowerShell\v1.0') + if sys32_ps_dir not in normenv['PATH']: + normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_ps_dir + debug("PATH: %s" % normenv['PATH']) return normenv @@ -185,16 +190,21 @@ def get_output(vcbat, args=None, env=None): # Create a blank environment, for use in launching the tools env = SCons.Environment.Environment(tools=[]) - # TODO: This is a hard-coded list of the variables that (may) need - # to be imported from os.environ[] for v[sc]*vars*.bat file - # execution to work. This list should really be either directly - # controlled by vc.py, or else derived from the common_tools_var - # settings in vs.py. + # TODO: Hard-coded list of the variables that (may) need to be + # imported from os.environ[] for the chain of development batch + # files to execute correctly. One call to vcvars*.bat may + # end up running a dozen or more scripts, changes not only with + # each release but with what is installed at the time. We think + # in modern installations most are set along the way and don't + # need to be picked from the env, but include these for safety's sake. + # Any VSCMD variables definitely are picked from the env and + # control execution in interesting ways. + # Note these really should be unified - either controlled by vs.py, + # or synced with the the common_tools_var # settings in vs.py. vs_vc_vars = [ - 'COMSPEC', - # VS100 and VS110: Still set, but modern MSVC setup scripts will - # discard these if registry has values. However Intel compiler setup - # script still requires these as of 2013/2014. + 'COMSPEC', # path to "shell" + 'VS160COMNTOOLS', # path to common tools for given version + 'VS150COMNTOOLS', 'VS140COMNTOOLS', 'VS120COMNTOOLS', 'VS110COMNTOOLS', @@ -204,6 +214,8 @@ def get_output(vcbat, args=None, env=None): 'VS71COMNTOOLS', 'VS70COMNTOOLS', 'VS60COMNTOOLS', + 'VSCMD_DEBUG', # enable logging and other debug aids + 'VSCMD_SKIP_SENDTELEMETRY', ] env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False) @@ -234,21 +246,35 @@ def get_output(vcbat, args=None, env=None): # debug('get_output():stdout:%s'%stdout) # debug('get_output():stderr:%s'%stderr) + # Ongoing problems getting non-corrupted text led to this + # changing to "oem" from "mbcs" - the scripts run presumably + # attached to a console, so some particular rules apply. + # Unfortunately, "oem" not defined in Python 3.5, so get another way + if sys.version_info.major == 3 and sys.version_info.minor < 6: + from ctypes import windll + + OEM = "cp{}".format(windll.kernel32.GetConsoleOutputCP()) + else: + OEM = "oem" if stderr: # TODO: find something better to do with stderr; # this at least prevents errors from getting swallowed. - sys.stderr.write(stderr) + sys.stderr.write(stderr.decode(OEM)) if popen.wait() != 0: - raise IOError(stderr.decode("mbcs")) + raise IOError(stderr.decode(OEM)) - output = stdout.decode("mbcs") - return output + return stdout.decode(OEM) -KEEPLIST = ("INCLUDE", "LIB", "LIBPATH", "PATH", 'VSCMD_ARG_app_plat', - 'VCINSTALLDIR', # needed by clang -VS 2017 and newer - 'VCToolsInstallDir', # needed by clang - VS 2015 and older - ) +KEEPLIST = ( + "INCLUDE", + "LIB", + "LIBPATH", + "PATH", + "VSCMD_ARG_app_plat", + "VCINSTALLDIR", # needed by clang -VS 2017 and newer + "VCToolsInstallDir", # needed by clang - VS 2015 and older +) def parse_output(output, keep=KEEPLIST): |