mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-07 22:30:13 -06:00
FindXCTest: Fix test module generation for Xcode 16
In Xcode 7.3 and above, the `TEST_HOST` setting causes Xcode to
implicitly place the test module inside the executable bundle regardless
of the module's own location settings. Since commit a364d2513a (Xcode:
Fixup XCTest bundle location for Xcode 7.3, 2016-03-25, v3.5.2~6^2) we
explicitly tell CMake to put the test module in the same location so
that generator expressions used by `xctest_add_test` agree with where
Xcode actually puts it. In Xcode 16 and above, our explicit location
settings for the test module conflict with Xcode's `TEST_HOST` rules,
causing errors about multiple commands producing the same path.
Fix this by dropping CMake's explicit location for the test module
unless needed to match a project-specified location for the testee.
Instead, teach `xctest_add_test` to express the xctest module location
selected by `TEST_HOST` by using generator expressions referencing the
testee bundle.
Fixes: #26301
Fixes: #26514
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -158,18 +158,13 @@ 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_options(${target}
|
||||
PRIVATE "SHELL:-bundle_loader \"$<TARGET_FILE:${testee}>\"")
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user