зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1515528 - Detect MSVC paths separately for host and target. r=chmanchester
Because MSVC compilers only support one architecture, we need to search "cl" in different toolchain search paths for each of the host and target, especially when they are different. Likewise for the library paths for the linker. Ideally we'd pass -LIBPATH both for host and target, but that has implications for rust that I don't want to have to figure just now. Depends on D15263 Differential Revision: https://phabricator.services.mozilla.com/D15264 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
f90954f379
Коммит
9936784a53
|
@ -713,38 +713,46 @@ def vs_major_version(value):
|
|||
return {'2017': 15}[value[0]]
|
||||
|
||||
|
||||
@depends(host, target, vs_major_version, check_build_environment, '--with-visual-studio-version')
|
||||
@imports(_from='__builtin__', _import='sorted')
|
||||
@imports(_from='operator', _import='itemgetter')
|
||||
@imports('platform')
|
||||
def vc_compiler_path(host, target, vs_major_version, env, vs_release_name):
|
||||
if host.kernel != 'WINNT':
|
||||
return
|
||||
vc_target = {
|
||||
'x86': 'x86',
|
||||
'x86_64': 'x64',
|
||||
'arm': 'arm',
|
||||
'aarch64': 'arm64'
|
||||
}.get(target.cpu)
|
||||
if vc_target is None:
|
||||
return
|
||||
@template
|
||||
def vc_compiler_path_for(host_or_target):
|
||||
@depends(host, host_or_target, vs_major_version, check_build_environment,
|
||||
'--with-visual-studio-version')
|
||||
@imports(_from='__builtin__', _import='sorted')
|
||||
@imports(_from='operator', _import='itemgetter')
|
||||
@imports('platform')
|
||||
def vc_compiler_path(host, target, vs_major_version, env, vs_release_name):
|
||||
if host.kernel != 'WINNT':
|
||||
return
|
||||
vc_target = {
|
||||
'x86': 'x86',
|
||||
'x86_64': 'x64',
|
||||
'arm': 'arm',
|
||||
'aarch64': 'arm64'
|
||||
}.get(target.cpu)
|
||||
if vc_target is None:
|
||||
return
|
||||
|
||||
all_versions = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0))
|
||||
if not all_versions:
|
||||
return
|
||||
if vs_major_version:
|
||||
versions = [d for (v, d) in all_versions if v.major ==
|
||||
vs_major_version]
|
||||
if not versions:
|
||||
die('Visual Studio %s could not be found!' % vs_release_name)
|
||||
data = versions[0]
|
||||
else:
|
||||
# Choose the newest version.
|
||||
data = all_versions[-1][1]
|
||||
paths = data.get(vc_target)
|
||||
if not paths:
|
||||
return
|
||||
return paths
|
||||
all_versions = sorted(get_vc_paths(env.topsrcdir), key=itemgetter(0))
|
||||
if not all_versions:
|
||||
return
|
||||
if vs_major_version:
|
||||
versions = [d for (v, d) in all_versions if v.major ==
|
||||
vs_major_version]
|
||||
if not versions:
|
||||
die('Visual Studio %s could not be found!' % vs_release_name)
|
||||
data = versions[0]
|
||||
else:
|
||||
# Choose the newest version.
|
||||
data = all_versions[-1][1]
|
||||
paths = data.get(vc_target)
|
||||
if not paths:
|
||||
return
|
||||
return paths
|
||||
return vc_compiler_path
|
||||
|
||||
|
||||
vc_compiler_path = vc_compiler_path_for(target)
|
||||
host_vc_compiler_path = vc_compiler_path_for(host)
|
||||
|
||||
|
||||
@dependable
|
||||
|
@ -754,42 +762,57 @@ def original_path():
|
|||
return environ['PATH'].split(os.pathsep)
|
||||
|
||||
|
||||
@depends(vc_compiler_path, original_path)
|
||||
@imports('os')
|
||||
@imports(_from='os', _import='environ')
|
||||
def toolchain_search_path(vc_compiler_path, original_path):
|
||||
result = list(original_path)
|
||||
@template
|
||||
def toolchain_search_path_for(host_or_target):
|
||||
vc_path = {
|
||||
host: host_vc_compiler_path,
|
||||
target: vc_compiler_path,
|
||||
}[host_or_target]
|
||||
|
||||
if vc_compiler_path:
|
||||
# The second item, if there is one, is necessary to have in $PATH for
|
||||
# Windows to load the required DLLs from there.
|
||||
if len(vc_compiler_path) > 1:
|
||||
environ['PATH'] = os.pathsep.join(result + vc_compiler_path[1:])
|
||||
@depends(vc_path, original_path)
|
||||
@imports('os')
|
||||
@imports(_from='os', _import='environ')
|
||||
def toolchain_search_path(vc_compiler_path, original_path):
|
||||
result = list(original_path)
|
||||
|
||||
# The first item is where the programs are going to be
|
||||
result.append(vc_compiler_path[0])
|
||||
if vc_compiler_path:
|
||||
# The second item, if there is one, is necessary to have in $PATH for
|
||||
# Windows to load the required DLLs from there.
|
||||
if len(vc_compiler_path) > 1:
|
||||
environ['PATH'] = os.pathsep.join(result + vc_compiler_path[1:])
|
||||
|
||||
# Also add in the location to which `mach bootstrap` or
|
||||
# `mach artifact toolchain` installs clang.
|
||||
mozbuild_state_dir = environ.get('MOZBUILD_STATE_PATH',
|
||||
os.path.expanduser(os.path.join('~', '.mozbuild')))
|
||||
bootstrap_clang_path = os.path.join(mozbuild_state_dir, 'clang', 'bin')
|
||||
result.append(bootstrap_clang_path)
|
||||
# The first item is where the programs are going to be
|
||||
result.append(vc_compiler_path[0])
|
||||
|
||||
bootstrap_cbindgen_path = os.path.join(mozbuild_state_dir, 'cbindgen')
|
||||
result.append(bootstrap_cbindgen_path)
|
||||
# Also add in the location to which `mach bootstrap` or
|
||||
# `mach artifact toolchain` installs clang.
|
||||
mozbuild_state_dir = environ.get('MOZBUILD_STATE_PATH',
|
||||
os.path.expanduser(os.path.join('~', '.mozbuild')))
|
||||
bootstrap_clang_path = os.path.join(mozbuild_state_dir, 'clang', 'bin')
|
||||
result.append(bootstrap_clang_path)
|
||||
|
||||
return result
|
||||
bootstrap_cbindgen_path = os.path.join(mozbuild_state_dir, 'cbindgen')
|
||||
result.append(bootstrap_cbindgen_path)
|
||||
|
||||
return result
|
||||
return toolchain_search_path
|
||||
|
||||
|
||||
toolchain_search_path = toolchain_search_path_for(target)
|
||||
host_toolchain_search_path = toolchain_search_path_for(host)
|
||||
|
||||
|
||||
# As a workaround until bug 1516228 and bug 1516253 are fixed, set the PATH
|
||||
# variable for the build to contain the toolchain search path.
|
||||
@depends(toolchain_search_path)
|
||||
@depends(toolchain_search_path, host_toolchain_search_path)
|
||||
@imports('os')
|
||||
@imports(_from='os', _import='environ')
|
||||
def altered_path(toolchain_search_path):
|
||||
def altered_path(toolchain_search_path, host_toolchain_search_path):
|
||||
path = environ['PATH'].split(os.pathsep)
|
||||
altered_path = list(toolchain_search_path)
|
||||
for p in host_toolchain_search_path:
|
||||
if p not in altered_path:
|
||||
altered_path.append(p)
|
||||
for p in path:
|
||||
if p not in altered_path:
|
||||
altered_path.append(p)
|
||||
|
@ -841,6 +864,10 @@ def default_c_compilers(host_or_target, other_c_compiler=None):
|
|||
# Android NDK clangs do not function as host compiler, so
|
||||
# prioritize a raw 'clang' instead.
|
||||
prioritized = info.type
|
||||
elif info.type == 'msvc' and target.cpu != host_or_target.cpu:
|
||||
# MSVC compilers only support one architecture, so we'll
|
||||
# want a cl in another (detected) path.
|
||||
prioritized = 'cl'
|
||||
|
||||
types = [prioritized] + [t for t in types if t != info.type]
|
||||
|
||||
|
@ -984,13 +1011,18 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
|
|||
# HOST_CXX variables.
|
||||
provided_compiler = provided_program(var)
|
||||
|
||||
search_path = {
|
||||
host: host_toolchain_search_path,
|
||||
target: toolchain_search_path,
|
||||
}[host_or_target]
|
||||
|
||||
# Normally, we'd use `var` instead of `_var`, but the interaction with
|
||||
# old-configure complicates things, and for now, we a) can't take the plain
|
||||
# result from check_prog as CC/CXX/HOST_CC/HOST_CXX and b) have to let
|
||||
# old-configure AC_SUBST it (because it's autoconf doing it, not us)
|
||||
compiler = check_prog('_%s' % var, what=what, progs=default_compilers,
|
||||
input=provided_compiler.program,
|
||||
paths=toolchain_search_path)
|
||||
paths=search_path)
|
||||
|
||||
@depends(compiler, provided_compiler, compiler_wrapper, host_or_target, macos_sdk)
|
||||
@checking('whether %s can be used' % what, lambda x: bool(x))
|
||||
|
|
|
@ -343,57 +343,73 @@ def include_path(vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
|||
set_config('INCLUDE', include_path)
|
||||
|
||||
|
||||
@depends(target, c_compiler, vc_path, valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
|
||||
@template
|
||||
def lib_path_for(host_or_target):
|
||||
compiler = {
|
||||
host: host_c_compiler,
|
||||
target: c_compiler,
|
||||
}[host_or_target]
|
||||
|
||||
@depends(host_or_target, dependable(host_or_target is host), compiler, vc_path,
|
||||
valid_windows_sdk_dir, valid_ucrt_sdk_dir, dia_sdk_dir)
|
||||
@imports('os')
|
||||
def lib_path(target, is_host, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
||||
if not vc_path:
|
||||
return
|
||||
sdk_target = {
|
||||
'x86': 'x86',
|
||||
'x86_64': 'x64',
|
||||
'arm': 'arm',
|
||||
'aarch64': 'arm64',
|
||||
}.get(target.cpu)
|
||||
|
||||
old_target = {
|
||||
'x86': '',
|
||||
'x86_64': 'amd64',
|
||||
'arm': 'arm',
|
||||
'aarch64': 'arm64'
|
||||
}.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)
|
||||
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 = []
|
||||
lib_env = os.environ.get('LIB')
|
||||
if lib_env and not is_host:
|
||||
libs.extend(lib_env.split(os.pathsep))
|
||||
libs.extend((
|
||||
os.path.join(vc_path, 'lib', *vc_target),
|
||||
atlmfc_dir,
|
||||
os.path.join(windows_sdk_dir.lib, 'um', sdk_target),
|
||||
os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target),
|
||||
))
|
||||
if dia_sdk_dir:
|
||||
# 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))
|
||||
return libs
|
||||
|
||||
return lib_path
|
||||
|
||||
|
||||
@depends(lib_path_for(target))
|
||||
@imports('os')
|
||||
def lib_path(target, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
|
||||
if not vc_path:
|
||||
return
|
||||
sdk_target = {
|
||||
'x86': 'x86',
|
||||
'x86_64': 'x64',
|
||||
'arm': 'arm',
|
||||
'aarch64': 'arm64',
|
||||
}.get(target.cpu)
|
||||
|
||||
old_target = {
|
||||
'x86': '',
|
||||
'x86_64': 'amd64',
|
||||
'arm': 'arm',
|
||||
'aarch64': 'arm64'
|
||||
}.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)
|
||||
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 = []
|
||||
lib_env = os.environ.get('LIB')
|
||||
if lib_env:
|
||||
libs.append(lib_env)
|
||||
libs.extend((
|
||||
os.path.join(vc_path, 'lib', *vc_target),
|
||||
atlmfc_dir,
|
||||
os.path.join(windows_sdk_dir.lib, 'um', sdk_target),
|
||||
os.path.join(ucrt_sdk_dir.lib, 'ucrt', sdk_target),
|
||||
))
|
||||
if dia_sdk_dir:
|
||||
# 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))
|
||||
def lib_path(libs):
|
||||
# Set in the environment for old-configure
|
||||
libs = os.pathsep.join(libs)
|
||||
os.environ['LIB'] = libs
|
||||
|
@ -403,6 +419,15 @@ def lib_path(target, c_compiler, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk
|
|||
set_config('LIB', lib_path)
|
||||
|
||||
|
||||
@depends(lib_path_for(host))
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
def host_linker_libpaths(libs):
|
||||
return ['-LIBPATH:%s' % quote(l) for l in libs]
|
||||
|
||||
|
||||
set_config('HOST_LINKER_LIBPATHS', host_linker_libpaths)
|
||||
|
||||
|
||||
option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool')
|
||||
|
||||
|
||||
|
@ -475,7 +500,7 @@ link = check_prog('LINKER', linker_progs_for(target),
|
|||
paths=toolchain_search_path)
|
||||
|
||||
host_link = check_prog('HOST_LINKER', linker_progs_for(host),
|
||||
paths=toolchain_search_path)
|
||||
paths=host_toolchain_search_path)
|
||||
|
||||
add_old_configure_assignment('LINKER', link)
|
||||
|
||||
|
|
|
@ -582,7 +582,7 @@ endif
|
|||
$(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS) $(call mkdir_deps,$(DEPTH)/dist/host/bin)
|
||||
$(REPORT_BUILD)
|
||||
ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
|
||||
$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LINKER_LIBPATHS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
ifdef MSMANIFEST_TOOL
|
||||
@if test -f $@.manifest; then \
|
||||
if test -f '$(srcdir)/$(notdir $@).manifest'; then \
|
||||
|
@ -643,7 +643,7 @@ endif
|
|||
$(HOST_SIMPLE_PROGRAMS): host_%$(HOST_BIN_SUFFIX): $(HOST_LIBS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
ifeq (WINNT_,$(HOST_OS_ARCH)_$(GNU_CC))
|
||||
$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
$(HOST_LINKER) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $($(notdir $@)_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LINKER_LIBPATHS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
else
|
||||
ifneq (,$(HOST_CPPSRCS)$(USE_HOST_CXX))
|
||||
$(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXX_LDFLAGS) $($(notdir $@)_OBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
|
@ -675,7 +675,7 @@ $(HOST_SHARED_LIBRARY): Makefile
|
|||
$(REPORT_BUILD)
|
||||
$(RM) $@
|
||||
ifdef _MSC_VER
|
||||
$(HOST_LINKER) -NOLOGO -DLL -OUT:$@ $($(notdir $@)_OBJS) $(HOST_CXX_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
$(HOST_LINKER) -NOLOGO -DLL -OUT:$@ $($(notdir $@)_OBJS) $(HOST_CXX_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LINKER_LIBPATHS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
else
|
||||
$(HOST_CXX) $(HOST_OUTOPTION)$@ $($(notdir $@)_OBJS) $(HOST_CXX_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
|
||||
endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче