Skip to content

Commit 7a0e274

Browse files
committed
Fix vswhere search for msbuild on Python 3, and demote pywin32 as optional when only enabling emsdk for current command prompt instance. Fixes #177
1 parent 0d8576c commit 7a0e274

File tree

1 file changed

+27
-10
lines changed

1 file changed

+27
-10
lines changed

emsdk

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def vswhere(version):
118118
# Visual Studio 2017 Express is not included in the above search, and it does not have the VC.Tools.x86.x64 tool, so do a catch-all attempt as a fallback, to detect Express version.
119119
if len(output) == 0:
120120
output = json.loads(subprocess.check_output([vswhere_path, '-latest', '-version', '[%s.0,%s.0)' % (version, version + 1), '-products', '*', '-property', 'installationPath', '-format', 'json']))
121-
return output[0]['installationPath'].encode('ascii') if len(output) > 0 else ''
121+
return str(output[0]['installationPath']) if len(output) > 0 else ''
122122
except Exception as e:
123123
return ''
124124

@@ -174,14 +174,22 @@ def remove_tree(d):
174174
if VERBOSE: print('remove_tree threw an exception, ignoring: ' + str(e))
175175
pass
176176

177+
def import_pywin32():
178+
if WINDOWS:
179+
try:
180+
import win32api, win32con
181+
except Exception as e:
182+
print('Failed to import Python Windows extensions win32api and win32con. Make sure you are using the version of python available in emsdk, or install PyWin extensions to the distribution of Python you are attempting to use. (This script was launched in python instance from "' + sys.executable + '")')
183+
sys.exit(1)
184+
177185
def win_set_environment_variable_direct(key, value, system=True):
178186
prev_path = os.environ['PATH']
179187
try:
180188
py = find_used_python()
181189
if py:
182190
py_path = to_native_path(py.expand_vars(py.activated_path))
183191
os.environ['PATH'] = os.environ['PATH'] + ';' + py_path
184-
import win32api, win32con
192+
import_pywin32()
185193
if system: # Read globally from ALL USERS section.
186194
folder = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment', 0, win32con.KEY_ALL_ACCESS)
187195
else: # Register locally from CURRENT USER section.
@@ -209,12 +217,17 @@ def win_get_environment_variable(key, system=True):
209217
if py:
210218
py_path = to_native_path(py.expand_vars(py.activated_path))
211219
os.environ['PATH'] = os.environ['PATH'] + ';' + py_path
212-
import win32api, win32con
213-
if system: # Read globally from ALL USERS section.
214-
folder = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
215-
else: # Register locally from CURRENT USER section.
216-
folder = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'Environment')
217-
value = str(win32api.RegQueryValueEx(folder, key)[0])
220+
try:
221+
import win32api, win32con
222+
if system: # Read globally from ALL USERS section.
223+
folder = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, 'SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
224+
else: # Register locally from CURRENT USER section.
225+
folder = win32api.RegOpenKey(win32con.HKEY_CURRENT_USER, 'Environment')
226+
value = str(win32api.RegQueryValueEx(folder, key)[0])
227+
except Exception as e:
228+
# PyWin32 is not available - read via os.environ. This has the drawback that expansion items such as %PROGRAMFILES% will have been expanded, so
229+
# need to be precise not to set these back to system registry, or expansion items would be lost.
230+
return os.environ[key]
218231
except Exception as e:
219232
if e[0] != 2: # 'The system cannot find the file specified.'
220233
print('Failed to read environment variable ' + key + ':', file=sys.stderr)
@@ -650,7 +663,7 @@ def build_env(generator):
650663

651664
elif 'Visual Studio 15' in generator:
652665
path = vswhere(15)
653-
build_env['VCTargetsPath'] = os.path.join(path, 'Common7\IDE\VC\VCTargets')
666+
build_env['VCTargetsPath'] = os.path.join(path, 'Common7\\IDE\\VC\\VCTargets')
654667

655668
# CMake and VS2017 cl.exe needs to have mspdb140.dll et al. in its PATH.
656669
vc_bin_paths = [vs_filewhere(path, 'amd64', 'cl.exe'),
@@ -700,6 +713,8 @@ def find_msbuild(sln_file):
700713
os.path.join(os.environ['ProgramFiles(x86)'], 'MSBuild/12.0/Bin')]
701714
search_paths_old = [os.path.join(os.environ["WINDIR"], 'Microsoft.NET/Framework/v4.0.30319')]
702715
generator = get_generator_for_sln_file(sln_file)
716+
if VERBOSE:
717+
print('find_msbuild looking for generator ' + str(generator))
703718
if generator == 'Visual Studio 15':
704719
path = vswhere(15)
705720
search_paths = [os.path.join(path, 'MSBuild/15.0/Bin/amd64'),
@@ -713,6 +728,8 @@ def find_msbuild(sln_file):
713728

714729
for path in search_paths:
715730
p = os.path.join(path, 'MSBuild.exe')
731+
if VERBOSE:
732+
print('Searching for MSBuild.exe: ' + p)
716733
if os.path.isfile(p): return p
717734
if VERBOSE:
718735
print('MSBuild.exe in PATH? ' + str(which('MSBuild.exe')))
@@ -730,7 +747,7 @@ def make_build(build_root, build_type, build_target_platform='x64'):
730747

731748
if WINDOWS:
732749
if 'Visual Studio' in CMAKE_GENERATOR:
733-
solution_name = subprocess.check_output(['dir', '/b', '*.sln'], shell=True, cwd=build_root).strip()
750+
solution_name = str(subprocess.check_output(['dir', '/b', '*.sln'], shell=True, cwd=build_root).decode('utf-8').strip())
734751
generator_to_use = get_generator_for_sln_file(os.path.join(build_root, solution_name))
735752
# Disabled for now: Don't pass /maxcpucount argument to msbuild, since it looks like when building, msbuild already automatically spawns the full amount of logical
736753
# cores the system has, and passing the number of logical cores here has been observed to give a quadratic N*N explosion on the number of spawned processes

0 commit comments

Comments
 (0)