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:
Brad King
2025-04-02 09:27:27 -04:00
parent c653c1aa47
commit 2e59cee922
5 changed files with 56 additions and 27 deletions

View File

@@ -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()

View File

@@ -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()