Skip to content

Commit 245b627

Browse files
committed
Merge remote-tracking branch 'upstream/master' into feature/minor_java_improvements
2 parents e5043ad + 1f66961 commit 245b627

File tree

8 files changed

+288
-21
lines changed

8 files changed

+288
-21
lines changed

CHANGES.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
3131
determination when configuring the build environment. This could lead to build failures when
3232
only an MSVC Express instance is installed and the MSVC version is not explicitly specified
3333
(issue #2668 and issue #2697).
34+
- Added MSVC_USE_SETTINGS variable to pass a dictionary to configure the msvc compiler
35+
system environment as an alternative to bypassing Visual Studio autodetection entirely.
36+
- The imported system environment variable names for MSVC 7.0 and 6.0 have been changed to the
37+
names set by their respective installers. Prior to this change, bypassing MSVC detection by
38+
specifying the MSVC 7.0 batch file directly would fail due to using an erroneous environment
39+
variable name. Arguments are no longer passed to the MSVC 6.0 to 7.1 batch files as no
40+
arguments are required and could improve the effectiveness of the internal MSVC cache.
41+
- Propagate the OS and windir environment variables from the system environment to the msvc
42+
environment. The OS and windir environment variables are used in the MSVC 6.0 batch file
43+
and the SDK 6.0-7.1 SetEnv.cmd batch files. Inclusion of the OS and windir environment
44+
variables eliminates some partial paths and warnings generated by the MSVC 6.0 and SDK
45+
6.0-7.1 batch files when the variables are not defined.
46+
Note: Attempting to run the SDK 6.0-7.1 batch files directly via MSVC_USE_SCRIPT can lead to
47+
build failures and/or incomplete build environments. The SDK 6.0-7.1 batch files
48+
require delayed expansion to be enabled which is currently not supported and is
49+
typically not enabled by default on the host system. The batch files may also require
50+
environment variables that are not included by default in the msvc environment.
3451

3552
From William Deegan:
3653
- Fix check for unsupported Python version. It was broken. Also now the error message
@@ -111,6 +128,15 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
111128
processors for testing threads.
112129
- Fixed crash in C scanner's dictify_CPPDEFINES() function which happens if
113130
AppendUnique is called on CPPPATH. (Issue #4108).
131+
- The MSVC script_env_cache now contains a sanity check: if the retrieved
132+
tools path does not exist, the entry is invalidated so it will
133+
be recomputed, in an attempt to avoid scons failing when certain
134+
compiler version bumps have taken place. The dictionary key (uses
135+
the name of a batch file and any arguments which may have been
136+
passes), is now computed a bit differently: the dashes are left
137+
off if there are no arguments. The default cachefile is changed
138+
to have a .json suffix, for better recognition on Windows since
139+
the contents are json.
114140
- As "code modernization" all of SCons now uses the current super()
115141
zero-argument syntax instead of direct calls to a parent class method
116142
or the super() two-argument syntax.

RELEASE.txt

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ NEW FUNCTIONALITY
1919
- Added SHELL_ENV_GENERATOR construction variables. This variable allows the user to Define
2020
a function which will be called to generate or alter the execution environment which will
2121
be used in the shell command of some Action.
22+
- Added MSVC_USE_SETTINGS variable to pass a dictionary to configure the msvc compiler
23+
system environment as an alternative to bypassing Visual Studio autodetection entirely.
2224

2325

2426
DEPRECATED FUNCTIONALITY
@@ -30,9 +32,10 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
3032
---------------------------------------
3133

3234
- On Windows, %AllUsersProfile%\scons\site_scons is now the default "system"
33-
location for a site_scons. %AllUsersProfile%\Application Data\scons\site_scons
34-
will continue to work. There does not seem to be any convention to use
35-
an "Application Data" subdirectory here.
35+
location for a site_scons directory.
36+
%AllUsersProfile%\Application Data\scons\site_scons will continue to work.
37+
There does not seem to be any existing convention to use an
38+
"Application Data" subdirectory here.
3639
- Action._subproc() can now be used as a python context manager to ensure that the
3740
POpen object is properly closed.
3841
- SCons help (-H) no longer prints the "ignored for compatibility" options,
@@ -45,6 +48,16 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
4548
- The change to "content" and "content-timestamp" Decider names is reflected
4649
in the User Guide as well, since the hash function may be other than md5
4750
(tidying up from earlier change)
51+
- If the (experimental) SCONS_CACHE_MSVC_CONFIG feature is used, it will now
52+
attempt a sanity check for the cached compiler information, and regenerate
53+
it if needed. Previously, this cache would fail if a compiler upgrade caused
54+
a change to internal paths (e.g. upgrading from 17.1 to 17.2 causes
55+
a necessary path component in some of the cached vars to need to 14.32.31326
56+
instead of 14.31.31103), and the cache file needed to be manually removed.
57+
The default cachefile name is now "scons_msvc_cache.json" rather than
58+
".scons_msvc_cache" so there should be no transition problem if using the
59+
default; if using a custom cache file name, the cache should still be
60+
manually removed if there are problems to transition to the new style.
4861
- Update ninja file generation to only create response files for build commands
4962
which exceed MAXLINELENGTH
5063
- Update the debug output written to stdout for MSVC initialization which is enabled
@@ -53,6 +66,20 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
5366
message of MSVC initialization debugging output. A single space was added before the
5467
message for all debugging output records written to stdout and to files.
5568
- Add JavaScanner to include JAVACLASSPATH as a dependency when using the Java tool.
69+
- The build argument (i.e., x86) is no longer passed to the MSVC 6.0 to 7.1 batch
70+
files. This may improve the effectiveness of the internal msvc cache when using
71+
MSVC detection and when bypassing MSVC detection as the MSVC 6.0 to 7.1 batch files
72+
do not expect any arguments.
73+
- Propagate the OS and windir environment variables from the system environment to the msvc
74+
environment. The OS and windir environment variables are used in the MSVC 6.0 batch file
75+
and the SDK 6.0-7.1 SetEnv.cmd batch files. Inclusion of the OS and windir environment
76+
variables eliminates some partial paths and warnings generated by the MSVC 6.0 and SDK
77+
6.0-7.1 batch files when the variables are not defined.
78+
Note: Attempting to run the SDK 6.0-7.1 batch files directly via MSVC_USE_SCRIPT can lead to
79+
build failures and/or incomplete build environments. The SDK 6.0-7.1 batch files
80+
require delayed expansion to be enabled which is currently not supported and is
81+
typically not enabled by default on the host system. The batch files may also require
82+
environment variables that are not included by default in the msvc environment.
5683

5784
FIXES
5885
-----
@@ -96,6 +123,9 @@ FIXES
96123
- Fix typo in ninja scons daemon startup which causes ConnectionRefusedError to not retry
97124
to connect to the server during start up.
98125
- Fix incorrect Java classpath generation when a NodeList is used as part of any JAVA*PATH variables.
126+
- The system environment variable names imported for MSVC 7.0 and 6.0 were updated to be
127+
consistent with the variables names defined by their respective installers. This fixes an
128+
error caused when bypassing MSVC detection by specifying the MSVC 7.0 batch file directly.
99129

100130
IMPROVEMENTS
101131
------------

SCons/Tool/MSCommon/common.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import re
3232
import subprocess
3333
import sys
34+
from contextlib import suppress
35+
from pathlib import Path
3436

3537
import SCons.Util
3638

@@ -94,16 +96,21 @@ def debug(x, *args):
9496
# SCONS_CACHE_MSVC_CONFIG is public, and is documented.
9597
CONFIG_CACHE = os.environ.get('SCONS_CACHE_MSVC_CONFIG')
9698
if CONFIG_CACHE in ('1', 'true', 'True'):
97-
CONFIG_CACHE = os.path.join(os.path.expanduser('~'), '.scons_msvc_cache')
99+
CONFIG_CACHE = os.path.join(os.path.expanduser('~'), 'scons_msvc_cache.json')
98100

99101

100102
def read_script_env_cache():
101103
""" fetch cached msvc env vars if requested, else return empty dict """
102104
envcache = {}
103105
if CONFIG_CACHE:
104106
try:
105-
with open(CONFIG_CACHE, 'r') as f:
106-
envcache = json.load(f)
107+
p = Path(CONFIG_CACHE)
108+
with p.open('r') as f:
109+
# Convert the list of cache entry dictionaries read from
110+
# json to the cache dictionary. Reconstruct the cache key
111+
# tuple from the key list written to json.
112+
envcache_list = json.load(f)
113+
envcache = {tuple(d['key']): d['data'] for d in envcache_list}
107114
except FileNotFoundError:
108115
# don't fail if no cache file, just proceed without it
109116
pass
@@ -114,11 +121,17 @@ def write_script_env_cache(cache):
114121
""" write out cache of msvc env vars if requested """
115122
if CONFIG_CACHE:
116123
try:
117-
with open(CONFIG_CACHE, 'w') as f:
118-
json.dump(cache, f, indent=2)
124+
p = Path(CONFIG_CACHE)
125+
with p.open('w') as f:
126+
# Convert the cache dictionary to a list of cache entry
127+
# dictionaries. The cache key is converted from a tuple to
128+
# a list for compatibility with json.
129+
envcache_list = [{'key': list(key), 'data': data} for key, data in cache.items()]
130+
json.dump(envcache_list, f, indent=2)
119131
except TypeError:
120132
# data can't serialize to json, don't leave partial file
121-
os.remove(CONFIG_CACHE)
133+
with suppress(FileNotFoundError):
134+
p.unlink()
122135
except IOError:
123136
# can't write the file, just skip
124137
pass
@@ -243,6 +256,7 @@ def get_output(vcbat, args=None, env=None):
243256
# or synced with the the common_tools_var # settings in vs.py.
244257
vs_vc_vars = [
245258
'COMSPEC', # path to "shell"
259+
'OS', # name of OS family: Windows_NT or undefined (95/98/ME)
246260
'VS170COMNTOOLS', # path to common tools for given version
247261
'VS160COMNTOOLS',
248262
'VS150COMNTOOLS',
@@ -253,10 +267,11 @@ def get_output(vcbat, args=None, env=None):
253267
'VS90COMNTOOLS',
254268
'VS80COMNTOOLS',
255269
'VS71COMNTOOLS',
256-
'VS70COMNTOOLS',
257-
'VS60COMNTOOLS',
270+
'VSCOMNTOOLS',
271+
'MSDevDir',
258272
'VSCMD_DEBUG', # enable logging and other debug aids
259273
'VSCMD_SKIP_SENDTELEMETRY',
274+
'windir', # windows directory (SystemRoot not available in 95/98/ME)
260275
]
261276
env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False)
262277

SCons/Tool/MSCommon/vc.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import subprocess
4444
import os
4545
import platform
46+
from pathlib import Path
4647
from string import digits as string_digits
4748
from subprocess import PIPE
4849
import re
@@ -84,6 +85,9 @@ class BatchFileExecutionError(VisualCException):
8485
class MSVCScriptNotFound(VisualCException):
8586
pass
8687

88+
class MSVCUseSettingsError(VisualCException):
89+
pass
90+
8791
# Dict to 'canonalize' the arch
8892
_ARCH_TO_CANONICAL = {
8993
"amd64" : "amd64",
@@ -777,12 +781,8 @@ def find_batch_file(env, msvc_version, host_arch, target_arch):
777781
# 14.0 (VS2015) to 8.0 (VS2005)
778782
arg, _ = _LE2015_HOST_TARGET_BATCHARG_CLPATHCOMPS[(host_arch, target_arch)]
779783
batfilename = os.path.join(pdir, "vcvarsall.bat")
780-
elif 8 > vernum >= 7:
781-
# 7.1 (VS2003) to 7.0 (VS2003)
782-
pdir = os.path.join(pdir, os.pardir, "Common7", "Tools")
783-
batfilename = os.path.join(pdir, "vsvars32.bat")
784784
else:
785-
# 6.0 (VS6) and earlier
785+
# 7.1 (VS2003) and earlier
786786
pdir = os.path.join(pdir, "Bin")
787787
batfilename = os.path.join(pdir, "vcvars32.bat")
788788

@@ -985,8 +985,25 @@ def script_env(script, args=None):
985985

986986
if script_env_cache is None:
987987
script_env_cache = common.read_script_env_cache()
988-
cache_key = "{}--{}".format(script, args)
988+
cache_key = (script, args if args else None)
989989
cache_data = script_env_cache.get(cache_key, None)
990+
991+
# Brief sanity check: if we got a value for the key,
992+
# see if it has a VCToolsInstallDir entry that is not empty.
993+
# If so, and that path does not exist, invalidate the entry.
994+
# If empty, this is an old compiler, just leave it alone.
995+
if cache_data is not None:
996+
try:
997+
toolsdir = cache_data["VCToolsInstallDir"]
998+
except KeyError:
999+
# we write this value, so should not happen
1000+
pass
1001+
else:
1002+
if toolsdir:
1003+
toolpath = Path(toolsdir[0])
1004+
if not toolpath.exists():
1005+
cache_data = None
1006+
9901007
if cache_data is None:
9911008
stdout = common.get_output(script, args)
9921009

@@ -1125,6 +1142,37 @@ def msvc_find_valid_batch_script(env, version):
11251142

11261143
return d
11271144

1145+
_undefined = None
1146+
1147+
def get_use_script_use_settings(env):
1148+
global _undefined
1149+
1150+
if _undefined is None:
1151+
_undefined = object()
1152+
1153+
# use_script use_settings return values action
1154+
# value ignored (value, None) use script or bypass detection
1155+
# undefined value not None (False, value) use dictionary
1156+
# undefined undefined/None (True, None) msvc detection
1157+
1158+
# None (documentation) or evaluates False (code): bypass detection
1159+
# need to distinguish between undefined and None
1160+
use_script = env.get('MSVC_USE_SCRIPT', _undefined)
1161+
1162+
if use_script != _undefined:
1163+
# use_script defined, use_settings ignored (not type checked)
1164+
return (use_script, None)
1165+
1166+
# undefined or None: use_settings ignored
1167+
use_settings = env.get('MSVC_USE_SETTINGS', None)
1168+
1169+
if use_settings is not None:
1170+
# use script undefined, use_settings defined and not None (type checked)
1171+
return (False, use_settings)
1172+
1173+
# use script undefined, use_settings undefined or None
1174+
return (True, None)
1175+
11281176

11291177
def msvc_setup_env(env):
11301178
debug('called')
@@ -1142,7 +1190,7 @@ def msvc_setup_env(env):
11421190
env['MSVS'] = {}
11431191

11441192

1145-
use_script = env.get('MSVC_USE_SCRIPT', True)
1193+
use_script, use_settings = get_use_script_use_settings(env)
11461194
if SCons.Util.is_String(use_script):
11471195
use_script = use_script.strip()
11481196
if not os.path.exists(use_script):
@@ -1155,6 +1203,12 @@ def msvc_setup_env(env):
11551203
debug('use_script 2 %s', d)
11561204
if not d:
11571205
return d
1206+
elif use_settings is not None:
1207+
if not SCons.Util.is_Dict(use_settings):
1208+
error_msg = 'MSVC_USE_SETTINGS type error: expected a dictionary, found {}'.format(type(use_settings).__name__)
1209+
raise MSVCUseSettingsError(error_msg)
1210+
d = use_settings
1211+
debug('use_settings %s', d)
11581212
else:
11591213
debug('MSVC_USE_SCRIPT set to False')
11601214
warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \

SCons/Tool/MSCommon/vs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ def reset(self):
391391
VisualStudio('7.0',
392392
sdk_version='2003R2',
393393
hkeys=[r'Microsoft\VisualStudio\7.0\Setup\VS\ProductDir'],
394-
common_tools_var='VS70COMNTOOLS',
394+
common_tools_var='VSCOMNTOOLS',
395395
executable_path=r'Common7\IDE\devenv.com',
396396
batch_file_path=r'Common7\Tools\vsvars32.bat',
397397
default_dirname='Microsoft Visual Studio .NET',
@@ -403,7 +403,7 @@ def reset(self):
403403
sdk_version='2003R1',
404404
hkeys=[r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Studio\ProductDir',
405405
'use_dir'],
406-
common_tools_var='VS60COMNTOOLS',
406+
common_tools_var='MSDevDir',
407407
executable_path=r'Common\MSDev98\Bin\MSDEV.COM',
408408
batch_file_path=r'Common7\Tools\vsvars32.bat',
409409
default_dirname='Microsoft Visual Studio',

SCons/Tool/msvc.xml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,72 @@ Provides arguments passed to the script &cv-link-MSVC_USE_SCRIPT;.
422422
</summary>
423423
</cvar>
424424

425+
<cvar name="MSVC_USE_SETTINGS">
426+
<summary>
427+
<para>
428+
Use a dictionary to set up the Microsoft Visual C++ compiler.
429+
</para>
430+
431+
<para>
432+
&cv-MSVC_USE_SETTINGS; is ignored when &cv-link-MSVC_USE_SCRIPT; is defined
433+
and/or when &cv-MSVC_USE_SETTINGS; is set to <constant>None</constant>.
434+
</para>
435+
436+
<para>
437+
The dictionary is used to populate the environment with the relevant variables
438+
(typically <envar>%INCLUDE%</envar>, <envar>%LIB%</envar>, and <envar>%PATH%</envar>)
439+
for supplying to the build. This can be useful to force the use of a compiler environment
440+
that &SCons; does not configure correctly. This is an alternative to manually configuring
441+
the environment when bypassing Visual Studio autodetection entirely by setting
442+
&cv-link-MSVC_USE_SCRIPT; to <constant>None</constant>.
443+
</para>
444+
445+
<para>
446+
Here is an example of configuring a build environment using the Microsoft Visual C/C++ compiler
447+
included in the Microsoft SDK on a 64-bit host and building for a 64-bit architecture:
448+
<programlisting>
449+
# Microsoft SDK 6.0 (MSVC 8.0): 64-bit host and 64-bit target
450+
msvc_use_settings = {
451+
"PATH": [
452+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Bin\\x64",
453+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin\\x64",
454+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin",
455+
"C:\\Windows\\Microsoft.NET\\Framework\\v2.0.50727",
456+
"C:\\Windows\\system32",
457+
"C:\\Windows",
458+
"C:\\Windows\\System32\\Wbem",
459+
"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\"
460+
],
461+
"INCLUDE": [
462+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Include",
463+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Include\\Sys",
464+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Include",
465+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Include\\gl",
466+
],
467+
"LIB": [
468+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\VC\\Lib\\x64",
469+
"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Lib\\x64",
470+
],
471+
"LIBPATH": [],
472+
"VSCMD_ARG_app_plat": [],
473+
"VCINSTALLDIR": [],
474+
"VCToolsInstallDir": []
475+
}
476+
477+
# Specifying MSVC_VERSION is recommended
478+
env = Environment(MSVC_VERSION='8.0', MSVC_USE_SETTINGS=msvc_use_settings)
479+
</programlisting>
480+
</para>
481+
482+
<para>
483+
Note: the dictionary content requirements are based on the internal msvc implementation and
484+
therefore may change at any time. The burden is on the user to ensure the dictionary contents
485+
are minimally sufficient to ensure successful builds.
486+
</para>
487+
488+
</summary>
489+
</cvar>
490+
425491
<!-- This has moved to Platform/Platform.xml to avoid duplication
426492
<cvar name="HOST_ARCH">
427493
<summary>

0 commit comments

Comments
 (0)