mpv/waftools/detections/compiler_swift.py

204 lines
7.3 KiB
Python

import re
import string
import os.path
from waflib import Utils
from distutils.version import StrictVersion
def __run(cmd):
try:
output = Utils.subprocess.check_output(cmd, stderr=Utils.subprocess.STDOUT, universal_newlines=True)
return output.strip()
except Exception:
return ""
def __add_swift_flags(ctx):
ctx.env.SWIFT_FLAGS = [
"-frontend", "-c", "-sdk", ctx.env.MACOS_SDK,
"-enable-objc-interop", "-emit-objc-header", "-parse-as-library",
]
verRe = re.compile("(?i)version\s?([\d.]+)")
ctx.env.SWIFT_VERSION = verRe.search(__run([ctx.env.SWIFT, '-version'])).group(1)
# prevent possible breakages with future swift versions
if StrictVersion(ctx.env.SWIFT_VERSION) >= StrictVersion("6.0"):
ctx.env.SWIFT_FLAGS.extend(["-swift-version", "5"])
if ctx.is_debug_build():
ctx.env.SWIFT_FLAGS.append("-g")
if ctx.is_optimization():
ctx.env.SWIFT_FLAGS.append("-O")
def __add_static_swift_library_linking_flags(ctx, swift_library):
ctx.env.append_value('LINKFLAGS', [
'-L%s' % swift_library,
'-Xlinker', '-force_load_swift_libs', '-lc++',
])
def __add_dynamic_swift_library_linking_flags(ctx, swift_library):
ctx.env.append_value('LINKFLAGS', ['-L%s' % swift_library])
# ABI compatibility
if StrictVersion(ctx.env.SWIFT_VERSION) >= StrictVersion("5.0"):
ctx.env.append_value('LINKFLAGS', [
'-Xlinker', '-rpath', '-Xlinker', '/usr/lib/swift',
'-L/usr/lib/swift',
])
ctx.env.append_value('LINKFLAGS', [
'-Xlinker', '-rpath', '-Xlinker', swift_library,
])
def __find_swift_library(ctx):
swift_libraries = {}
# look for set lib paths in passed environment variables
if 'SWIFT_LIB_DYNAMIC' in ctx.environ:
swift_libraries['SWIFT_LIB_DYNAMIC'] = ctx.environ['SWIFT_LIB_DYNAMIC']
if 'SWIFT_LIB_STATIC' in ctx.environ:
swift_libraries['SWIFT_LIB_STATIC'] = ctx.environ['SWIFT_LIB_STATIC']
# search for swift libs relative to the swift compiler executable
swift_library_relative_paths = {
'SWIFT_LIB_DYNAMIC': '../../lib/swift/macosx',
'SWIFT_LIB_STATIC': '../../lib/swift_static/macosx'
}
for lib_type, path in swift_library_relative_paths.items():
if lib_type not in swift_libraries:
lib_path = os.path.join(ctx.env.SWIFT, path)
swift_library = ctx.root.find_dir(lib_path)
if swift_library is not None:
swift_libraries[lib_type] = swift_library.abspath()
# fall back to xcode-select path
swift_library_paths = {
'SWIFT_LIB_DYNAMIC': [
'Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx',
'usr/lib/swift/macosx'
],
'SWIFT_LIB_STATIC': [
'Toolchains/XcodeDefault.xctoolchain/usr/lib/swift_static/macosx',
'usr/lib/swift_static/macosx'
]
}
dev_path = __run(['xcode-select', '-p'])[1:]
for lib_type, paths in swift_library_paths.items():
for path in paths:
if lib_type not in swift_libraries:
swift_library = ctx.root.find_dir([dev_path, path])
if swift_library is not None:
swift_libraries[lib_type] = swift_library.abspath()
break
else:
break
# check if library paths were found
ctx.start_msg('Checking for dynamic Swift Library')
if 'SWIFT_LIB_DYNAMIC' in swift_libraries:
ctx.end_msg(swift_libraries['SWIFT_LIB_DYNAMIC'])
else:
ctx.end_msg(False)
ctx.start_msg('Checking for static Swift Library')
if 'SWIFT_LIB_STATIC' in swift_libraries:
ctx.end_msg(swift_libraries['SWIFT_LIB_STATIC'])
ctx.env['SWIFT_LIB_STATIC'] = swift_libraries['SWIFT_LIB_STATIC']
else:
ctx.end_msg(False)
enableStatic = getattr(ctx.options, 'enable_swift-static')
if (enableStatic) and 'SWIFT_LIB_STATIC' in swift_libraries:
__add_static_swift_library_linking_flags(ctx, swift_libraries['SWIFT_LIB_STATIC'])
else:
__add_dynamic_swift_library_linking_flags(ctx, swift_libraries['SWIFT_LIB_DYNAMIC'])
def __find_macos_sdk(ctx):
ctx.start_msg('Checking for macOS SDK')
sdk = None
sdk_build_version = None
sdk_version = None
# look for set macOS SDK paths and version in passed environment variables
if 'MACOS_SDK' in ctx.environ:
sdk = ctx.environ['MACOS_SDK']
if 'MACOS_SDK_VERSION' in ctx.environ:
ctx.env.MACOS_SDK_VERSION = ctx.environ['MACOS_SDK_VERSION']
# find macOS SDK paths and version
if not sdk:
sdk = __run(['xcrun', '--sdk', 'macosx', '--show-sdk-path'])
if not ctx.env.MACOS_SDK_VERSION:
# show-sdk-build-version: is not available on older command line tools, but return a build version (eg 17A360)
# show-sdk-version: is always available, but on older dev tools it's only the major version
sdk_build_version = __run(['xcrun', '--sdk', 'macosx', '--show-sdk-build-version'])
sdk_version = __run(['xcrun', '--sdk', 'macosx', '--show-sdk-version'])
if sdk:
ctx.env.MACOS_SDK = sdk
build_version = '10.10.0'
if not ctx.env.MACOS_SDK_VERSION:
# convert build version to a version string
# first 2 two digits are the major version, starting with 15 which is 10.11 (offset of 4)
# 1 char is the minor version, A => 0, B => 1 and ongoing
# last digits are bugfix version, which are not relevant for us
# eg 16E185 => 10.12.4, 17A360 => 10.13, 18B71 => 10.14.1
if sdk_build_version and isinstance(sdk_build_version, str):
verRe = re.compile("(\d+)(\D+)(\d+)")
version_parts = verRe.search(sdk_build_version)
major = int(version_parts.group(1)) - 4
minor = string.ascii_lowercase.index(version_parts.group(2).lower())
build_version = '10.' + str(major) + '.' + str(minor)
# from 20 onwards macOS 11.0 starts
if int(version_parts.group(1)) >= 20:
build_version = '11.' + str(minor)
if not isinstance(sdk_version, str):
sdk_version = '10.10.0'
# pick the higher version, always pick sdk over build if newer
if StrictVersion(build_version) > StrictVersion(sdk_version):
ctx.env.MACOS_SDK_VERSION = build_version
else:
ctx.env.MACOS_SDK_VERSION = sdk_version
ctx.end_msg(sdk + ' (version found: ' + ctx.env.MACOS_SDK_VERSION + ')')
else:
ctx.end_msg(False)
def __find_swift_compiler(ctx):
ctx.start_msg('Checking for swift (Swift compiler)')
swift = ''
# look for set swift paths in passed environment variables
if 'SWIFT' in ctx.environ:
swift = ctx.environ['SWIFT']
# find swift executable
if not swift:
swift = __run(['xcrun', '-find', 'swift'])
if swift:
ctx.end_msg(swift)
ctx.env.SWIFT = swift
__add_swift_flags(ctx)
__find_swift_library(ctx)
else:
ctx.end_msg(False)
def configure(ctx):
if ctx.env.DEST_OS == "darwin":
__find_macos_sdk(ctx)
if ctx.options.enable_swift is not False:
__find_swift_compiler(ctx)