Browse Source

CMake: Refactor FindSwiftTesting to find TestingMacros dir on macOS

Turns out we need this directory to pass to the -frontend command
for creating the interop header, so refactor the whole find module
to find it on each platform.
Andrew Kaster 2 weeks ago
parent
commit
1ed4e64575
2 changed files with 63 additions and 18 deletions
  1. 53 18
      Meta/CMake/FindSwiftTesting.cmake
  2. 10 0
      Meta/CMake/Swift/swift-settings.cmake

+ 53 - 18
Meta/CMake/FindSwiftTesting.cmake

@@ -1,25 +1,60 @@
 # Finds the swift-testing library
 # On Apple platforms, this is a framework included in the Xcode release
+include_guard()
 
-find_library(SWIFT_TESTING NAMES Testing
-  PATHS ${SWIFT_LIBRARY_SEARCH_PATHS}
-)
-if (SWIFT_TESTING)
-    if (NOT TARGET SwiftTesting::SwiftTesting)
-      add_library(SwiftTesting::SwiftTesting IMPORTED UNKNOWN)
-      message(STATUS "Found SwiftTesting: ${SWIFT_TESTING}")
-      cmake_path(GET SWIFT_TESTING PARENT_PATH _SWIFT_TESTING_DIR)
-      set_target_properties(SwiftTesting::SwiftTesting PROPERTIES
-        IMPORTED_LOCATION "${SWIFT_TESTING}"
-        INTERFACE_LINK_DIRECTORIES "${_SWIFT_TESTING_DIR}"
-      )
-      if (UNIX AND NOT APPLE)
-        cmake_path(GET _SWIFT_TESTING_DIR PARENT_PATH _SWIFT_TESTING_TARGETLESS_DIR)
-        set_target_properties(SwiftTesting::SwiftTesting PROPERTIES
-          INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:Swift>:SHELL:-load-plugin-library ${_SWIFT_TESTING_TARGETLESS_DIR}/host/plugins/libTestingMacros.so>"
-          INTERFACE_LINK_OPTIONS "-load-plugin-library;${_SWIFT_TESTING_TARGETLESS_DIR}/host/plugins/libTestingMacros.so"
-        )
+if (NOT TARGET SwiftTesting::SwiftTesting)
+  cmake_policy(PUSH)
+  if (POLICY CMP0152)
+    cmake_policy(SET CMP0152 NEW)
+  endif()
+
+  set(_SEARCH_PATHS "")
+  set(_PLUGIN_PATHS "")
+  foreach(path IN LISTS SWIFT_LIBRARY_SEARCH_PATHS)
+    file(REAL_PATH ${path} real_path)
+    if (EXISTS ${real_path})
+      list(APPEND _SEARCH_PATHS ${real_path})
+      if (EXISTS "${real_path}/testing")
+        list(APPEND _SEARCH_PATHS "${real_path}/testing")
+      endif()
+    endif()
+    if (EXISTS "${real_path}/../host/plugins")
+      file(REAL_PATH "${real_path}/../host/plugins" plugin_path)
+      list(APPEND _PLUGIN_PATHS ${plugin_path})
+      if (EXISTS "${plugin_path}/testing")
+        list(APPEND _PLUGIN_PATHS "${plugin_path}/testing")
       endif()
     endif()
+  endforeach()
+  list(REMOVE_DUPLICATES _SEARCH_PATHS)
+  list(REMOVE_DUPLICATES _PLUGIN_PATHS)
+
+  find_library(SWIFT_TESTING NAMES Testing
+    PATHS ${_SEARCH_PATHS}
+  )
+  if (SWIFT_TESTING)
+    add_library(SwiftTesting::SwiftTesting IMPORTED UNKNOWN)
+    message(STATUS "Found SwiftTesting: ${SWIFT_TESTING}")
+    cmake_path(GET SWIFT_TESTING PARENT_PATH _SWIFT_TESTING_DIR)
+
+    find_library(SWIFT_TESTING_MACROS NAMES TestingMacros
+      PATHS ${_PLUGIN_PATHS}
+      NO_DEFAULT_PATH
+    )
+    if (NOT SWIFT_TESTING_MACROS)
+      message(FATAL_ERROR "Could not find associated TestingMacros plugin for ${SWIFT_TESTING}")
+    else()
+      message(VERBOSE "Found SwiftTesting macros: ${SWIFT_TESTING_MACROS}")
+    endif()
+
+    set_target_properties(SwiftTesting::SwiftTesting PROPERTIES
+      IMPORTED_LOCATION "${SWIFT_TESTING}"
+      INTERFACE_LINK_DIRECTORIES "${_SWIFT_TESTING_DIR}"
+      INTERFACE_INCLUDE_DIRECTORIES "${_SWIFT_TESTING_DIR}"
+      INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:Swift>:SHELL:-load-plugin-library ${SWIFT_TESTING_MACROS}>"
+      INTERFACE_LINK_OPTIONS "-load-plugin-library;${SWIFT_TESTING_MACROS}"
+    )
     set(SwiftTesting_FOUND TRUE)
+  endif()
+  cmake_policy(POP)
 endif()

+ 10 - 0
Meta/CMake/Swift/swift-settings.cmake

@@ -17,6 +17,8 @@ endif()
 include(${CMAKE_CURRENT_LIST_DIR}/InitializeSwift.cmake)
 include(${CMAKE_CURRENT_LIST_DIR}/GenerateSwiftHeader.cmake)
 
+find_package(SwiftTesting REQUIRED)
+
 # FIXME: https://gitlab.kitware.com/cmake/cmake/-/issues/26174
 if (APPLE)
     set(CMAKE_Swift_COMPILER_TARGET "${SWIFT_TARGET_TRIPLE}")
@@ -60,6 +62,14 @@ function(add_swift_target_properties target_name)
     get_target_property(_NATIVE_DIRS ${target_name} INCLUDE_DIRECTORIES)
     list(APPEND _NATIVE_DIRS ${CMAKE_Swift_MODULE_DIRECTORY})
 
+    # Swift-testing in swift.org toolchains on macOS has its .swiftmodule in a testing/ subdirectory of
+    # the swift compiler's built-in lib dirs.
+    get_target_property(DEPENDENCIES ${target_name} LINK_LIBRARIES)
+    if (SwiftTesting::SwiftTesting IN_LIST DEPENDENCIES)
+        get_target_property(SWIFT_TESTING_INCLUDE_DIRS SwiftTesting::SwiftTesting INTERFACE_INCLUDE_DIRECTORIES)
+        list(APPEND _NATIVE_DIRS ${SWIFT_TESTING_INCLUDE_DIRS})
+    endif()
+
     set(EXTRA_COMPILE_DEFINITIONS "")
     foreach (compile_definition IN LISTS SWIFT_TARGET_COMPILE_DEFINITIONS)
         list(APPEND EXTRA_COMPILE_DEFINITIONS "-Xcc" "-D${compile_definition}")