diff options
author | Jeremy Andrews <athenian200@outlook.com> | 2022-07-01 17:43:55 -0500 |
---|---|---|
committer | Jeremy Andrews <athenian200@outlook.com> | 2022-07-02 13:05:26 -0500 |
commit | 057c632bee4c1d2ec9e1546229227583ea4fc835 (patch) | |
tree | 75ecfb67a9e1f77a229598f48bbe97b80839227b /build | |
parent | 07689ab83f78ea379e744fdb473b22ed0f9ebf95 (diff) | |
download | uxp-057c632bee4c1d2ec9e1546229227583ea4fc835.tar.gz |
Issue #1956 - Allow building with newer MSVC versions.
Diffstat (limited to 'build')
-rw-r--r-- | build/moz.configure/toolchain.configure | 82 | ||||
-rw-r--r-- | build/moz.configure/windows.configure | 45 | ||||
-rw-r--r-- | build/win32/vswhere.exe | bin | 0 -> 469952 bytes |
3 files changed, 73 insertions, 54 deletions
diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index ee14ce009e..e1df749456 100644 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -383,57 +383,63 @@ def check_compiler(compiler, language, target): ) -@imports(_from='collections', _import='defaultdict') +@imports(_from='__builtin__', _import='open') +@imports('json') +@imports('subprocess') +def get_vc_paths(topsrcdir): + def vswhere(args): + return json.loads(subprocess.check_output([os.path.join(topsrcdir, 'build/win32/vswhere.exe'), '-format', 'json'] + args)) + + # Can't pass -requires with -legacy, so query each separately. + # Legacy versions first (VS2015) + for install in vswhere(['-legacy', '-version', '[14.0,15.0)']): + version = Version(install['installationVersion']) + # Skip anything older than VS2015. + if version < '14': + continue + path = install['installationPath'] + + yield (Version(install['installationVersion']), { + 'x64': [os.path.join(path, r'VC\bin\amd64')], + # The x64->x86 cross toolchain requires DLLs from the native x64 toolchain. + 'x86': [os.path.join(path, r'VC\bin\amd64_x86'), os.path.join (path, r'VC\bin\amd64')], + }) + # Then VS2017 and newer. + for install in vswhere(['-requires', 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64']): + path = install['installationPath'] + tools_version = open(os.path.join(path, r'VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt'), 'rb').read().strip() + tools_path = os.path.join(path, r'VC\Tools\MSVC', tools_version, r'bin\HostX64') + yield (Version(install['installationVersion']), { + 'x64': [os.path.join(tools_path, 'x64')], + # The x64->x86 cross toolchain requires DLLs from the native x64 toolchain. + 'x86': [os.path.join(tools_path, 'x86'), os.path.join(tools_path, 'x64')], + }) + + +@depends(host, target, check_build_environment) @imports(_from='__builtin__', _import='sorted') -def get_vc_paths(base): - vc = defaultdict(lambda: defaultdict(dict)) - subkey = r'Microsoft\VisualStudio\VC\*\*\*\Compiler' - for v, h, t, p in get_registry_values(base + '\\' + subkey): - vc[v][h][t] = p - if not vc: - return - version, data = sorted(vc.iteritems(), key=lambda x: Version(x[0]))[-1] - return data - - -@depends(host) +@imports(_from='operator', _import='itemgetter') @imports('platform') -def vc_compiler_path(host): +def vc_compiler_path(host, target, env): if host.kernel != 'WINNT': return - vc_host = { - 'x86': 'x86', - 'AMD64': 'x64', - }.get(platform.machine()) - if vc_host is None: - return vc_target = { 'x86': 'x86', 'x86_64': 'x64', 'arm': 'arm', - }.get(host.cpu) + }.get(target.cpu) if vc_target is None: return - - base_key = r'HKEY_LOCAL_MACHINE\SOFTWARE' - data = get_vc_paths(base_key) - if not data: - data = get_vc_paths(base_key + r'\Wow6432Node') - if not data: + all_versions = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0)) + if not all_versions: return - path = data.get(vc_host, {}).get(vc_target) - if not path and vc_host == 'x64': - vc_host = 'x86' - path = data.get(vc_host, {}).get(vc_target) - if not path: + # Choose the newest version. + data = all_versions[-1][1] + paths = data.get(vc_target) + if not paths: return - path = os.path.dirname(path) - if vc_host != vc_target: - other_path = data.get(vc_host, {}).get(vc_host) - if other_path: - return (path, os.path.dirname(other_path)) - return (path,) + return paths @depends(vc_compiler_path) diff --git a/build/moz.configure/windows.configure b/build/moz.configure/windows.configure index 1ad2cd3eb6..f139013aeb 100644 --- a/build/moz.configure/windows.configure +++ b/build/moz.configure/windows.configure @@ -261,13 +261,17 @@ def vc_path(c_compiler): break return result - -@depends_win(vc_path) +@depends_win(vc_path, c_compiler) @checking('for the Debug Interface Access SDK', lambda x: x or 'not found') @imports(_from='os.path', _import='isdir') -def dia_sdk_dir(vc_path): +def dia_sdk_dir(vc_path, c_compiler): if vc_path: - path = os.path.join(os.path.dirname(vc_path), 'DIA SDK') + if c_compiler.version < '19.10': + path = os.path.join(os.path.dirname(vc_path), 'DIA SDK') + else: + # This would be easier if we had the installationPath that + # get_vc_paths works with, since 'DIA SDK' is relative to that. + path = os.path.normpath(os.path.join(vc_path, r'..\..\..\..\DIA SDK')) if isdir(path): return path @@ -309,28 +313,35 @@ def include_path(vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir): set_config('INCLUDE', include_path) -@depends_win(target, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir) +@depends_win(target, c_compiler, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir) @imports('os') -def lib_path(target, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir): +def lib_path(target, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir): if not vc_path: return - vc_target = { + sdk_target = { + 'x86': 'x86', + 'x86_64': 'x64', + 'arm': 'arm', + }.get(target.cpu) + + old_target = { 'x86': '', 'x86_64': 'amd64', 'arm': 'arm', }.get(target.cpu) - if vc_target is None: + if old_target is None: return - # As vc_target can be '', and os.path.join will happily use the empty + # As old_target can be '', and os.path.join will happily use the empty # string, leading to a string ending with a backslash, that Make will # interpret as a "string continues on next line" indicator, use variable # args. - vc_target = (vc_target,) if vc_target else () - sdk_target = { - 'x86': 'x86', - 'x86_64': 'x64', - 'arm': 'arm', - }.get(target.cpu) + old_target = (old_target,) if old_target else () + if c_compiler.version < '19.10': + # MSVC2015 + vc_target = old_target + else: + # MSVC2017 switched to use the same target naming as the sdk. + vc_target = (sdk_target,) atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', *vc_target) if not os.path.isdir(atlmfc_dir): @@ -349,7 +360,9 @@ def lib_path(target, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir): os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target), )) if dia_sdk_dir: - libs.append(os.path.join(dia_sdk_dir, 'lib', *vc_target)) + # For some reason the DIA SDK still uses the old-style targets + # even in a newer MSVC. + libs.append(os.path.join(dia_sdk_dir, 'lib', *old_target)) # Set in the environment for old-configure libs = os.pathsep.join(libs) os.environ['LIB'] = libs diff --git a/build/win32/vswhere.exe b/build/win32/vswhere.exe Binary files differnew file mode 100644 index 0000000000..ab3c7f3fce --- /dev/null +++ b/build/win32/vswhere.exe |