Bug 1560044 - Always use a SDK path on macOS. r=nalexander

The SDK headers may not be installed in /usr/include. The usual response
has been to have people run e.g. `open
/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg`
which is not really sustainable.

This makes builds that happen on a macOS host try to detect their SDK
and use that as a default for --with-macos-sdk, which has the side
effect of enabling the SDK version check in that configuration.

Differential Revision: https://phabricator.services.mozilla.com/D36558

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Mike Hommey 2019-07-03 22:11:05 +00:00
Родитель dc4a97fb4e
Коммит 7256ffeb9b
4 изменённых файлов: 74 добавлений и 19 удалений

Просмотреть файл

@ -136,23 +136,34 @@ with only_when(host_is_osx | target_is_osx):
js_option('--with-macos-sdk', env='MACOS_SDK_DIR', nargs=1,
help='Location of platform SDK to use')
@depends_if('--with-macos-sdk')
@depends('--with-macos-sdk', host)
@imports(_from='os.path', _import='isdir')
@imports(_from='biplist', _import='readPlist')
def macos_sdk(value):
def macos_sdk(sdk, host):
sdk_min_version = Version('10.11')
sdk_max_version = Version('10.14')
if not isdir(value[0]):
if sdk:
sdk = sdk[0]
elif host.os == 'OSX':
sdk = check_cmd_output('xcrun', '--show-sdk-path', onerror=lambda: '').rstrip()
if not sdk:
die('Could not find the macOS SDK. Please use --with-macos-sdk to give '
'the path to a macOS SDK.')
else:
die('Need a macOS SDK when targeting macOS. Please use --with-macos-sdk '
'to give the path to a macOS SDK.')
if not isdir(sdk):
die('SDK not found in %s. When using --with-macos-sdk, you must specify a '
'valid SDK. SDKs are installed when the optional cross-development '
'tools are selected during the Xcode/Developer Tools installation.'
% value[0])
obj = readPlist(os.path.join(value[0], 'SDKSettings.plist'))
% sdk)
obj = readPlist(os.path.join(sdk, 'SDKSettings.plist'))
if not obj:
die('Error parsing SDKSettings.plist in the SDK directory: %s' % value[0])
die('Error parsing SDKSettings.plist in the SDK directory: %s' % sdk)
if 'Version' not in obj:
die('Error finding Version information in SDKSettings.plist from the SDK: %s' % value[0])
die('Error finding Version information in SDKSettings.plist from the SDK: %s' % sdk)
version = Version(obj['Version'])
if version < sdk_min_version:
die('SDK version "%s" is too old. Please upgrade to at least %s. '
@ -164,7 +175,7 @@ with only_when(host_is_osx | target_is_osx):
'%s. You may need to point to it using --with-macos-sdk=<path> in '
'your mozconfig. Various SDK versions are available from '
'https://github.com/phracker/MacOSX-SDKs' % (version, sdk_max_version))
return value[0]
return sdk
set_config('MACOS_SDK_DIR', macos_sdk)

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Version</key>
<string>10.14</string>
</dict>
</plist>

Просмотреть файл

@ -21,6 +21,7 @@ from mozpack import path as mozpath
from test_toolchain_helpers import (
FakeCompiler,
CompilerResult,
PrependFlags,
)
@ -796,6 +797,13 @@ class LinuxX86_64CrossToolchainTest(BaseToolchainTest):
})
def xcrun(stdin, args):
if args == ('--show-sdk-path',):
return 0, os.path.join(os.path.abspath(os.path.dirname(__file__)),
'fake_macos_sdk'), ''
raise NotImplementedError()
class OSXToolchainTest(BaseToolchainTest):
HOST = 'x86_64-apple-darwin11.2.0'
PATHS = {
@ -809,6 +817,7 @@ class OSXToolchainTest(BaseToolchainTest):
'/usr/bin/clang++-4.0': CLANGXX_4_0 + CLANG_PLATFORM_X86_64_OSX,
'/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64_OSX,
'/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64_OSX,
'/usr/bin/xcrun': xcrun,
}
CLANG_3_3_RESULT = LinuxToolchainTest.CLANG_3_3_RESULT
CLANGXX_3_3_RESULT = LinuxToolchainTest.CLANGXX_3_3_RESULT
@ -818,12 +827,15 @@ class OSXToolchainTest(BaseToolchainTest):
GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT
GCC_7_RESULT = LinuxToolchainTest.GCC_7_RESULT
GXX_7_RESULT = LinuxToolchainTest.GXX_7_RESULT
SYSROOT_FLAGS = {
'flags': PrependFlags(['-isysroot', xcrun('', ('--show-sdk-path',))[1]]),
}
def test_clang(self):
# We only try clang because gcc is known not to work.
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.DEFAULT_CLANG_RESULT,
'cxx_compiler': self.DEFAULT_CLANGXX_RESULT,
'c_compiler': self.DEFAULT_CLANG_RESULT + self.SYSROOT_FLAGS,
'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + self.SYSROOT_FLAGS,
})
def test_not_gcc(self):
@ -849,8 +861,8 @@ class OSXToolchainTest(BaseToolchainTest):
def test_forced_gcc(self):
# GCC can still be forced if the user really wants it.
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.GCC_7_RESULT,
'cxx_compiler': self.GXX_7_RESULT,
'c_compiler': self.GCC_7_RESULT + self.SYSROOT_FLAGS,
'cxx_compiler': self.GXX_7_RESULT + self.SYSROOT_FLAGS,
}, environ={
'CC': 'gcc-7',
'CXX': 'g++-7',
@ -1322,17 +1334,17 @@ class OSXCrossToolchainTest(BaseToolchainTest):
def test_osx_cross(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.DEFAULT_CLANG_RESULT + {
'c_compiler': self.DEFAULT_CLANG_RESULT + OSXToolchainTest.SYSROOT_FLAGS + {
'flags': ['--target=i686-apple-darwin11.2.0'],
},
'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + {
'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + OSXToolchainTest.SYSROOT_FLAGS + {
'flags': ['--target=i686-apple-darwin11.2.0'],
},
'host_c_compiler': self.DEFAULT_CLANG_RESULT,
'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT,
}, environ={
'CC': 'clang',
})
}, args=['--with-macos-sdk=%s' % OSXToolchainTest.SYSROOT_FLAGS['flags'][1]])
def test_cannot_osx_cross(self):
self.do_toolchain_test(self.PATHS, {
@ -1340,7 +1352,7 @@ class OSXCrossToolchainTest(BaseToolchainTest):
'match --target kernel (Darwin)',
}, environ={
'CC': 'gcc',
})
}, args=['--with-macos-sdk=%s' % OSXToolchainTest.SYSROOT_FLAGS['flags'][1]])
class WindowsCrossToolchainTest(BaseToolchainTest):

Просмотреть файл

@ -173,8 +173,22 @@ class FakeCompiler(dict):
self.setdefault(key, {}).update(value)
def __call__(self, stdin, args):
files = [arg for arg in args if not arg.startswith('-')]
flags = [arg for arg in args if arg.startswith('-')]
files = []
flags = []
args = iter(args)
while True:
arg = next(args, None)
if arg is None:
break
if arg.startswith('-'):
# Ignore -isysroot and the argument that follows it.
if arg == '-isysroot':
next(args, None)
else:
flags.append(arg)
else:
files.append(arg)
if '-E' in flags:
assert len(files) == 1
file = files[0]
@ -347,6 +361,12 @@ class TestFakeCompiler(unittest.TestCase):
})
class PrependFlags(list):
'''Wrapper to allow to Prepend to flags instead of appending, in
CompilerResult.
'''
class CompilerResult(ReadOnlyNamespace):
'''Helper of convenience to manipulate toolchain results in unit tests
@ -375,7 +395,11 @@ class CompilerResult(ReadOnlyNamespace):
result = copy.deepcopy(self.__dict__)
for k, v in other.iteritems():
if k == 'flags':
result.setdefault(k, []).extend(v)
flags = result.setdefault(k, [])
if isinstance(v, PrependFlags):
flags[:0] = v
else:
flags.extend(v)
else:
result[k] = v
return CompilerResult(**result)