Skip to content

Fix for vcpkg run time issue in windows runner #4717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
From John Doe:
- Whatever John Doe did.

From Joseph Brill:
- MSVS: Fix a significant MSVC/MSVC tool initialization slowdown when
vcpkg has been installed and the PSModulePath is not initialized
or propagated from the user's shell environment. To resolve this
The default Windows Powershell 7 path is added before the default
Windows Powershell 5 path in the carefully constructed
environment in which the MSVC batch files are run. The shell
environment variables and values for VCPKG_DISABLE_METRICS and
VCPKG_ROOT are added to the limited MSVC environment when defined.
At present, the VCPKG_DISABLE_METRICS and VCPKG_ROOT variables and
values are not propagated to the SCons environment after running
the MSVC batch files.

From Bill Prendergast:
- Fixed SCons.Variables.PackageVariable to correctly test the default
setting against both enable & disable strings. (Fixes #4702)
Expand Down
6 changes: 6 additions & 0 deletions RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY
one from PEP 308 introduced in Python 2.5 (2006). The idiom being
replaced (using and/or) is regarded as error prone.

- MSVS: The default Windows powershell 7 path is added before the default
Windows powershell 5 path in the limited environment in which the
MSVC batch files are run.

FIXES
-----

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

IMPROVEMENTS
------------
Expand Down
86 changes: 55 additions & 31 deletions SCons/Tool/MSCommon/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,40 @@
import SCons.Util
import SCons.Warnings


# 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', # path to "shell"
'OS', # name of OS family: Windows_NT or undefined (95/98/ME)
'VS170COMNTOOLS', # path to common tools for given version
'VS160COMNTOOLS',
'VS150COMNTOOLS',
'VS140COMNTOOLS',
'VS120COMNTOOLS',
'VS110COMNTOOLS',
'VS100COMNTOOLS',
'VS90COMNTOOLS',
'VS80COMNTOOLS',
'VS71COMNTOOLS',
'VSCOMNTOOLS',
'MSDevDir',
'VSCMD_DEBUG', # enable logging and other debug aids
'VSCMD_SKIP_SENDTELEMETRY',
'windir', # windows directory (SystemRoot not available in 95/98/ME)
'VCPKG_DISABLE_METRICS',
'VCPKG_ROOT',
]

class MSVCCacheInvalidWarning(SCons.Warnings.WarningOnByDefault):
pass

Expand Down Expand Up @@ -325,6 +359,9 @@ def normalize_env(env, keys, force: bool=False):
for k in keys:
if k in os.environ and (force or k not in normenv):
normenv[k] = os.environ[k]
debug("keys: normenv[%s]=%s", k, normenv[k])
else:
debug("keys: skipped[%s]", k)

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

# ProgramFiles for PowerShell 7 Path and PSModulePath
progfiles_dir = os.environ.get("ProgramFiles")
if not progfiles_dir:
sysroot_drive, _ = os.path.splitdrive(sys32_dir)
sysroot_path = sysroot_drive + os.sep
progfiles_dir = os.path.join(sysroot_path, "Program Files")

# Powershell 7
progfiles_ps_dir = os.path.join(progfiles_dir, "PowerShell", "7")
if progfiles_ps_dir not in normenv["PATH"]:
normenv["PATH"] = normenv["PATH"] + os.pathsep + progfiles_ps_dir

# 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.
Expand All @@ -353,48 +402,22 @@ def normalize_env(env, keys, force: bool=False):
return normenv




def get_output(vcbat, args=None, env=None, skip_sendtelemetry=False):
"""Parse the output of given bat file, with given args."""

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

# 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', # path to "shell"
'OS', # name of OS family: Windows_NT or undefined (95/98/ME)
'VS170COMNTOOLS', # path to common tools for given version
'VS160COMNTOOLS',
'VS150COMNTOOLS',
'VS140COMNTOOLS',
'VS120COMNTOOLS',
'VS110COMNTOOLS',
'VS100COMNTOOLS',
'VS90COMNTOOLS',
'VS80COMNTOOLS',
'VS71COMNTOOLS',
'VSCOMNTOOLS',
'MSDevDir',
'VSCMD_DEBUG', # enable logging and other debug aids
'VSCMD_SKIP_SENDTELEMETRY',
'windir', # windows directory (SystemRoot not available in 95/98/ME)
]
env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False)
env['ENV'] = normalize_env(env['ENV'], VS_VC_VARS, force=False)

if skip_sendtelemetry:
_force_vscmd_skip_sendtelemetry(env)

# debug("ENV=%r", env['ENV'])

if args:
debug("Calling '%s %s'", vcbat, args)
cmd_str = '"%s" %s & set' % (vcbat, args)
Expand Down Expand Up @@ -460,6 +483,7 @@ def add_env(rmatch, key, dkeep=dkeep) -> None:
# it.
path = path.strip('"')
dkeep[key].append(str(path))
debug("dkeep[%s].append(%r)", key, path)

for line in output.splitlines():
for k, value in rdk.items():
Expand Down
Loading