Skip to content

Commit 4562f2e

Browse files
authored
Merge pull request #4717 from jcbrill/jbrill-msvc-slow
Fix for vcpkg run time issue in windows runner
2 parents 8d4d937 + 096fc51 commit 4562f2e

File tree

3 files changed

+74
-31
lines changed

3 files changed

+74
-31
lines changed

CHANGES.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
1515
From John Doe:
1616
- Whatever John Doe did.
1717

18+
From Joseph Brill:
19+
- MSVS: Fix a significant MSVC/MSVC tool initialization slowdown when
20+
vcpkg has been installed and the PSModulePath is not initialized
21+
or propagated from the user's shell environment. To resolve this
22+
The default Windows Powershell 7 path is added before the default
23+
Windows Powershell 5 path in the carefully constructed
24+
environment in which the MSVC batch files are run. The shell
25+
environment variables and values for VCPKG_DISABLE_METRICS and
26+
VCPKG_ROOT are added to the limited MSVC environment when defined.
27+
At present, the VCPKG_DISABLE_METRICS and VCPKG_ROOT variables and
28+
values are not propagated to the SCons environment after running
29+
the MSVC batch files.
30+
1831
From Bill Prendergast:
1932
- Fixed SCons.Variables.PackageVariable to correctly test the default
2033
setting against both enable & disable strings. (Fixes #4702)

RELEASE.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,17 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
3535
one from PEP 308 introduced in Python 2.5 (2006). The idiom being
3636
replaced (using and/or) is regarded as error prone.
3737

38+
- MSVS: The default Windows powershell 7 path is added before the default
39+
Windows powershell 5 path in the limited environment in which the
40+
MSVC batch files are run.
41+
3842
FIXES
3943
-----
4044

4145
- Fixed SCons.Variables.PackageVariable to correctly test the default
4246
setting against both enable & disable strings. (Fixes #4702)
47+
- MSVS: Fix significant slowdown initializing MSVC tools when vcpkg has
48+
been installed on the system.
4349

4450
IMPROVEMENTS
4551
------------

SCons/Tool/MSCommon/common.py

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,40 @@
3838
import SCons.Util
3939
import SCons.Warnings
4040

41+
42+
# TODO: Hard-coded list of the variables that (may) need to be
43+
# imported from os.environ[] for the chain of development batch
44+
# files to execute correctly. One call to vcvars*.bat may
45+
# end up running a dozen or more scripts, changes not only with
46+
# each release but with what is installed at the time. We think
47+
# in modern installations most are set along the way and don't
48+
# need to be picked from the env, but include these for safety's sake.
49+
# Any VSCMD variables definitely are picked from the env and
50+
# control execution in interesting ways.
51+
# Note these really should be unified - either controlled by vs.py,
52+
# or synced with the the common_tools_var # settings in vs.py.
53+
VS_VC_VARS = [
54+
'COMSPEC', # path to "shell"
55+
'OS', # name of OS family: Windows_NT or undefined (95/98/ME)
56+
'VS170COMNTOOLS', # path to common tools for given version
57+
'VS160COMNTOOLS',
58+
'VS150COMNTOOLS',
59+
'VS140COMNTOOLS',
60+
'VS120COMNTOOLS',
61+
'VS110COMNTOOLS',
62+
'VS100COMNTOOLS',
63+
'VS90COMNTOOLS',
64+
'VS80COMNTOOLS',
65+
'VS71COMNTOOLS',
66+
'VSCOMNTOOLS',
67+
'MSDevDir',
68+
'VSCMD_DEBUG', # enable logging and other debug aids
69+
'VSCMD_SKIP_SENDTELEMETRY',
70+
'windir', # windows directory (SystemRoot not available in 95/98/ME)
71+
'VCPKG_DISABLE_METRICS',
72+
'VCPKG_ROOT',
73+
]
74+
4175
class MSVCCacheInvalidWarning(SCons.Warnings.WarningOnByDefault):
4276
pass
4377

@@ -325,6 +359,9 @@ def normalize_env(env, keys, force: bool=False):
325359
for k in keys:
326360
if k in os.environ and (force or k not in normenv):
327361
normenv[k] = os.environ[k]
362+
debug("keys: normenv[%s]=%s", k, normenv[k])
363+
else:
364+
debug("keys: skipped[%s]", k)
328365

329366
# add some things to PATH to prevent problems:
330367
# Shouldn't be necessary to add system32, since the default environment
@@ -342,6 +379,18 @@ def normalize_env(env, keys, force: bool=False):
342379
if sys32_wbem_dir not in normenv['PATH']:
343380
normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir
344381

382+
# ProgramFiles for PowerShell 7 Path and PSModulePath
383+
progfiles_dir = os.environ.get("ProgramFiles")
384+
if not progfiles_dir:
385+
sysroot_drive, _ = os.path.splitdrive(sys32_dir)
386+
sysroot_path = sysroot_drive + os.sep
387+
progfiles_dir = os.path.join(sysroot_path, "Program Files")
388+
389+
# Powershell 7
390+
progfiles_ps_dir = os.path.join(progfiles_dir, "PowerShell", "7")
391+
if progfiles_ps_dir not in normenv["PATH"]:
392+
normenv["PATH"] = normenv["PATH"] + os.pathsep + progfiles_ps_dir
393+
345394
# Without Powershell in PATH, an internal call to a telemetry
346395
# function (starting with a VS2019 update) can fail
347396
# Note can also set VSCMD_SKIP_SENDTELEMETRY to avoid this.
@@ -353,48 +402,22 @@ def normalize_env(env, keys, force: bool=False):
353402
return normenv
354403

355404

405+
406+
356407
def get_output(vcbat, args=None, env=None, skip_sendtelemetry=False):
357408
"""Parse the output of given bat file, with given args."""
358409

359410
if env is None:
360411
# Create a blank environment, for use in launching the tools
361412
env = SCons.Environment.Environment(tools=[])
362413

363-
# TODO: Hard-coded list of the variables that (may) need to be
364-
# imported from os.environ[] for the chain of development batch
365-
# files to execute correctly. One call to vcvars*.bat may
366-
# end up running a dozen or more scripts, changes not only with
367-
# each release but with what is installed at the time. We think
368-
# in modern installations most are set along the way and don't
369-
# need to be picked from the env, but include these for safety's sake.
370-
# Any VSCMD variables definitely are picked from the env and
371-
# control execution in interesting ways.
372-
# Note these really should be unified - either controlled by vs.py,
373-
# or synced with the the common_tools_var # settings in vs.py.
374-
vs_vc_vars = [
375-
'COMSPEC', # path to "shell"
376-
'OS', # name of OS family: Windows_NT or undefined (95/98/ME)
377-
'VS170COMNTOOLS', # path to common tools for given version
378-
'VS160COMNTOOLS',
379-
'VS150COMNTOOLS',
380-
'VS140COMNTOOLS',
381-
'VS120COMNTOOLS',
382-
'VS110COMNTOOLS',
383-
'VS100COMNTOOLS',
384-
'VS90COMNTOOLS',
385-
'VS80COMNTOOLS',
386-
'VS71COMNTOOLS',
387-
'VSCOMNTOOLS',
388-
'MSDevDir',
389-
'VSCMD_DEBUG', # enable logging and other debug aids
390-
'VSCMD_SKIP_SENDTELEMETRY',
391-
'windir', # windows directory (SystemRoot not available in 95/98/ME)
392-
]
393-
env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False)
414+
env['ENV'] = normalize_env(env['ENV'], VS_VC_VARS, force=False)
394415

395416
if skip_sendtelemetry:
396417
_force_vscmd_skip_sendtelemetry(env)
397418

419+
# debug("ENV=%r", env['ENV'])
420+
398421
if args:
399422
debug("Calling '%s %s'", vcbat, args)
400423
cmd_str = '"%s" %s & set' % (vcbat, args)
@@ -460,6 +483,7 @@ def add_env(rmatch, key, dkeep=dkeep) -> None:
460483
# it.
461484
path = path.strip('"')
462485
dkeep[key].append(str(path))
486+
debug("dkeep[%s].append(%r)", key, path)
463487

464488
for line in output.splitlines():
465489
for k, value in rdk.items():

0 commit comments

Comments
 (0)