зеркало из https://github.com/mozilla/gecko-dev.git
bug 1318143 - add support for detecting Visual Studio 2017 to configure. r=gps
This patch adds a copy of vswhere.exe to build/win32, downloaded from the current latest release (1.0.62): https://github.com/Microsoft/vswhere/releases/download/1.0.62/vswhere.exe It changes toolchain.configure to invoke vswhere.exe instead of reading the registry, since that no longer works for VS2017 (but vswhere can locate VS2015). It also removes a layer of complexity in that code by dropping support for non-64-bit host systems, since we don't really support building on 32-bit Windows anymore anyway. There's a little bit of fixup in windows.configure where some LIB paths have changed in 2017. MozReview-Commit-ID: 5XLWjidS6W4 --HG-- extra : rebase_source : 15c69aeca3295a1811c85a9cf4c2793312dcd122
This commit is contained in:
Родитель
0956db6c55
Коммит
aaf6f64815
|
@ -410,57 +410,53 @@ 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)']):
|
||||||
|
path = install['installationPath']
|
||||||
|
yield (Version(install['installationVersion']), {
|
||||||
|
'x64': [os.path.join(path, r'VC\bin\amd64')],
|
||||||
|
'x86': [os.path.join(path, r'VC\bin\amd64_x86')],
|
||||||
|
})
|
||||||
|
# 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')
|
@imports(_from='__builtin__', _import='sorted')
|
||||||
def get_vc_paths(base):
|
@imports(_from='operator', _import='itemgetter')
|
||||||
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('platform')
|
@imports('platform')
|
||||||
def vc_compiler_path(host):
|
def vc_compiler_path(host, target, env):
|
||||||
if host.kernel != 'WINNT':
|
if host.kernel != 'WINNT':
|
||||||
return
|
return
|
||||||
vc_host = {
|
|
||||||
'x86': 'x86',
|
|
||||||
'AMD64': 'x64',
|
|
||||||
}.get(platform.machine())
|
|
||||||
if vc_host is None:
|
|
||||||
return
|
|
||||||
vc_target = {
|
vc_target = {
|
||||||
'x86': 'x86',
|
'x86': 'x86',
|
||||||
'x86_64': 'x64',
|
'x86_64': 'x64',
|
||||||
'arm': 'arm',
|
'arm': 'arm',
|
||||||
}.get(host.cpu)
|
}.get(target.cpu)
|
||||||
if vc_target is None:
|
if vc_target is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
base_key = r'HKEY_LOCAL_MACHINE\SOFTWARE'
|
version, data = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0))[-1]
|
||||||
data = get_vc_paths(base_key)
|
paths = data.get(vc_target)
|
||||||
if not data:
|
if not paths:
|
||||||
data = get_vc_paths(base_key + r'\Wow6432Node')
|
|
||||||
if not data:
|
|
||||||
return
|
return
|
||||||
|
return paths
|
||||||
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:
|
|
||||||
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,)
|
|
||||||
|
|
||||||
|
|
||||||
@depends(vc_compiler_path)
|
@depends(vc_compiler_path)
|
||||||
|
|
|
@ -252,12 +252,17 @@ def vc_path(c_compiler):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
@depends(vc_path)
|
@depends(vc_path, c_compiler)
|
||||||
@checking('for the Debug Interface Access SDK', lambda x: x or 'not found')
|
@checking('for the Debug Interface Access SDK', lambda x: x or 'not found')
|
||||||
@imports(_from='os.path', _import='isdir')
|
@imports(_from='os.path', _import='isdir')
|
||||||
def dia_sdk_dir(vc_path):
|
def dia_sdk_dir(vc_path, c_compiler):
|
||||||
if vc_path:
|
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):
|
if isdir(path):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
@ -299,37 +304,40 @@ def include_path(vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
||||||
set_config('INCLUDE', include_path)
|
set_config('INCLUDE', include_path)
|
||||||
|
|
||||||
|
|
||||||
@depends(target, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
|
@depends(target, c_compiler, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
|
||||||
@imports('os')
|
@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:
|
if not vc_path:
|
||||||
return
|
return
|
||||||
vc_target = {
|
|
||||||
'x86': '',
|
|
||||||
'x86_64': 'amd64',
|
|
||||||
'arm': 'arm',
|
|
||||||
}.get(target.cpu)
|
|
||||||
if vc_target is None:
|
|
||||||
return
|
|
||||||
# As vc_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 = {
|
sdk_target = {
|
||||||
'x86': 'x86',
|
'x86': 'x86',
|
||||||
'x86_64': 'x64',
|
'x86_64': 'x64',
|
||||||
'arm': 'arm',
|
'arm': 'arm',
|
||||||
}.get(target.cpu)
|
}.get(target.cpu)
|
||||||
|
|
||||||
|
old_target = {
|
||||||
|
'x86': '',
|
||||||
|
'x86_64': 'amd64',
|
||||||
|
'arm': 'arm',
|
||||||
|
}.get(target.cpu)
|
||||||
|
if old_target is None:
|
||||||
|
return
|
||||||
|
# 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.
|
||||||
|
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)
|
atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', *vc_target)
|
||||||
if not os.path.isdir(atlmfc_dir):
|
if not os.path.isdir(atlmfc_dir):
|
||||||
# For Visual Studio 2017
|
die('Cannot find the ATL/MFC libraries in the Visual C++ directory '
|
||||||
atlmfc_dir = os.path.join(vc_path, 'atlmfc', 'lib', sdk_target)
|
'(%s). Please install them.' % vc_path)
|
||||||
if not os.path.isdir(atlmfc_dir):
|
|
||||||
die('Cannot find the ATL/MFC libraries in the Visual C++ directory '
|
|
||||||
'(%s). Please install them.' % vc_path)
|
|
||||||
|
|
||||||
|
|
||||||
libs = []
|
libs = []
|
||||||
lib_env = os.environ.get('LIB')
|
lib_env = os.environ.get('LIB')
|
||||||
|
@ -342,7 +350,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),
|
os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target),
|
||||||
))
|
))
|
||||||
if dia_sdk_dir:
|
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
|
# Set in the environment for old-configure
|
||||||
libs = os.pathsep.join(libs)
|
libs = os.pathsep.join(libs)
|
||||||
os.environ['LIB'] = libs
|
os.environ['LIB'] = libs
|
||||||
|
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче