Skip to content

Commit

Permalink
Start using vswhere.exe in vs_util.py
Browse files Browse the repository at this point in the history
Unlike GYP build, we cannot simply pass '--vcvarsall_path' in Bazel
build for Windows (#948). To support environment where Visual C++ is
installed in a non standard directory, 'vs_util.py' starts using
'vswhere.exe' [1] with this commit.

See also #1057.

 [1]: https://github.com/microsoft/vswhere

PiperOrigin-RevId: 682300183
  • Loading branch information
yukawa authored and hiroyuki-komatsu committed Oct 4, 2024
1 parent e183c13 commit ace3145
Showing 1 changed file with 58 additions and 14 deletions.
72 changes: 58 additions & 14 deletions src/build_tools/vs_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

"""A helper script to use Visual Studio."""
import json
import os
import pathlib
import subprocess
import sys
Expand All @@ -47,25 +48,68 @@ def get_vcvarsall(path_hint: Union[str, None] = None) -> pathlib.Path:
Raises:
FileNotFoundError: When 'vcvarsall.bat' cannot be found.
ChildProcessError: When 'vcvarsall.bat' cannot be executed.
"""
if path_hint is not None:
path = pathlib.Path(path_hint).resolve()
if path.exists():
return path

for program_files in ['Program Files', 'Program Files (x86)']:
for edition in ['Community', 'Professional', 'Enterprise', 'BuildTools']:
vcvarsall = pathlib.Path('C:\\', program_files, 'Microsoft Visual Studio',
'2022', edition, 'VC', 'Auxiliary', 'Build',
'vcvarsall.bat')
if vcvarsall.exists():
return vcvarsall

raise FileNotFoundError(
'Could not find vcvarsall.bat. '
'Consider using --vcvarsall_path option e.g.\n'
r' --vcvarsall_path=C:\VS\VC\Auxiliary\Build\vcvarsall.bat'
)
raise FileNotFoundError(
f'Could not find vcvarsall.bat. path_hint={path_hint}'
)

program_files_x86 = os.environ.get('ProgramFiles(x86)')
if not program_files_x86:
program_files_x86 = r'C:\Program Files (x86)'

vswhere_path = pathlib.Path(program_files_x86).joinpath(
'Microsoft Visual Studio', 'Installer', 'vswhere.exe')
if not vswhere_path.exists():
raise FileNotFoundError(
'Could not find vswhere.exe.'
'Consider using --vcvarsall_path option e.g.\n'
r' --vcvarsall_path=C:\VS\VC\Auxiliary\Build\vcvarsall.bat'
)

cmd = [
str(vswhere_path),
'-products',
'Microsoft.VisualStudio.Product.Enterprise',
'Microsoft.VisualStudio.Product.Professional',
'Microsoft.VisualStudio.Product.Community',
'Microsoft.VisualStudio.Product.BuildTools',
'-requires',
'Microsoft.VisualStudio.Component.VC.Redist.14.Latest',
'-find',
'VC/Auxiliary/Build/vcvarsall.bat',
'-utf8',
]
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=False,
text=True,
encoding='utf-8')
stdout, stderr = process.communicate()
exitcode = process.wait()
if exitcode != 0:
msgs = ['Failed to execute vswhere.exe']
if stdout:
msgs += ['-----stdout-----', stdout]
if stderr:
msgs += ['-----stderr-----', stderr]
raise ChildProcessError('\n'.join(msgs))

vcvarsall = pathlib.Path(stdout.splitlines()[0])
if not vcvarsall.exists():
raise FileNotFoundError(
'Could not find vcvarsall.bat.'
'Consider using --vcvarsall_path option e.g.\n'
r' --vcvarsall_path=C:\VS\VC\Auxiliary\Build\vcvarsall.bat'
)

return vcvarsall


def get_vs_env_vars(
Expand Down

0 comments on commit ace3145

Please sign in to comment.