Bug 1290026 - Automatically set LIB from configure. r=chmanchester

--HG--
extra : rebase_source : 4ca572685169fdd2fbb0c9ae6aac5361d2669569
This commit is contained in:
Mike Hommey 2016-07-27 18:01:04 +09:00
parent 9bca5c6d3a
commit 8eff2bec09
2 changed files with 118 additions and 39 deletions

View File

@ -50,31 +50,48 @@ def windows_sdk_dir(value, host):
# 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.
# 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.
@imports('os')
@imports('re')
@imports(_from='__builtin__', _import='sorted')
@imports(_from='__builtin__', _import='WindowsError')
def get_include_dir(sdk, subdir):
base = os.path.join(sdk, 'include')
try:
subdirs = [d for d in os.listdir(base)
if os.path.isdir(os.path.join(base, d))]
except WindowsError:
subdirs = []
if not subdirs:
return None
if subdir in subdirs:
return os.path.join(base, subdir)
# At this point, either we have an incomplete or invalid SDK directory,
# or we exclusively have version numbers in subdirs.
versions = sorted((Version(d) for d in subdirs), reverse=True)
# Version('non-number').major is 0, so if the biggest version we have is
# 0, we have a problem.
if versions[0].major == 0:
return None
path = os.path.join(base, str(versions[0]), subdir)
return path if os.path.isdir(path) else None
def get_sdk_dirs(sdk, subdir):
def get_dirs_containing(sdk, stem, subdir):
base = os.path.join(sdk, stem)
try:
subdirs = [d for d in os.listdir(base)
if os.path.isdir(os.path.join(base, d))]
except WindowsError:
subdirs = []
if not subdirs:
return ()
if subdir in subdirs:
return (base,)
# At this point, either we have an incomplete or invalid SDK directory,
# or we exclusively have version numbers in subdirs.
return tuple(os.path.join(base, s) for s in subdirs
if os.path.isdir(os.path.join(base, s, subdir)))
def categorize(dirs):
return {os.path.basename(d): d for d in dirs}
include_dirs = categorize(get_dirs_containing(sdk, 'include', subdir))
lib_dirs = categorize(get_dirs_containing(sdk, 'lib', subdir))
if 'include' in include_dirs:
include_dirs['winv6.3'] = include_dirs['include']
del include_dirs['include']
valid_versions = sorted(set(include_dirs) & set(lib_dirs), reverse=True)
if valid_versions:
return namespace(
path=sdk,
lib=lib_dirs[valid_versions[0]],
include=include_dirs[valid_versions[0]],
)
@imports(_from='mozbuild.shellutil', _import='quote')
@ -93,13 +110,14 @@ def valid_windows_sdk_dir(compiler, windows_sdk_dir, target_version,
windows_sdk_dir_env = windows_sdk_dir_env[0]
sdks = {}
for d in windows_sdk_dir:
um_dir = get_include_dir(d, 'um')
shared_dir = get_include_dir(d, 'shared')
if um_dir and shared_dir:
sdk = get_sdk_dirs(d, 'um')
if sdk:
check = dedent('''\
#include <winsdkver.h>
WINVER_MAXVER
''')
um_dir = os.path.join(sdk.include, 'um')
shared_dir = os.path.join(sdk.include, 'shared')
result = try_preprocess(compiler.wrapper + [compiler.compiler] +
compiler.flags +
['-I', um_dir, '-I', shared_dir], 'C',
@ -111,7 +129,7 @@ def valid_windows_sdk_dir(compiler, windows_sdk_dir, target_version,
except:
pass
else:
sdks[d] = maxver
sdks[d] = maxver, sdk
continue
if d == windows_sdk_dir_env:
raise FatalCheckError(
@ -119,9 +137,9 @@ def valid_windows_sdk_dir(compiler, windows_sdk_dir, target_version,
'WINDOWSSDKDIR (%s). Please verify it contains a valid and '
'complete SDK installation.' % windows_sdk_dir_env)
valid_sdks = sorted(sdks, key=lambda x: sdks[x], reverse=True)
valid_sdks = sorted(sdks, key=lambda x: sdks[x][0], reverse=True)
if valid_sdks:
biggest_version = sdks[valid_sdks[0]]
biggest_version, sdk = sdks[valid_sdks[0]]
if not valid_sdks or biggest_version < target_version:
if windows_sdk_dir_env:
raise FatalCheckError(
@ -137,7 +155,9 @@ def valid_windows_sdk_dir(compiler, windows_sdk_dir, target_version,
'Cannot find a Windows SDK for version >= 0x%04x.' % target_version)
return namespace(
path=valid_sdks[0],
path=sdk.path,
include=sdk.include,
lib=sdk.lib,
version=biggest_version,
)
@ -164,30 +184,34 @@ def valid_ucrt_sdk_dir(windows_sdk_dir, windows_sdk_dir_env):
windows_sdk_dir_env = windows_sdk_dir_env[0]
sdks = {}
for d in windows_sdk_dir:
ucrt_dir = get_include_dir(d, 'ucrt')
if ucrt_dir:
version = os.path.basename(os.path.dirname(ucrt_dir))
sdk = get_sdk_dirs(d, 'ucrt')
if sdk:
version = os.path.basename(sdk.include)
# We're supposed to always find a version in the directory, because
# the 8.1 SDK, which doesn't have a version in the directory, doesn't
# contain the Universal CRT SDK. When the main SDK is 8.1, there
# is, however, supposed to be a reduced install of the SDK 10
# with the UCRT.
if version != 'include':
sdks[d] = Version(version)
sdks[d] = Version(version), sdk
continue
if d == windows_sdk_dir_env:
raise FatalCheckError(
'The SDK in WINDOWSSDKDIR (%s) does not contain the Universal '
'CRT.' % windows_sdk_dir_env)
valid_sdks = sorted(sdks, key=lambda x: sdks[x], reverse=True)
valid_sdks = sorted(sdks, key=lambda x: sdks[x][0], reverse=True)
if not valid_sdks:
raise FatalCheckError('Cannot find the Universal CRT SDK. '
'Please install it.')
version, sdk = sdks[valid_sdks[0]]
return namespace(
path=valid_sdks[0],
version=sdks[valid_sdks[0]],
path=sdk.path,
include=sdk.include,
lib=sdk.lib,
version=version,
)
@ -231,7 +255,7 @@ def include_path(vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
die('Cannot find the ATL/MFC headers in the Visual C++ directory (%s). '
'Please install them.' % vc_path)
winrt_dir = get_include_dir(windows_sdk_dir.path, 'winrt')
winrt_dir = os.path.join(windows_sdk_dir.include, 'winrt')
if not os.path.isdir(winrt_dir):
die('Cannot find the WinRT headers in the Windows SDK directory (%s). '
'Please install them.' % windows_sdk_dir.path)
@ -243,10 +267,10 @@ def include_path(vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
includes.extend((
os.path.join(vc_path, 'include'),
atlmfc_dir,
get_include_dir(windows_sdk_dir.path, 'shared'),
get_include_dir(windows_sdk_dir.path, 'um'),
os.path.join(windows_sdk_dir.include, 'shared'),
os.path.join(windows_sdk_dir.include, 'um'),
winrt_dir,
get_include_dir(ucrt_sdk_dir.path, 'ucrt'),
os.path.join(ucrt_sdk_dir.include, 'ucrt'),
))
if dia_sdk_dir:
includes.append(os.path.join(dia_sdk_dir, 'include'))
@ -258,6 +282,55 @@ 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)
@imports('os')
def lib_path(target, vc_path, windows_sdk_dir, ucrt_sdk_dir, dia_sdk_dir):
if not vc_path:
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 = {
'x86': 'x86',
'x86_64': 'x64',
'arm': 'arm',
}.get(target.cpu)
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:
libs.append(os.path.join(dia_sdk_dir, 'lib', *vc_target))
# Set in the environment for old-configure
libs = os.pathsep.join(libs)
os.environ['LIB'] = libs
return libs
set_config('LIB', lib_path)
option(env='MT', nargs=1, help='Path to the Microsoft Manifest Tool')
@depends_win(valid_windows_sdk_dir)

View File

@ -364,6 +364,12 @@ ifdef INCLUDE
export INCLUDE
endif
# Export to propagate to link.exe and submake for third-party code.
# Eventually, we'll want to just use -LIBPATH.
ifdef LIB
export LIB
endif
ifdef MOZ_USING_CCACHE
ifdef CLANG_CXX
export CCACHE_CPP2=1