From 80908ea45ae81b11c7e18f13c59db67a0489ad5b Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Tue, 10 Mar 2026 11:13:17 -0400 Subject: [PATCH 01/15] Reimplement `_TestingInterop` in C++. Normally we try to _reduce_ our C++ content, but the complexity's much lower here since we can't use Swift's atomics properly on Darwin yet and since we don't need to juggle Swift module visibility. --- .../Events/Event+FallbackEventHandler.swift | 2 +- .../include/FallbackEventHandler.h | 52 ++++++++ Sources/_TestingInternals/include/Stubs.h | 37 ------ .../include/module.modulemap | 5 + Sources/_TestingInterop/CMakeLists.txt | 15 ++- .../_TestingInterop/FallbackEventHandler.cpp | 27 +++++ .../FallbackEventHandler.swift | 112 ------------------ .../EventHandlingInteropTests.swift | 2 +- 8 files changed, 98 insertions(+), 154 deletions(-) create mode 100644 Sources/_TestingInternals/include/FallbackEventHandler.h create mode 100644 Sources/_TestingInterop/FallbackEventHandler.cpp delete mode 100644 Sources/_TestingInterop/FallbackEventHandler.swift diff --git a/Sources/Testing/Events/Event+FallbackEventHandler.swift b/Sources/Testing/Events/Event+FallbackEventHandler.swift index effd8385c..78fe242f7 100644 --- a/Sources/Testing/Events/Event+FallbackEventHandler.swift +++ b/Sources/Testing/Events/Event+FallbackEventHandler.swift @@ -8,7 +8,7 @@ // See https://swift.org/CONTRIBUTORS.txt for Swift project authors // -private import _TestingInternals +private import _TestingInternals.InteropOnly extension Event { /// Attempt to handle an event encoded as JSON as if it had been generated in diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h new file mode 100644 index 000000000..7a341a4eb --- /dev/null +++ b/Sources/_TestingInternals/include/FallbackEventHandler.h @@ -0,0 +1,52 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +#if !defined(SWT_NO_INTEROP) +#include "Defines.h" +#include "Includes.h" + +SWT_ASSUME_NONNULL_BEGIN + +/// A type describing a fallback event handler that testing API can invoke as an +/// alternate method of reporting test events to the current test runner. +/// Shadows the type with the same name in _TestingInterop. +/// +/// - Parameters: +/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode +/// the event record. +/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. +/// - recordJSONByteCount: The size of the encoded event in bytes. +/// - reserved: Reserved for future use. +typedef void (* SWTFallbackEventHandler)(const char *recordJSONSchemaVersionNumber, + const void *recordJSONBaseAddress, + size_t recordJSONByteCount, + const void *_Nullable reserved); + +/// Set the current fallback event handler if one has not already been set. +/// +/// - Parameters: +/// - handler: The handler function to set. +/// +/// - Returns: Whether or not `handler` was installed. +/// +/// The fallback event handler can only be installed once per process, typically +/// by the first testing library to run. If this function has already been +/// called and the handler set, it does not replace the previous handler. +SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler handler); + +/// Get the current fallback event handler. +/// Shadows the function with the same name in _TestingInterop. +/// +/// - Returns: The currently-set handler function, if any. +SWT_EXTERN SWTFallbackEventHandler _Nullable _swift_testing_getFallbackEventHandler(void); + +SWT_ASSUME_NONNULL_END + +#endif diff --git a/Sources/_TestingInternals/include/Stubs.h b/Sources/_TestingInternals/include/Stubs.h index ec7e09706..c62d985c9 100644 --- a/Sources/_TestingInternals/include/Stubs.h +++ b/Sources/_TestingInternals/include/Stubs.h @@ -275,43 +275,6 @@ static const char *_Nullable swt_getExitCodeName(int exitCode) { #undef SWT_SYSEXIT_CODE }; -#if !SWT_NO_INTEROP - -/// A type describing a fallback event handler that testing API can invoke as an -/// alternate method of reporting test events to the current test runner. -/// Shadows the type with the same name in _TestingInterop. -/// -/// - Parameters: -/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode -/// the event record. -/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. -/// - recordJSONByteCount: The size of the encoded event in bytes. -/// - reserved: Reserved for future use. -typedef void (* SWTFallbackEventHandler)(const char *recordJSONSchemaVersionNumber, - const void *recordJSONBaseAddress, - size_t recordJSONByteCount, - const void *_Nullable reserved); - -/// Set the current fallback event handler if one has not already been set. -/// -/// - Parameters: -/// - handler: The handler function to set. -/// -/// - Returns: Whether or not `handler` was installed. -/// -/// The fallback event handler can only be installed once per process, typically -/// by the first testing library to run. If this function has already been -/// called and the handler set, it does not replace the previous handler. -SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler handler); - -/// Get the current fallback event handler. -/// Shadows the function with the same name in _TestingInterop. -/// -/// - Returns: The currently-set handler function, if any. -SWT_EXTERN SWTFallbackEventHandler _Nullable _swift_testing_getFallbackEventHandler(void); - -#endif - SWT_ASSUME_NONNULL_END #endif diff --git a/Sources/_TestingInternals/include/module.modulemap b/Sources/_TestingInternals/include/module.modulemap index c820c7bd8..93b2f1b32 100644 --- a/Sources/_TestingInternals/include/module.modulemap +++ b/Sources/_TestingInternals/include/module.modulemap @@ -16,4 +16,9 @@ module _TestingInternals { header "Stubs.h" export * } + + explicit module InteropOnly { + header "FallbackEventHandler.h" + export * + } } diff --git a/Sources/_TestingInterop/CMakeLists.txt b/Sources/_TestingInterop/CMakeLists.txt index 3269e7fcf..891180335 100644 --- a/Sources/_TestingInterop/CMakeLists.txt +++ b/Sources/_TestingInterop/CMakeLists.txt @@ -8,10 +8,19 @@ include(ModuleABIName) add_library(_TestingInterop - FallbackEventHandler.swift) + FallbackEventHandler.cpp) +if("${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC" OR + "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + target_compile_options(_TestingInternals PRIVATE + /EHa-c) +elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + target_compile_options(_TestingInternals PRIVATE + -fno-exceptions -fPIC) +else() + target_compile_options(_TestingInternals PRIVATE + -fno-exceptions) +endif() -target_link_libraries(_TestingInterop PRIVATE - _TestingInternals) if(NOT BUILD_SHARED_LIBS) # When building a static library, tell clients to autolink the internal # libraries. diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp new file mode 100644 index 000000000..2d58f8bb8 --- /dev/null +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -0,0 +1,27 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025–2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +#if !defined(SWT_NO_INTEROP) +#include "../_TestingInternals/include/FallbackEventHandler.h" + +#include + +/// Storage for the fallback event handler. +static std::atomic fallbackEventHandler { nullptr }; + +bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler handler) { + SWTFallbackEventHandler nullptrValue = nullptr + return fallbackEventHandler.compare_exchange_strong(nullptrValue, handler, std::memory_order_seq_cst, std::memory_order_relaxed); +} + +SWTFallbackEventHandler _swift_testing_getFallbackEventHandler(void) { + return fallbackEventHandler.load(std::memory_order_seq_cst); +} +#endif diff --git a/Sources/_TestingInterop/FallbackEventHandler.swift b/Sources/_TestingInterop/FallbackEventHandler.swift deleted file mode 100644 index e83992258..000000000 --- a/Sources/_TestingInterop/FallbackEventHandler.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2025 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for Swift project authors -// - -#if !SWT_NO_INTEROP -#if SWT_TARGET_OS_APPLE && !hasFeature(Embedded) -private import _TestingInternals -#else -private import Synchronization -#endif - -/// `Atomic`-compatible storage for ``FallbackEventHandler``. -private final class _FallbackEventHandlerStorage: Sendable, RawRepresentable { - let rawValue: FallbackEventHandler - - init(rawValue: FallbackEventHandler) { - self.rawValue = rawValue - } -} - -/// The installed event handler. -#if SWT_TARGET_OS_APPLE && !hasFeature(Embedded) -private nonisolated(unsafe) let _fallbackEventHandler = { - let result = UnsafeMutablePointer.allocate(capacity: 1) - result.initialize(to: nil) - return result -}() -#else -private let _fallbackEventHandler = AtomicLazyReference<_FallbackEventHandlerStorage>() -#endif - -/// A type describing a fallback event handler that testing API can invoke as an -/// alternate method of reporting test events to the current test runner. -/// -/// For example, an `XCTAssert` failure in the body of a Swift Testing test -/// cannot record issues directly with the Swift Testing runner. Instead, the -/// framework packages the assertion failure as a JSON `Event` and invokes this -/// handler to report the failure. -/// -/// - Parameters: -/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode -/// the event record. -/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. -/// - recordJSONByteCount: The size of the encoded event in bytes. -/// - reserved: Reserved for future use. -@usableFromInline -package typealias FallbackEventHandler = @Sendable @convention(c) ( - _ recordJSONSchemaVersionNumber: UnsafePointer, - _ recordJSONBaseAddress: UnsafeRawPointer, - _ recordJSONByteCount: Int, - _ reserved: UnsafeRawPointer? -) -> Void - -/// Get the current fallback event handler. -/// -/// - Returns: The currently-set handler function, if any. -@c -@usableFromInline -package func _swift_testing_getFallbackEventHandler() -> FallbackEventHandler? { -#if SWT_TARGET_OS_APPLE && !hasFeature(Embedded) - guard let unmanaged = swt_atomicLoad(_fallbackEventHandler).map(Unmanaged<_FallbackEventHandlerStorage>.fromOpaque) else { - return nil - } - return unmanaged.takeUnretainedValue().rawValue -#else - // If we had a setter, this load would present a race condition because - // another thread could store a new value in between the load and the call to - // `takeUnretainedValue()`, resulting in a use-after-free on this thread. We - // would need a full lock in order to avoid that problem. However, because we - // instead have a one-time installation function, we can be sure that the - // loaded value (if non-nil) will never be replaced with another value. - return _fallbackEventHandler.load()?.rawValue -#endif -} - -/// Set the current fallback event handler if one has not already been set. -/// -/// - Parameters: -/// - handler: The handler function to set. -/// -/// - Returns: Whether or not `handler` was installed. -/// -/// The fallback event handler can only be installed once per process, typically -/// by the first testing library to run. If this function has already been -/// called and the handler set, it does not replace the previous handler. -@c -@usableFromInline -package func _swift_testing_installFallbackEventHandler(_ handler: FallbackEventHandler) -> CBool { - var result = false - - let handler = _FallbackEventHandlerStorage(rawValue: handler) -#if SWT_TARGET_OS_APPLE && !hasFeature(Embedded) - let unmanaged = Unmanaged.passRetained(handler) - var expectedNil: UnsafeRawPointer? - result = swt_atomicCompareExchange(_fallbackEventHandler, &expectedNil, unmanaged.toOpaque()) - if !result { - unmanaged.release() - } -#else - let stored = _fallbackEventHandler.storeIfNil(handler) - result = (handler === stored) -#endif - - return result -} -#endif diff --git a/Tests/TestingTests/EventHandlingInteropTests.swift b/Tests/TestingTests/EventHandlingInteropTests.swift index 3b69eb6f5..67ff25143 100644 --- a/Tests/TestingTests/EventHandlingInteropTests.swift +++ b/Tests/TestingTests/EventHandlingInteropTests.swift @@ -9,7 +9,7 @@ // @testable @_spi(ForToolsIntegrationOnly) import Testing -private import _TestingInternals +private import _TestingInternals.InteropOnly #if canImport(Foundation) import Foundation From 3c78ef1055a4403b82503beda4b96c5320b531b7 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Tue, 10 Mar 2026 11:19:05 -0400 Subject: [PATCH 02/15] Fix typo sigh --- Sources/_TestingInterop/FallbackEventHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp index 2d58f8bb8..325933f06 100644 --- a/Sources/_TestingInterop/FallbackEventHandler.cpp +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -17,7 +17,7 @@ static std::atomic fallbackEventHandler { nullptr }; bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler handler) { - SWTFallbackEventHandler nullptrValue = nullptr + SWTFallbackEventHandler nullptrValue = nullptr; return fallbackEventHandler.compare_exchange_strong(nullptrValue, handler, std::memory_order_seq_cst, std::memory_order_relaxed); } From 7149e06c3ee9cf3cd541ef2fbb00c2c2f4d6ea3a Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Tue, 10 Mar 2026 14:01:56 -0400 Subject: [PATCH 03/15] Intentionally empty header file so git includes the empty includes directory --- Sources/_TestingInterop/include/Empty.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 Sources/_TestingInterop/include/Empty.h diff --git a/Sources/_TestingInterop/include/Empty.h b/Sources/_TestingInterop/include/Empty.h new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Sources/_TestingInterop/include/Empty.h @@ -0,0 +1 @@ + From 16680d7207fc58fbde4dfe25e0411ac48d03e005 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:10:55 -0400 Subject: [PATCH 04/15] Fixup headers a bit --- .../include/FallbackEventHandler.h | 4 ++++ Sources/_TestingInterop/include/Empty.h | 1 - Sources/_TestingInterop/include/Interop.h | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) delete mode 100644 Sources/_TestingInterop/include/Empty.h create mode 100644 Sources/_TestingInterop/include/Interop.h diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h index 7a341a4eb..c9f0e929f 100644 --- a/Sources/_TestingInternals/include/FallbackEventHandler.h +++ b/Sources/_TestingInternals/include/FallbackEventHandler.h @@ -8,6 +8,9 @@ // See https://swift.org/CONTRIBUTORS.txt for Swift project authors // +#if !defined(SWT_FALLBACK_EVENT_HANDLER_H) +#define SWT_FALLBACK_EVENT_HANDLER_H + #if !defined(SWT_NO_INTEROP) #include "Defines.h" #include "Includes.h" @@ -50,3 +53,4 @@ SWT_EXTERN SWTFallbackEventHandler _Nullable _swift_testing_getFallbackEventHand SWT_ASSUME_NONNULL_END #endif +#endif diff --git a/Sources/_TestingInterop/include/Empty.h b/Sources/_TestingInterop/include/Empty.h deleted file mode 100644 index 8b1378917..000000000 --- a/Sources/_TestingInterop/include/Empty.h +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Sources/_TestingInterop/include/Interop.h b/Sources/_TestingInterop/include/Interop.h new file mode 100644 index 000000000..93ad2c33c --- /dev/null +++ b/Sources/_TestingInterop/include/Interop.h @@ -0,0 +1,19 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +#if !defined(SWT_TESTING_INTEROP_H) +#define SWT_TESTING_INTEROP_H + +/// - Note: Because we do not build the `_TestingInterop` library as part of a +/// package build, this header has no content. The module's symbol(s) are +/// instead declared in headers in the `_TestingInternals` target and can be +/// imported into Swift using the `_TestingInternals.InteropOnly` submodule. + +#endif From 85b841a49d2d314f8a41d20bd723992b7619aeac Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:12:32 -0400 Subject: [PATCH 05/15] sendability annotations --- .../include/FallbackEventHandler.h | 15 ++++++++------- Sources/_TestingInterop/FallbackEventHandler.cpp | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h index c9f0e929f..f54f5f63c 100644 --- a/Sources/_TestingInternals/include/FallbackEventHandler.h +++ b/Sources/_TestingInternals/include/FallbackEventHandler.h @@ -19,7 +19,6 @@ SWT_ASSUME_NONNULL_BEGIN /// A type describing a fallback event handler that testing API can invoke as an /// alternate method of reporting test events to the current test runner. -/// Shadows the type with the same name in _TestingInterop. /// /// - Parameters: /// - recordJSONSchemaVersionNumber: The JSON schema version used to encode @@ -27,10 +26,12 @@ SWT_ASSUME_NONNULL_BEGIN /// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. /// - recordJSONByteCount: The size of the encoded event in bytes. /// - reserved: Reserved for future use. -typedef void (* SWTFallbackEventHandler)(const char *recordJSONSchemaVersionNumber, - const void *recordJSONBaseAddress, - size_t recordJSONByteCount, - const void *_Nullable reserved); +typedef void (* SWT_SENDABLE SWTFallbackEventHandler)( + const char *recordJSONSchemaVersionNumber, + const void *recordJSONBaseAddress, + size_t recordJSONByteCount, + const void *_Nullable reserved +); /// Set the current fallback event handler if one has not already been set. /// @@ -42,13 +43,13 @@ typedef void (* SWTFallbackEventHandler)(const char *recordJSONSchemaVersionNumb /// The fallback event handler can only be installed once per process, typically /// by the first testing library to run. If this function has already been /// called and the handler set, it does not replace the previous handler. -SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler handler); +SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler SWT_SENDABLE handler); /// Get the current fallback event handler. /// Shadows the function with the same name in _TestingInterop. /// /// - Returns: The currently-set handler function, if any. -SWT_EXTERN SWTFallbackEventHandler _Nullable _swift_testing_getFallbackEventHandler(void); +SWT_EXTERN SWTFallbackEventHandler SWT_SENDABLE _Nullable _swift_testing_getFallbackEventHandler(void); SWT_ASSUME_NONNULL_END diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp index 325933f06..9718e1d85 100644 --- a/Sources/_TestingInterop/FallbackEventHandler.cpp +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -16,12 +16,12 @@ /// Storage for the fallback event handler. static std::atomic fallbackEventHandler { nullptr }; -bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler handler) { +bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler SWT_SENDABLE handler) { SWTFallbackEventHandler nullptrValue = nullptr; return fallbackEventHandler.compare_exchange_strong(nullptrValue, handler, std::memory_order_seq_cst, std::memory_order_relaxed); } -SWTFallbackEventHandler _swift_testing_getFallbackEventHandler(void) { +SWTFallbackEventHandler SWT_SENDABLE _swift_testing_getFallbackEventHandler(void) { return fallbackEventHandler.load(std::memory_order_seq_cst); } #endif From 6ea9d5736d649212b678f7a36d999ce20da580b1 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:15:14 -0400 Subject: [PATCH 06/15] Fix CMake module name --- Sources/_TestingInterop/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/_TestingInterop/CMakeLists.txt b/Sources/_TestingInterop/CMakeLists.txt index 891180335..87cfddf17 100644 --- a/Sources/_TestingInterop/CMakeLists.txt +++ b/Sources/_TestingInterop/CMakeLists.txt @@ -11,13 +11,13 @@ add_library(_TestingInterop FallbackEventHandler.cpp) if("${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - target_compile_options(_TestingInternals PRIVATE + target_compile_options(_TestingInterop PRIVATE /EHa-c) elseif(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - target_compile_options(_TestingInternals PRIVATE + target_compile_options(_TestingInterop PRIVATE -fno-exceptions -fPIC) else() - target_compile_options(_TestingInternals PRIVATE + target_compile_options(_TestingInterop PRIVATE -fno-exceptions) endif() @@ -25,7 +25,7 @@ if(NOT BUILD_SHARED_LIBS) # When building a static library, tell clients to autolink the internal # libraries. target_compile_options(_TestingInterop PRIVATE - "SHELL:-Xfrontend -public-autolink-library -Xfrontend _TestingInternals") + "SHELL:-Xfrontend -public-autolink-library -Xfrontend _TestingInterop") endif() target_compile_options(_TestingInterop PRIVATE -enable-library-evolution From feae9209b7457c9a16c81937729ec3bab87110d7 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:20:26 -0400 Subject: [PATCH 07/15] Import module explicitly --- Sources/_TestingInterop/FallbackEventHandler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp index 9718e1d85..314fcb3a8 100644 --- a/Sources/_TestingInterop/FallbackEventHandler.cpp +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -9,7 +9,9 @@ // #if !defined(SWT_NO_INTEROP) -#include "../_TestingInternals/include/FallbackEventHandler.h" +#if !defined(__APPLE__) +#pragma clang module import _TestingInternals.InteropOnly +#endif #include From 06904d7b1b0f233df7c83cc4a57a1891758d7615 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:25:15 -0400 Subject: [PATCH 08/15] Revert "Import module explicitly" This reverts commit feae9209b7457c9a16c81937729ec3bab87110d7. --- Sources/_TestingInterop/FallbackEventHandler.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp index 314fcb3a8..9718e1d85 100644 --- a/Sources/_TestingInterop/FallbackEventHandler.cpp +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -9,9 +9,7 @@ // #if !defined(SWT_NO_INTEROP) -#if !defined(__APPLE__) -#pragma clang module import _TestingInternals.InteropOnly -#endif +#include "../_TestingInternals/include/FallbackEventHandler.h" #include From 1da1682f0a1794a557254798209b48726f9d1412 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:30:59 -0400 Subject: [PATCH 09/15] Move header to interop target, symlink it from internals --- .../include/FallbackEventHandler.h | 58 +---------------- .../_TestingInterop/FallbackEventHandler.cpp | 2 +- .../include/FallbackEventHandler.h | 63 +++++++++++++++++++ Sources/_TestingInterop/include/Interop.h | 19 ------ 4 files changed, 65 insertions(+), 77 deletions(-) mode change 100644 => 120000 Sources/_TestingInternals/include/FallbackEventHandler.h create mode 100644 Sources/_TestingInterop/include/FallbackEventHandler.h delete mode 100644 Sources/_TestingInterop/include/Interop.h diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h deleted file mode 100644 index f54f5f63c..000000000 --- a/Sources/_TestingInternals/include/FallbackEventHandler.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for Swift project authors -// - -#if !defined(SWT_FALLBACK_EVENT_HANDLER_H) -#define SWT_FALLBACK_EVENT_HANDLER_H - -#if !defined(SWT_NO_INTEROP) -#include "Defines.h" -#include "Includes.h" - -SWT_ASSUME_NONNULL_BEGIN - -/// A type describing a fallback event handler that testing API can invoke as an -/// alternate method of reporting test events to the current test runner. -/// -/// - Parameters: -/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode -/// the event record. -/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. -/// - recordJSONByteCount: The size of the encoded event in bytes. -/// - reserved: Reserved for future use. -typedef void (* SWT_SENDABLE SWTFallbackEventHandler)( - const char *recordJSONSchemaVersionNumber, - const void *recordJSONBaseAddress, - size_t recordJSONByteCount, - const void *_Nullable reserved -); - -/// Set the current fallback event handler if one has not already been set. -/// -/// - Parameters: -/// - handler: The handler function to set. -/// -/// - Returns: Whether or not `handler` was installed. -/// -/// The fallback event handler can only be installed once per process, typically -/// by the first testing library to run. If this function has already been -/// called and the handler set, it does not replace the previous handler. -SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler SWT_SENDABLE handler); - -/// Get the current fallback event handler. -/// Shadows the function with the same name in _TestingInterop. -/// -/// - Returns: The currently-set handler function, if any. -SWT_EXTERN SWTFallbackEventHandler SWT_SENDABLE _Nullable _swift_testing_getFallbackEventHandler(void); - -SWT_ASSUME_NONNULL_END - -#endif -#endif diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h new file mode 120000 index 000000000..8f154ea5a --- /dev/null +++ b/Sources/_TestingInternals/include/FallbackEventHandler.h @@ -0,0 +1 @@ +../../_TestingInterop/include/FallbackEventHandler.h \ No newline at end of file diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp index 9718e1d85..971e79e9e 100644 --- a/Sources/_TestingInterop/FallbackEventHandler.cpp +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -9,7 +9,7 @@ // #if !defined(SWT_NO_INTEROP) -#include "../_TestingInternals/include/FallbackEventHandler.h" +#include "FallbackEventHandler.h" #include diff --git a/Sources/_TestingInterop/include/FallbackEventHandler.h b/Sources/_TestingInterop/include/FallbackEventHandler.h new file mode 100644 index 000000000..f5785ceb0 --- /dev/null +++ b/Sources/_TestingInterop/include/FallbackEventHandler.h @@ -0,0 +1,63 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +#if !defined(SWT_FALLBACK_EVENT_HANDLER_H) +#define SWT_FALLBACK_EVENT_HANDLER_H + +/// - Note: Because we do not build the `_TestingInterop` library as part of a +/// package build, this header is inaccessible during said build. To solve +/// that problem, we create a symlink to it in the `_TestingInternals` target +/// directory. The symbols in this header can then be accessed from Swift by +/// importing the `_TestingInternals.InteropOnly` submodule. + +#if !defined(SWT_NO_INTEROP) +#include "Defines.h" +#include "Includes.h" + +SWT_ASSUME_NONNULL_BEGIN + +/// A type describing a fallback event handler that testing API can invoke as an +/// alternate method of reporting test events to the current test runner. +/// +/// - Parameters: +/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode +/// the event record. +/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. +/// - recordJSONByteCount: The size of the encoded event in bytes. +/// - reserved: Reserved for future use. +typedef void (* SWT_SENDABLE SWTFallbackEventHandler)( + const char *recordJSONSchemaVersionNumber, + const void *recordJSONBaseAddress, + size_t recordJSONByteCount, + const void *_Nullable reserved +); + +/// Set the current fallback event handler if one has not already been set. +/// +/// - Parameters: +/// - handler: The handler function to set. +/// +/// - Returns: Whether or not `handler` was installed. +/// +/// The fallback event handler can only be installed once per process, typically +/// by the first testing library to run. If this function has already been +/// called and the handler set, it does not replace the previous handler. +SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler SWT_SENDABLE handler); + +/// Get the current fallback event handler. +/// Shadows the function with the same name in _TestingInterop. +/// +/// - Returns: The currently-set handler function, if any. +SWT_EXTERN SWTFallbackEventHandler SWT_SENDABLE _Nullable _swift_testing_getFallbackEventHandler(void); + +SWT_ASSUME_NONNULL_END + +#endif +#endif diff --git a/Sources/_TestingInterop/include/Interop.h b/Sources/_TestingInterop/include/Interop.h deleted file mode 100644 index 93ad2c33c..000000000 --- a/Sources/_TestingInterop/include/Interop.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for Swift project authors -// - -#if !defined(SWT_TESTING_INTEROP_H) -#define SWT_TESTING_INTEROP_H - -/// - Note: Because we do not build the `_TestingInterop` library as part of a -/// package build, this header has no content. The module's symbol(s) are -/// instead declared in headers in the `_TestingInternals` target and can be -/// imported into Swift using the `_TestingInternals.InteropOnly` submodule. - -#endif From 6b29b65d8a46b64738aec0efc45eb3c8671b7226 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:33:31 -0400 Subject: [PATCH 10/15] Revert "Move header to interop target, symlink it from internals" This reverts commit 1da1682f0a1794a557254798209b48726f9d1412. --- .../include/FallbackEventHandler.h | 58 ++++++++++++++++- .../_TestingInterop/FallbackEventHandler.cpp | 2 +- .../include/FallbackEventHandler.h | 63 ------------------- Sources/_TestingInterop/include/Interop.h | 19 ++++++ 4 files changed, 77 insertions(+), 65 deletions(-) mode change 120000 => 100644 Sources/_TestingInternals/include/FallbackEventHandler.h delete mode 100644 Sources/_TestingInterop/include/FallbackEventHandler.h create mode 100644 Sources/_TestingInterop/include/Interop.h diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h deleted file mode 120000 index 8f154ea5a..000000000 --- a/Sources/_TestingInternals/include/FallbackEventHandler.h +++ /dev/null @@ -1 +0,0 @@ -../../_TestingInterop/include/FallbackEventHandler.h \ No newline at end of file diff --git a/Sources/_TestingInternals/include/FallbackEventHandler.h b/Sources/_TestingInternals/include/FallbackEventHandler.h new file mode 100644 index 000000000..f54f5f63c --- /dev/null +++ b/Sources/_TestingInternals/include/FallbackEventHandler.h @@ -0,0 +1,57 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +#if !defined(SWT_FALLBACK_EVENT_HANDLER_H) +#define SWT_FALLBACK_EVENT_HANDLER_H + +#if !defined(SWT_NO_INTEROP) +#include "Defines.h" +#include "Includes.h" + +SWT_ASSUME_NONNULL_BEGIN + +/// A type describing a fallback event handler that testing API can invoke as an +/// alternate method of reporting test events to the current test runner. +/// +/// - Parameters: +/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode +/// the event record. +/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. +/// - recordJSONByteCount: The size of the encoded event in bytes. +/// - reserved: Reserved for future use. +typedef void (* SWT_SENDABLE SWTFallbackEventHandler)( + const char *recordJSONSchemaVersionNumber, + const void *recordJSONBaseAddress, + size_t recordJSONByteCount, + const void *_Nullable reserved +); + +/// Set the current fallback event handler if one has not already been set. +/// +/// - Parameters: +/// - handler: The handler function to set. +/// +/// - Returns: Whether or not `handler` was installed. +/// +/// The fallback event handler can only be installed once per process, typically +/// by the first testing library to run. If this function has already been +/// called and the handler set, it does not replace the previous handler. +SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler SWT_SENDABLE handler); + +/// Get the current fallback event handler. +/// Shadows the function with the same name in _TestingInterop. +/// +/// - Returns: The currently-set handler function, if any. +SWT_EXTERN SWTFallbackEventHandler SWT_SENDABLE _Nullable _swift_testing_getFallbackEventHandler(void); + +SWT_ASSUME_NONNULL_END + +#endif +#endif diff --git a/Sources/_TestingInterop/FallbackEventHandler.cpp b/Sources/_TestingInterop/FallbackEventHandler.cpp index 971e79e9e..9718e1d85 100644 --- a/Sources/_TestingInterop/FallbackEventHandler.cpp +++ b/Sources/_TestingInterop/FallbackEventHandler.cpp @@ -9,7 +9,7 @@ // #if !defined(SWT_NO_INTEROP) -#include "FallbackEventHandler.h" +#include "../_TestingInternals/include/FallbackEventHandler.h" #include diff --git a/Sources/_TestingInterop/include/FallbackEventHandler.h b/Sources/_TestingInterop/include/FallbackEventHandler.h deleted file mode 100644 index f5785ceb0..000000000 --- a/Sources/_TestingInterop/include/FallbackEventHandler.h +++ /dev/null @@ -1,63 +0,0 @@ -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2026 Apple Inc. and the Swift project authors -// Licensed under Apache License v2.0 with Runtime Library Exception -// -// See https://swift.org/LICENSE.txt for license information -// See https://swift.org/CONTRIBUTORS.txt for Swift project authors -// - -#if !defined(SWT_FALLBACK_EVENT_HANDLER_H) -#define SWT_FALLBACK_EVENT_HANDLER_H - -/// - Note: Because we do not build the `_TestingInterop` library as part of a -/// package build, this header is inaccessible during said build. To solve -/// that problem, we create a symlink to it in the `_TestingInternals` target -/// directory. The symbols in this header can then be accessed from Swift by -/// importing the `_TestingInternals.InteropOnly` submodule. - -#if !defined(SWT_NO_INTEROP) -#include "Defines.h" -#include "Includes.h" - -SWT_ASSUME_NONNULL_BEGIN - -/// A type describing a fallback event handler that testing API can invoke as an -/// alternate method of reporting test events to the current test runner. -/// -/// - Parameters: -/// - recordJSONSchemaVersionNumber: The JSON schema version used to encode -/// the event record. -/// - recordJSONBaseAddress: A pointer to the first byte of the encoded event. -/// - recordJSONByteCount: The size of the encoded event in bytes. -/// - reserved: Reserved for future use. -typedef void (* SWT_SENDABLE SWTFallbackEventHandler)( - const char *recordJSONSchemaVersionNumber, - const void *recordJSONBaseAddress, - size_t recordJSONByteCount, - const void *_Nullable reserved -); - -/// Set the current fallback event handler if one has not already been set. -/// -/// - Parameters: -/// - handler: The handler function to set. -/// -/// - Returns: Whether or not `handler` was installed. -/// -/// The fallback event handler can only be installed once per process, typically -/// by the first testing library to run. If this function has already been -/// called and the handler set, it does not replace the previous handler. -SWT_EXTERN bool _swift_testing_installFallbackEventHandler(SWTFallbackEventHandler SWT_SENDABLE handler); - -/// Get the current fallback event handler. -/// Shadows the function with the same name in _TestingInterop. -/// -/// - Returns: The currently-set handler function, if any. -SWT_EXTERN SWTFallbackEventHandler SWT_SENDABLE _Nullable _swift_testing_getFallbackEventHandler(void); - -SWT_ASSUME_NONNULL_END - -#endif -#endif diff --git a/Sources/_TestingInterop/include/Interop.h b/Sources/_TestingInterop/include/Interop.h new file mode 100644 index 000000000..93ad2c33c --- /dev/null +++ b/Sources/_TestingInterop/include/Interop.h @@ -0,0 +1,19 @@ +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for Swift project authors +// + +#if !defined(SWT_TESTING_INTEROP_H) +#define SWT_TESTING_INTEROP_H + +/// - Note: Because we do not build the `_TestingInterop` library as part of a +/// package build, this header has no content. The module's symbol(s) are +/// instead declared in headers in the `_TestingInternals` target and can be +/// imported into Swift using the `_TestingInternals.InteropOnly` submodule. + +#endif From 8d8015e078ea9cd272b43b30bf0210437090c8fd Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:39:33 -0400 Subject: [PATCH 11/15] Try explicitly exporting the C++ module by name? --- Sources/_TestingInternals/include/Defines.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/_TestingInternals/include/Defines.h b/Sources/_TestingInternals/include/Defines.h index fa200ff62..493823195 100644 --- a/Sources/_TestingInternals/include/Defines.h +++ b/Sources/_TestingInternals/include/Defines.h @@ -11,6 +11,10 @@ #if !defined(SWT_DEFINES_H) #define SWT_DEFINES_H +#if __has_feature(modules) +export module _TestingInternals; +#endif + #define SWT_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #define SWT_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") From 74ab29ff786fce4e763f8e0d2d008a9a66422da0 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 10:58:51 -0400 Subject: [PATCH 12/15] Try explicitly disabling C++ modules? --- Package.swift | 6 +++++- Sources/_TestingInternals/include/Defines.h | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index 67c0614cd..e3415ade8 100644 --- a/Package.swift +++ b/Package.swift @@ -222,7 +222,11 @@ let package = Package( dependencies: ["_TestingInternals",], path: "Sources/_TestingInterop", exclude: ["CMakeLists.txt"], - cxxSettings: .packageSettings(), + cxxSettings: .packageSettings() + [ + .unsafeFlags([ + "-fno-cxx-modules", + ]), + ], swiftSettings: .packageSettings() + .moduleABIName("_TestingInterop") ), diff --git a/Sources/_TestingInternals/include/Defines.h b/Sources/_TestingInternals/include/Defines.h index 493823195..fa200ff62 100644 --- a/Sources/_TestingInternals/include/Defines.h +++ b/Sources/_TestingInternals/include/Defines.h @@ -11,10 +11,6 @@ #if !defined(SWT_DEFINES_H) #define SWT_DEFINES_H -#if __has_feature(modules) -export module _TestingInternals; -#endif - #define SWT_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") #define SWT_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") From 59ae16726d930d91073609f12527ee530299c486 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 13:22:23 -0400 Subject: [PATCH 13/15] Update CMake --- Sources/_TestingInternals/CMakeLists.txt | 5 ----- Sources/_TestingInterop/CMakeLists.txt | 5 ++--- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Sources/_TestingInternals/CMakeLists.txt b/Sources/_TestingInternals/CMakeLists.txt index e1ca291e2..b2bc5b6b1 100644 --- a/Sources/_TestingInternals/CMakeLists.txt +++ b/Sources/_TestingInternals/CMakeLists.txt @@ -35,9 +35,4 @@ if(NOT BUILD_SHARED_LIBS) # is linked into the main library and does not need to be installed separately. install(TARGETS _TestingInternals ARCHIVE DESTINATION "${SwiftTesting_INSTALL_LIBDIR}") - - # We don't necessarily want to export _TestingInternals, but it is unavoidable - # when building statically since _TestingInterop depends on it - # https://gitlab.kitware.com/cmake/cmake/-/issues/20041 - set_property(GLOBAL APPEND PROPERTY SwiftTesting_EXPORTS _TestingInternals) endif() diff --git a/Sources/_TestingInterop/CMakeLists.txt b/Sources/_TestingInterop/CMakeLists.txt index 87cfddf17..70392fe25 100644 --- a/Sources/_TestingInterop/CMakeLists.txt +++ b/Sources/_TestingInterop/CMakeLists.txt @@ -9,6 +9,8 @@ include(ModuleABIName) add_library(_TestingInterop FallbackEventHandler.cpp) +target_include_directories(_TestingInterop PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) if("${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "MSVC" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") target_compile_options(_TestingInterop PRIVATE @@ -27,9 +29,6 @@ if(NOT BUILD_SHARED_LIBS) target_compile_options(_TestingInterop PRIVATE "SHELL:-Xfrontend -public-autolink-library -Xfrontend _TestingInterop") endif() -target_compile_options(_TestingInterop PRIVATE - -enable-library-evolution - -emit-module-interface -emit-module-interface-path $/_TestingInterop.swiftinterface) _swift_testing_install_target(_TestingInterop) From f9d450ba6685ae7bc90368e8c3336952ffdb25a1 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Mon, 20 Apr 2026 15:21:17 -0400 Subject: [PATCH 14/15] Break up _swift_testing_install_target() --- Sources/Overlays/_Testing_AppKit/CMakeLists.txt | 1 + .../Overlays/_Testing_CoreGraphics/CMakeLists.txt | 1 + .../Overlays/_Testing_CoreImage/CMakeLists.txt | 1 + .../Overlays/_Testing_Foundation/CMakeLists.txt | 1 + Sources/Overlays/_Testing_UIKit/CMakeLists.txt | 1 + Sources/Overlays/_Testing_WinSDK/CMakeLists.txt | 1 + Sources/Testing/CMakeLists.txt | 1 + Sources/_TestDiscovery/CMakeLists.txt | 1 + cmake/modules/SwiftModuleInstallation.cmake | 15 +++++++++++++++ 9 files changed, 23 insertions(+) diff --git a/Sources/Overlays/_Testing_AppKit/CMakeLists.txt b/Sources/Overlays/_Testing_AppKit/CMakeLists.txt index 7f2425340..41c722b92 100644 --- a/Sources/Overlays/_Testing_AppKit/CMakeLists.txt +++ b/Sources/Overlays/_Testing_AppKit/CMakeLists.txt @@ -21,4 +21,5 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") -emit-module-interface -emit-module-interface-path $/_Testing_AppKit.swiftinterface) _swift_testing_install_target(_Testing_AppKit) + _swift_testing_install_swiftmodule(_Testing_AppKit) endif() diff --git a/Sources/Overlays/_Testing_CoreGraphics/CMakeLists.txt b/Sources/Overlays/_Testing_CoreGraphics/CMakeLists.txt index bb57c5574..aaa376248 100644 --- a/Sources/Overlays/_Testing_CoreGraphics/CMakeLists.txt +++ b/Sources/Overlays/_Testing_CoreGraphics/CMakeLists.txt @@ -23,4 +23,5 @@ if(APPLE) -emit-module-interface -emit-module-interface-path $/_Testing_CoreGraphics.swiftinterface) _swift_testing_install_target(_Testing_CoreGraphics) + _swift_testing_install_swiftmodule(_Testing_CoreGraphics) endif() diff --git a/Sources/Overlays/_Testing_CoreImage/CMakeLists.txt b/Sources/Overlays/_Testing_CoreImage/CMakeLists.txt index 326f13b91..73358c46c 100644 --- a/Sources/Overlays/_Testing_CoreImage/CMakeLists.txt +++ b/Sources/Overlays/_Testing_CoreImage/CMakeLists.txt @@ -21,4 +21,5 @@ if(APPLE) -emit-module-interface -emit-module-interface-path $/_Testing_CoreImage.swiftinterface) _swift_testing_install_target(_Testing_CoreImage) + _swift_testing_install_swiftmodule(_Testing_CoreImage) endif() diff --git a/Sources/Overlays/_Testing_Foundation/CMakeLists.txt b/Sources/Overlays/_Testing_Foundation/CMakeLists.txt index d5922df06..33f6fa093 100644 --- a/Sources/Overlays/_Testing_Foundation/CMakeLists.txt +++ b/Sources/Overlays/_Testing_Foundation/CMakeLists.txt @@ -41,3 +41,4 @@ target_compile_options(_Testing_Foundation PRIVATE -emit-module-interface -emit-module-interface-path $/_Testing_Foundation.swiftinterface) _swift_testing_install_target(_Testing_Foundation) +_swift_testing_install_swiftmodule(_Testing_Foundation) diff --git a/Sources/Overlays/_Testing_UIKit/CMakeLists.txt b/Sources/Overlays/_Testing_UIKit/CMakeLists.txt index e54ef95db..c4f8224a6 100644 --- a/Sources/Overlays/_Testing_UIKit/CMakeLists.txt +++ b/Sources/Overlays/_Testing_UIKit/CMakeLists.txt @@ -21,4 +21,5 @@ if(APPLE) -emit-module-interface -emit-module-interface-path $/_Testing_UIKit.swiftinterface) _swift_testing_install_target(_Testing_UIKit) + _swift_testing_install_swiftmodule(_Testing_UIKit) endif() diff --git a/Sources/Overlays/_Testing_WinSDK/CMakeLists.txt b/Sources/Overlays/_Testing_WinSDK/CMakeLists.txt index e73e818bc..de6b410f7 100644 --- a/Sources/Overlays/_Testing_WinSDK/CMakeLists.txt +++ b/Sources/Overlays/_Testing_WinSDK/CMakeLists.txt @@ -28,4 +28,5 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") -emit-module-interface -emit-module-interface-path $/_Testing_WinSDK.swiftinterface) _swift_testing_install_target(_Testing_WinSDK) + _swift_testing_install_swiftmodule(_Testing_WinSDK) endif() diff --git a/Sources/Testing/CMakeLists.txt b/Sources/Testing/CMakeLists.txt index f10fc18fb..76f841fe0 100644 --- a/Sources/Testing/CMakeLists.txt +++ b/Sources/Testing/CMakeLists.txt @@ -161,6 +161,7 @@ target_compile_options(Testing PRIVATE -emit-module-interface -emit-module-interface-path $/Testing.swiftinterface) _swift_testing_install_target(Testing) +_swift_testing_install_swiftmodule(Testing) # Install the Swift cross-import overlay directory. _swift_testing_install_swiftcrossimport(Testing diff --git a/Sources/_TestDiscovery/CMakeLists.txt b/Sources/_TestDiscovery/CMakeLists.txt index efa20223b..f88595f28 100644 --- a/Sources/_TestDiscovery/CMakeLists.txt +++ b/Sources/_TestDiscovery/CMakeLists.txt @@ -23,6 +23,7 @@ target_compile_options(_TestDiscovery PRIVATE set(CMAKE_STATIC_LIBRARY_PREFIX_Swift "lib") _swift_testing_install_target(_TestDiscovery) +_swift_testing_install_swiftmodule(_TestDiscovery) if(NOT BUILD_SHARED_LIBS) # When building a static library, install the internal library archive diff --git a/cmake/modules/SwiftModuleInstallation.cmake b/cmake/modules/SwiftModuleInstallation.cmake index 6947bb1cd..23ad9af68 100644 --- a/cmake/modules/SwiftModuleInstallation.cmake +++ b/cmake/modules/SwiftModuleInstallation.cmake @@ -8,12 +8,27 @@ ## See https://swift.org/CONTRIBUTORS.txt for Swift project authors ## +# Install the specified module's platform build products (executables, +# libraries, etc.) +# +# The files this function installs are sufficient for Swift programs to link to +# the given module at runtime, but not to build against them. To ensure SDK +# content is emitted for the module, you must also call +# _swift_testing_install_swiftmodule(). function(_swift_testing_install_target module) install(TARGETS ${module} ARCHIVE DESTINATION "${SwiftTesting_INSTALL_LIBDIR}" LIBRARY DESTINATION "${SwiftTesting_INSTALL_LIBDIR}" RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endfunction() +# Install the specified module's .swiftmodule, .swiftdoc, and .swiftinterface +# products into the appropriate directory. +# +# This function does not install the module's platform build products such as +# .dylib or .exe files. Call _swift_testing_install_target() to ensure those +# files are installed. +function(_swift_testing_install_swiftmodule module) get_target_property(type ${module} TYPE) if(type STREQUAL EXECUTABLE) return() From bfae5b2c8a1e695b4f790a0057df900fd920eaf3 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Tue, 21 Apr 2026 11:22:39 -0400 Subject: [PATCH 15/15] Remove autolink flag --- Sources/_TestingInterop/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Sources/_TestingInterop/CMakeLists.txt b/Sources/_TestingInterop/CMakeLists.txt index 70392fe25..4a4271ae3 100644 --- a/Sources/_TestingInterop/CMakeLists.txt +++ b/Sources/_TestingInterop/CMakeLists.txt @@ -23,13 +23,6 @@ else() -fno-exceptions) endif() -if(NOT BUILD_SHARED_LIBS) - # When building a static library, tell clients to autolink the internal - # libraries. - target_compile_options(_TestingInterop PRIVATE - "SHELL:-Xfrontend -public-autolink-library -Xfrontend _TestingInterop") -endif() - _swift_testing_install_target(_TestingInterop) set_property(GLOBAL APPEND PROPERTY SwiftTesting_EXPORTS _TestingInterop)