diff --git a/Runtimes/Core/cmake/modules/FindSwiftClientRetainRelease.cmake b/Runtimes/Core/cmake/modules/FindSwiftClientRetainRelease.cmake new file mode 100644 index 0000000000000..feed79b9d8bf9 --- /dev/null +++ b/Runtimes/Core/cmake/modules/FindSwiftClientRetainRelease.cmake @@ -0,0 +1,73 @@ +#[=======================================================================[.rst: +FindSwiftClientRetainRelease +------------ + +Find SwiftClientRetainRelease, deferring to the associated SwiftClientRetainReleaseConfig.cmake when requested. +This is meant to be linked in swiftCore. + +Imported Targets +^^^^^^^^^^^^^^^^ + +The following :prop_tgt:`IMPORTED` TARGETS may be defined: + + ``swiftClientRetainRelease`` + +#]=======================================================================] + +include_guard(GLOBAL) + +if(SwiftClientRetainRelease_DIR) + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) + list(APPEND args REQUIRED) + endif() + if(${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + list(APPEND args QUIET) + endif() + find_package(SwiftClientRetainRelease CONFIG ${args}) + return() +endif() + +include(FindPackageHandleStandardArgs) +include(PlatformInfo) + +if(APPLE) + # ClientRetainRelease is not installed in the SDKs, but in the + # toolchain next to the compiler + set(target_info_command "${CMAKE_Swift_COMPILER}" -print-target-info) + if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND target_info_command -target ${CMAKE_Swift_COMPILER_TARGET}) + endif() + execute_process(COMMAND ${target_info_command} OUTPUT_VARIABLE target_info_json) + message(CONFIGURE_LOG "Swift target info: ${target_info_command}\n" + "${target_info_json}") + + string(JSON runtime_library_import_paths_json GET "${target_info_json}" "paths" "runtimeLibraryImportPaths") + message(CONFIGURE_LOG "runtime_library_import_paths_json ${runtime_library_import_paths_json}") + + string(JSON number_of_runtime_library_import_paths LENGTH "${runtime_library_import_paths_json}") + math(EXPR index_of_last_runtime_library_import_path "${number_of_runtime_library_import_paths} - 1") + foreach(index RANGE 0 ${index_of_last_runtime_library_import_path}) + string(JSON runtime_library_import_path GET "${runtime_library_import_paths_json}" ${index}) + + list(APPEND SwiftClientRetainRelease_LIBRARY_HINTS + "${runtime_library_import_path}") + endforeach() + + list(APPEND swiftClientRetainRelease_NAMES libswiftClientRetainRelease.a) +else() + message(FATAL_ERROR "ClientRetainRelease is only available for Apple platforms at the moment.\n") +endif() + +find_library(swiftClientRetainRelease_LIBRARY + NAMES + ${swiftClientRetainRelease_NAMES} + NO_CMAKE_FIND_ROOT_PATH + HINTS + ${SwiftClientRetainRelease_LIBRARY_HINTS}) + +add_library(swiftClientRetainRelease STATIC IMPORTED GLOBAL) +set_target_properties(swiftClientRetainRelease PROPERTIES + IMPORTED_LOCATION "${swiftClientRetainRelease_LIBRARY}") + +find_package_handle_standard_args(SwiftClientRetainRelease DEFAULT_MSG + swiftClientRetainRelease_LIBRARY) diff --git a/Runtimes/Core/core/CMakeLists.txt b/Runtimes/Core/core/CMakeLists.txt index 023c23fe9e433..d3854dc9e24db 100644 --- a/Runtimes/Core/core/CMakeLists.txt +++ b/Runtimes/Core/core/CMakeLists.txt @@ -373,6 +373,15 @@ if(NOT ANDROID AND NOT APPLE AND NOT LINUX AND NOT WIN32 AND UNIX) target_link_libraries(swiftCore PRIVATE "${EXECINFO_LIBRARY}") endif() +check_compiler_flag(Swift "-Xfrontend -enable-client-retain-release" HAVE_Swift_EMIT_CLIENT_RETAIN_RELEASE_FLAG) +if(HAVE_Swift_EMIT_CLIENT_RETAIN_RELEASE_FLAG) + find_package(SwiftClientRetainRelease) + if(SwiftClientRetainRelease_FOUND) + target_compile_options(swiftCore PRIVATE "$<$:SHELL:-Xfrontend -enable-client-retain-release>") + target_link_libraries(swiftCore PRIVATE swiftClientRetainRelease) + endif() +endif() + if(APPLE AND BUILD_SHARED_LIBS) target_link_options(swiftCore PRIVATE "SHELL:-Xlinker -headerpad_max_install_names") endif()