Browse Source

Merge topic 'FindXCTest-xcode-16' into release-4.0

2e59cee922 FindXCTest: Fix test module generation for Xcode 16
c653c1aa47 FindXCTest: Pass -bundle_loader linker flag for test module more reliably

Acked-by: Kitware Robot <[email protected]>
Merge-request: !10573
Brad King 7 months ago
parent
commit
3c08fa2b0d

+ 0 - 7
.gitlab/ci/ctest_exclusions.cmake

@@ -13,13 +13,6 @@ if (CTEST_CMAKE_GENERATOR MATCHES "Visual Studio")
     "^ExternalProjectUpdateSetup$")
 endif ()
 
-if (CTEST_CMAKE_GENERATOR MATCHES "Xcode")
-  list(APPEND test_exclusions
-    # FIXME(#26301): The XCTest fails with Xcode 16.0.
-    "^XCTest$"
-    )
-endif ()
-
 if ("$ENV{CMAKE_CONFIGURATION}" MATCHES "_asan")
   list(APPEND test_exclusions
     CTestTest2 # crashes on purpose

+ 28 - 15
Modules/FindXCTest.cmake

@@ -158,21 +158,16 @@ function(xctest_add_bundle target testee)
       set_target_properties(${target} PROPERTIES
         XCODE_ATTRIBUTE_BUNDLE_LOADER "$(TEST_HOST)"
         XCODE_ATTRIBUTE_TEST_HOST "$<TARGET_FILE:${testee}>")
-      if(XCODE_VERSION VERSION_GREATER_EQUAL 7.3)
-        # The Xcode "new build system" used a different path until Xcode 12.5.
-        if(CMAKE_XCODE_BUILD_SYSTEM EQUAL 12 AND
-           XCODE_VERSION VERSION_LESS 12.5 AND
-           NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-          set(_output_directory "$<TARGET_BUNDLE_CONTENT_DIR:${testee}>")
-        else()
-          set(_output_directory "$<TARGET_BUNDLE_CONTENT_DIR:${testee}>/PlugIns")
-        endif()
-        set_target_properties(${target} PROPERTIES
-          LIBRARY_OUTPUT_DIRECTORY "${_output_directory}")
-      endif()
+      # TEST_HOST overrides ${target}'s artifact path, but the relative
+      # path from TEST_HOST to ${testee}'s PlugIns folder must not leave
+      # ${target}'s TARGET_BUILD_DIR.  If the project sets an explicit
+      # RUNTIME_OUTPUT_DIRECTORY for ${testee}, put ${target} there too.
+      # If not, just suppress the project's CMAKE_LIBRARY_OUTPUT_DIRECTORY.
+      get_property(testee_RUNTIME_OUTPUT_DIRECTORY TARGET ${testee} PROPERTY RUNTIME_OUTPUT_DIRECTORY)
+      set_property(TARGET ${target} PROPERTY LIBRARY_OUTPUT_DIRECTORY ${testee_RUNTIME_OUTPUT_DIRECTORY})
     else()
-      target_link_libraries(${target}
-        PRIVATE -bundle_loader $<TARGET_FILE:${testee}>)
+      target_link_options(${target}
+        PRIVATE "SHELL:-bundle_loader \"$<TARGET_FILE:${testee}>\"")
     endif()
 
   else()
@@ -210,6 +205,24 @@ function(xctest_add_test name bundle)
 
   get_property(_testee_type TARGET ${_testee} PROPERTY TYPE)
   get_property(_testee_framework TARGET ${_testee} PROPERTY FRAMEWORK)
+  get_property(_testee_macosx_bundle TARGET ${_testee} PROPERTY MACOSX_BUNDLE)
+
+  # Determine the path to the test module artifact on disk.
+  set(_test_bundle_dir "$<TARGET_BUNDLE_DIR:${bundle}>")
+  if(XCODE AND _testee_type STREQUAL "EXECUTABLE" AND _testee_macosx_bundle)
+    # Xcode's TEST_HOST setting places the test module inside the testee bundle.
+    if(XCODE_VERSION VERSION_GREATER_EQUAL 7.3)
+      # The Xcode "new build system" used a different path until Xcode 12.5.
+      if(CMAKE_XCODE_BUILD_SYSTEM EQUAL 12 AND
+          XCODE_VERSION VERSION_LESS 12.5 AND
+          NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+        set(_test_bundle_dir "$<TARGET_BUNDLE_CONTENT_DIR:${_testee}>")
+      else()
+        set(_test_bundle_dir "$<TARGET_BUNDLE_CONTENT_DIR:${_testee}>/PlugIns")
+      endif()
+      string(APPEND _test_bundle_dir "/$<TARGET_BUNDLE_DIR_NAME:${bundle}>")
+    endif()
+  endif()
 
   # register test
 
@@ -217,7 +230,7 @@ function(xctest_add_test name bundle)
   # here for CMP0178.
   add_test(
     NAME ${name}
-    COMMAND ${XCTest_EXECUTABLE} $<TARGET_BUNDLE_DIR:${bundle}>)
+    COMMAND ${XCTest_EXECUTABLE} ${_test_bundle_dir})
 
   # point loader to testee in case rpath is disabled
 

+ 1 - 0
Tests/RunCMake/XcodeProject-Device/RunCMakeTest.cmake

@@ -307,6 +307,7 @@ if (XCODE_VERSION VERSION_GREATER_EQUAL 7.3)
     if(BuildSystemVersion)
       set(RunCMake_GENERATOR_TOOLSET "buildsystem=${BuildSystemVersion}")
     endif()
+    set(RunCMake_TEST_VARIANT_DESCRIPTION "-${SystemName}-${SDK}")
     run_cmake(XCTestAddBundle)
   endfunction()
 

+ 14 - 7
Tests/RunCMake/XcodeProject-Device/XCTestAddBundle.cmake

@@ -10,13 +10,20 @@ add_executable(TestedApp MACOSX_BUNDLE dummy_main.swift)
 
 xctest_add_bundle(TestingAppBundle TestedApp dummy_main.swift)
 
-get_target_property(_lib_output_dir TestingAppBundle LIBRARY_OUTPUT_DIRECTORY)
+macro(add_test NAME name COMMAND xctest arg)
+  set(actual_arg "${arg}" PARENT_SCOPE)
+endmacro()
 
-if (NOT DEFINED TEST_EXPECTED_OUTPUT_DIR)
-    message(FATAL_ERROR "Testing variable TEST_EXPECTED_OUTPUT_DIR is not set")
-endif()
+xctest_add_test(TestedApp.TestingAppBundle TestingAppBundle)
 
-if (NOT _lib_output_dir STREQUAL TEST_EXPECTED_OUTPUT_DIR)
-    message(SEND_ERROR "Property LIBRARY_OUTPUT_DIRECTORY is expected to be ${TEST_EXPECTED_OUTPUT_DIR} "
-        "but was ${_lib_output_dir}")
+if(NOT DEFINED TEST_EXPECTED_OUTPUT_DIR)
+  message(FATAL_ERROR "Testing variable TEST_EXPECTED_OUTPUT_DIR is not set")
+endif()
+set(expect_arg "${TEST_EXPECTED_OUTPUT_DIR}/$<TARGET_BUNDLE_DIR_NAME:TestingAppBundle>")
+if(NOT "${actual_arg}" STREQUAL "${expect_arg}")
+  message(FATAL_ERROR "xctest argument expected to be:\n"
+    "  ${expect_arg}\n"
+    "but was:\n"
+    "  ${actual_arg}\n"
+  )
 endif()

+ 15 - 0
Tests/XCTest/CMakeLists.txt

@@ -60,6 +60,21 @@ xctest_add_bundle(CocoaExampleTests CocoaExample
 
 xctest_add_test(XCTest.CocoaExample CocoaExampleTests)
 
+# Cocoa App Bundle with explicit artifact location.
+block()
+  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
+  set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
+  add_executable(CocoaExample2 MACOSX_BUNDLE
+    CocoaExample/main.m
+    CocoaExample/AppDelegate.m
+    CocoaExample/AppDelegate.h
+    CocoaExample/MainMenu.xib
+  )
+  target_link_libraries(CocoaExample2 PRIVATE "-framework Foundation" "-framework AppKit")
+  xctest_add_bundle(CocoaExample2Tests CocoaExample2 CocoaExampleTests/CocoaExampleTests.m)
+  xctest_add_test(XCTest.CocoaExample2 CocoaExample2Tests)
+endblock()
+
 # Static lib
 
 add_library(StaticLibExample STATIC