blob: 680e5a053c1adc489c087a4beb77ddecf56893cc [file] [edit]
# Helpers and initialization logic for building with Apple SDKs.
#
# Always pass --sdk to xcrun explicitly -- otherwise, toolchain and SDK
# are not guaranteed to match.
# Sets CMAKE_OSX_SYSROOT and _sdk_version in the caller's scope.
function(WEBKIT_RESOLVE_SDK)
foreach (_sdk IN LISTS ARGN)
execute_process(COMMAND xcrun --sdk ${_sdk} --show-sdk-path
OUTPUT_VARIABLE _sdk_path
RESULT_VARIABLE _sdk_result
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if (_sdk_result EQUAL 0 AND _sdk_path)
file(READ "${_sdk_path}/SDKSettings.json" _sdk_settings)
string(JSON _sdk_version GET ${_sdk_settings} Version)
set(_sdk_version "${_sdk_version}" PARENT_SCOPE)
string(JSON _sdk_canonical_name GET ${_sdk_settings} CanonicalName)
string(JSON _platform_name GET ${_sdk_settings} DefaultProperties PLATFORM_NAME)
message(STATUS "Xcode SDK: ${_sdk_canonical_name} at ${_sdk_path}")
set(CMAKE_OSX_SYSROOT "${_sdk_path}" CACHE PATH "" FORCE)
if (_sdk_path MATCHES "\\.[Ii]nternal.sdk$")
set(USE_APPLE_INTERNAL_SDK ON CACHE BOOL "" FORCE)
else ()
set(USE_APPLE_INTERNAL_SDK OFF CACHE BOOL "" FORCE)
endif ()
if (NOT CMAKE_OSX_ARCHITECTURES)
# Build the supported-archs list from SDKSettings.json's
# SupportedTargets.<platform>.Archs. Order works out
# to match our preferred build defaults.
string(JSON _archs_length LENGTH ${_sdk_settings}
SupportedTargets ${_platform_name} Archs)
set(_supported_archs "")
math(EXPR _archs_last "${_archs_length} - 1")
foreach (_i RANGE 0 ${_archs_last})
string(JSON _arch_i GET ${_sdk_settings}
SupportedTargets ${_platform_name} Archs ${_i})
list(APPEND _supported_archs "${_arch_i}")
endforeach ()
# FIXME: This is different from what we do in the xcodebuild. For devices,
# we default to building for all architectures supported by the device
# (for iOS devices, just arm64e). For simulators, we query the system for
# created simulator targets and match their architecture (usually arm64).
if (PORT STREQUAL "Mac" OR PORT STREQUAL "JSCOnly")
# When building for the host machine CMAKE_HOST_SYSTEM_PROCESSOR
# isn't populated until `project()` is called, so consult `uname -m`.
# Only set _arch if SDK supports arm64e otherwise let `project()`
# configure.
execute_process(COMMAND uname -m
OUTPUT_VARIABLE _host_arch
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_host_arch STREQUAL "arm64" AND USE_APPLE_INTERNAL_SDK
AND "arm64e" IN_LIST _supported_archs)
set(_arch "arm64e")
set(_arch_reason "internal SDK + arm64 host")
endif ()
else ()
# When Cross-compiling, just trust the SDKSettings's ordering.
list(GET _supported_archs 0 _arch)
set(_arch_reason "first SDK-supported arch")
endif ()
if (DEFINED _arch)
set(CMAKE_OSX_ARCHITECTURES "${_arch}"
CACHE STRING "Target architecture" FORCE)
message(STATUS "Architecture: ${_arch} (${_arch_reason})")
endif ()
endif ()
return()
endif ()
endforeach ()
message(FATAL_ERROR "xcrun could not locate any SDK in: ${ARGN}")
endfunction()
# Runs `xcrun and capture stdout in OUTPUT_VAR
# (in the caller's scope).
function(WEBKIT_XCRUN OUTPUT_VAR)
if (NOT CMAKE_OSX_SYSROOT)
message(FATAL_ERROR "WEBKIT_XCRUN called before WEBKIT_RESOLVE_SDK")
endif ()
execute_process(COMMAND xcrun ${ARGN}
OUTPUT_VARIABLE _out
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
set(${OUTPUT_VAR} "${_out}" PARENT_SCOPE)
endfunction()
function(WEBKIT_RESOLVE_TOOL OUTPUT_VAR _tool)
if (DEFINED ${OUTPUT_VAR})
return()
endif ()
WEBKIT_XCRUN(_path -f ${_tool})
if (NOT EXISTS "${_path}")
message(SEND_ERROR "Cannot find ${_tool} in the active SDK and "
"toolchain (${CMAKE_OSX_SYSROOT})")
else ()
set(${OUTPUT_VAR} "${_path}" CACHE STRING "" FORCE)
endif ()
endfunction()
# Run Source/${PROJECT}/Scripts/process-entitlements.sh against an executable
# target and ad-hoc codesign it with the resulting entitlements. Mirrors the
# Xcode build's "Process Entitlements" build phase plus the signing step.
#
# Usage:
# WEBKIT_PROCESS_ENTITLEMENTS(target PROJECT name [PRODUCT_NAME name])
#
# PROJECT names the directory under Source/ containing Scripts/process-entitlements.sh
# (e.g. JavaScriptCore, WebKit). PRODUCT_NAME defaults to the CMake target name;
# set it explicitly when the script's dispatcher keys off a different name.
function(WEBKIT_PROCESS_ENTITLEMENTS _target)
cmake_parse_arguments(_arg "" "PROJECT;PRODUCT_NAME" "" ${ARGN})
if (NOT _arg_PROJECT)
message(FATAL_ERROR "WEBKIT_PROCESS_ENTITLEMENTS(${_target}): PROJECT is required")
endif ()
if (NOT _arg_PRODUCT_NAME)
set(_arg_PRODUCT_NAME ${_target})
endif ()
set(_xcent ${CMAKE_CURRENT_BINARY_DIR}/${_target}.xcent)
add_custom_command(TARGET ${_target} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E env
WK_PROCESSED_XCENT_FILE=${_xcent}
WK_PLATFORM_NAME=${WEBKIT_SDK_NAME}
PRODUCT_NAME=${_arg_PRODUCT_NAME}
${CMAKE_SOURCE_DIR}/Source/${_arg_PROJECT}/Scripts/process-entitlements.sh
COMMAND codesign --force --sign - --entitlements ${_xcent} $<TARGET_FILE:${_target}>
VERBATIM
)
endfunction()
# ----------------------------------------------------------------------------
# Initialization logic. Sets CMAKE_OSX_SYSROOT if needed, and pins compiler
# tools from the SDK.
# ----------------------------------------------------------------------------
if (CMAKE_OSX_SYSROOT)
WEBKIT_RESOLVE_SDK(${CMAKE_OSX_SYSROOT})
elseif (PORT STREQUAL "Mac" OR PORT STREQUAL "JSCOnly" OR NOT PORT)
# FIXME: Support macosx.internal.
WEBKIT_RESOLVE_SDK(macosx)
elseif (PORT STREQUAL "IOS" AND CMAKE_IOS_SIMULATOR)
WEBKIT_RESOLVE_SDK(iphonesimulator.internal iphonesimulator)
elseif (PORT STREQUAL "IOS" AND NOT CMAKE_IOS_SIMULATOR)
WEBKIT_RESOLVE_SDK(iphoneos.internal iphoneos)
else ()
message(FATAL_ERROR "Building for an Apple platform without an SDK "
"directory (CMAKE_OSX_SYSROOT) or supported PORT variable.")
endif ()
# Cross-compile setup for iOS. CMake doesn't infer CMAKE_SYSTEM_PROCESSOR once
# CMAKE_SYSTEM_NAME is set, so it has to be supplied explicitly. Both must be
# in place before project() runs.
if (PORT STREQUAL "IOS")
set(CMAKE_SYSTEM_NAME iOS)
if (NOT CMAKE_OSX_DEPLOYMENT_TARGET)
string(REGEX MATCH "^[0-9]+\\.[0-9]+" _ios_deployment_target "${_sdk_version}")
set(CMAKE_OSX_DEPLOYMENT_TARGET "${_ios_deployment_target}" CACHE STRING "Minimum iOS version" FORCE)
endif ()
if (NOT CMAKE_SYSTEM_PROCESSOR)
set(CMAKE_SYSTEM_PROCESSOR "aarch64" CACHE STRING "Target processor" FORCE)
endif ()
endif ()
# Subsequent use of `xcrun` or any of the system Xcode and BSD tools will
# use the selected SDK and toolchain.
set(ENV{SDKROOT} ${CMAKE_OSX_SYSROOT})
WEBKIT_RESOLVE_TOOL(CMAKE_C_COMPILER "clang")
WEBKIT_RESOLVE_TOOL(CMAKE_ASM_COMPILER "clang")
WEBKIT_RESOLVE_TOOL(CMAKE_CXX_COMPILER "clang++")
WEBKIT_RESOLVE_TOOL(CMAKE_OBJC_COMPILER "clang")
WEBKIT_RESOLVE_TOOL(CMAKE_OBJCXX_COMPILER "clang++")
WEBKIT_RESOLVE_TOOL(CMAKE_Swift_COMPILER "swiftc")
WEBKIT_RESOLVE_TOOL(CMAKE_INSTALL_NAME_TOOL "install_name_tool")
WEBKIT_RESOLVE_TOOL(CMAKE_LINKER "ld")
# FIXME: Move these to proper find modules, as they are not part of any CMake
# language.
WEBKIT_RESOLVE_TOOL(GPERF_EXECUTABLE "gperf")
WEBKIT_RESOLVE_TOOL(Mig_EXECUTABLE "mig")