Bug 1364137 - Find the right registry keys for python64. - r=glandium draft
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 10 May 2017 18:11:46 -0700
changeset 576368 478bc4813080f3e0678c96aa87a81f870e119aa2
parent 574519 b21b974d60d3075ae24f6fb1bae75d0f122f28fc
child 628179 3203240df8ef09f360410524a055e222f91a448b
push id58341
push userbmo:jgilbert@mozilla.com
push dateThu, 11 May 2017 17:34:01 +0000
reviewersglandium
bugs1364137
milestone55.0a1
Bug 1364137 - Find the right registry keys for python64. - r=glandium Also switch the key we check from 'Windows Kits' to 'Microsoft SDKs\Windows'.
build/moz.configure/util.configure
build/moz.configure/windows.configure
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -210,114 +210,16 @@ def try_invoke_compiler(compiler, langua
 def unique_list(l):
     result = []
     for i in l:
         if l not in result:
             result.append(i)
     return result
 
 
-# Get values out of the Windows registry. This function can only be called on
-# Windows.
-# The `pattern` argument is a string starting with HKEY_ and giving the full
-# "path" of the registry key to get the value for, with backslash separators.
-# The string can contains wildcards ('*').
-# The result of this functions is an enumerator yielding tuples for each
-# match. Each of these tuples contains the key name matching wildcards
-# followed by the value.
-#
-# Examples:
-#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
-#                       r'Windows Kits\Installed Roots\KitsRoot*')
-#   yields e.g.:
-#     ('KitsRoot81', r'C:\Program Files (x86)\Windows Kits\8.1\')
-#     ('KitsRoot10', r'C:\Program Files (x86)\Windows Kits\10\')
-#
-#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
-#                       r'Windows Kits\Installed Roots\KitsRoot8.1')
-#   yields e.g.:
-#     (r'C:\Program Files (x86)\Windows Kits\8.1\',)
-#
-#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
-#                       r'Windows Kits\*\KitsRoot*')
-#   yields e.g.:
-#     ('Installed Roots', 'KitsRoot81',
-#      r'C:\Program Files (x86)\Windows Kits\8.1\')
-#     ('Installed Roots', 'KitsRoot10',
-#      r'C:\Program Files (x86)\Windows Kits\10\')
-#
-#   get_registry_values(r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\'
-#                       r'VisualStudio\VC\*\x86\*\Compiler')
-#   yields e.g.:
-#     ('19.0', 'arm', r'C:\...\amd64_arm\cl.exe')
-#     ('19.0', 'x64', r'C:\...\amd64\cl.exe')
-#     ('19.0', 'x86', r'C:\...\amd64_x86\cl.exe')
-@imports(_import='_winreg', _as='winreg')
-@imports(_from='__builtin__', _import='WindowsError')
-@imports(_from='fnmatch', _import='fnmatch')
-def get_registry_values(pattern):
-    def enum_helper(func, key):
-        i = 0
-        while True:
-            try:
-                yield func(key, i)
-            except WindowsError:
-                break
-            i += 1
-
-    def get_keys(key, pattern):
-        try:
-            s = winreg.OpenKey(key, '\\'.join(pattern[:-1]))
-        except WindowsError:
-            return
-        for k in enum_helper(winreg.EnumKey, s):
-            if fnmatch(k, pattern[-1]):
-                try:
-                    yield k, winreg.OpenKey(s, k)
-                except WindowsError:
-                    pass
-
-    def get_values(key, pattern):
-        try:
-            s = winreg.OpenKey(key, '\\'.join(pattern[:-1]))
-        except WindowsError:
-            return
-        for k, v, t in enum_helper(winreg.EnumValue, s):
-            if fnmatch(k, pattern[-1]):
-                yield k, v
-
-    def split_pattern(pattern):
-        subpattern = []
-        for p in pattern:
-            subpattern.append(p)
-            if '*' in p:
-                yield subpattern
-                subpattern = []
-        if subpattern:
-            yield subpattern
-
-    pattern = pattern.split('\\')
-    assert pattern[0].startswith('HKEY_')
-    keys = [(getattr(winreg, pattern[0]),)]
-    pattern = list(split_pattern(pattern[1:]))
-    for i, p in enumerate(pattern):
-        next_keys = []
-        for base_key in keys:
-            matches = base_key[:-1]
-            base_key = base_key[-1]
-            if i == len(pattern) - 1:
-                want_name = '*' in p[-1]
-                for name, value in get_values(base_key, p):
-                    yield matches + ((name, value) if want_name else (value,))
-            else:
-                for name, k in get_keys(base_key, p):
-                    next_keys.append(matches + (name, k))
-        keys = next_keys
-
-
 @imports(_from='mozbuild.configure.util', _import='Version', _as='_Version')
 def Version(v):
     'A version number that can be compared usefully.'
     return _Version(v)
 
 # Denotes a deprecated option. Combines option() and @depends:
 # @deprecated_option('--option')
 # def option(value):
--- a/build/moz.configure/windows.configure
+++ b/build/moz.configure/windows.configure
@@ -22,25 +22,44 @@ def valid_windows_version(value):
 
     die('Invalid value for --with-windows-version (%s)', value[0])
 
 
 option(env='WINDOWSSDKDIR', nargs=1,
        help='Directory containing the Windows SDK')
 
 @depends('WINDOWSSDKDIR', host)
+@imports(_from='__builtin__', _import='WindowsError')
+@imports(_import='_winreg', _as='winreg')
 def windows_sdk_dir(value, host):
     if value:
         return value
     if host.kernel != 'WINNT':
         return ()
 
-    return tuple(x[1] for x in get_registry_values(
-        r'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Kits\Installed Roots'
-        r'\KitsRoot*'))
+    software_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE')
+    try:
+        software_key = winreg.OpenKey(software_key, 'WOW6432Node')
+    except WindowsError:
+        # 32-bit python
+        pass
+
+    sdks_key = winreg.OpenKey(software_key, 'Microsoft\Microsoft SDKs\Windows')
+    sdk_dirs = []
+
+    for version_subkey in ['v8.1', 'v10.0']:
+        try:
+            sdk_key = winreg.OpenKey(sdks_key, version_subkey)
+        except WindowsError:
+            continue
+        (dir, _) = winreg.QueryValueEx(sdk_key, 'InstallationFolder')
+        sdk_dirs.append(dir)
+        continue
+
+    return sdk_dirs
 
 # The Windows SDK 8.1 and 10 have different layouts. The former has
 # $SDK/include/$subdir, while the latter has $SDK/include/$version/$subdir.
 # The vcvars* scripts don't actually care about the version, they just take
 # the last alphanumerically.
 # The $SDK/lib directories always have version subdirectories, but while the
 # versions match the one in $SDK/include for SDK 10, it's "winv6.3" for SDK
 # 8.1.