Skip to content

[cmake] Build swift-testing with CMake. #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store
/.build
/build
/Packages
/*.xcodeproj
xcuserdata/
Expand Down
30 changes: 30 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2024 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors

cmake_minimum_required(VERSION 3.19.6...3.29)

if(POLICY CMP0157)
cmake_policy(SET CMP0157 NEW)
endif()

project(SwiftTesting
LANGUAGES CXX Swift)

list(APPEND CMAKE_MODULE_PATH
${PROJECT_SOURCE_DIR}/cmake/modules
${PROJECT_SOURCE_DIR}/cmake/modules/shared)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)

add_subdirectory(Sources)
77 changes: 77 additions & 0 deletions Documentation/CMake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Building with CMake

## Add `swift-testing` to Your Project

Add `swift-testing` with to your project using the standard `FetchContent` or `find_package` mechanism, as appropriate for your project. For example:

```cmake
include(FetchContent)
FetchContent_Declare(SwiftTesting
GIT_REPOSITORY https://github.com/apple/swift-testing.git
GIT_TAG main)
FetchContent_MakeAvailable(SwiftTesting)
```

## Define Your Test Executable

To build a test executable using `swift-testing`, define an executable target
of the form `[YOURPROJECT]PackageTests`, set the executable suffix to be
`.swift-testing`, and link to your project targets with `Testing`.

The following
example shows what this might look like for a hypothetical project called
`Example`:

```cmake
add_executable(ExamplePackageTests
ExampleTests.swift
...)
set_target_properties(ExamplePackageTests PROPERTIES
SUFFIX .swift-testing)
target_link_libraries(ExamplePackageTests PRIVATE
Example
Testing
...)
```

When building the test executable, the code you're testing will need to be built
with `-enable-testing`. This should only be enabled for testing, for example:

```cmake
include(CTest)
if(BUILD_TESTING)
add_compile_options($<$<COMPILE_LANGUAGE:Swift>:-enable-testing>)
endif()
```

## Add an Entry Point

You must define a custom source file with a `@main` entry point. This should be
a separate source file that is included in your test executable's `SOURCES`
list.

The following example uses the SwiftPM entry point:

```swift
import Testing

@main struct Runner {
static func main() async {
await Testing.__swiftPMEntryPoint() as Never
}
}
```
> [!WARNING]
> The entry point is expected to change to an entry point designed for other
> build systems prior to `swift-testing` v1.


## Integrate with CTest

To run your test using CTest, add the test using the appropriate command line.

```cmake
include(CTest)
add_test(NAME ExamplePackageTests
COMMAND ExamplePackageTests)
```
25 changes: 25 additions & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2024 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors

# Macros must be built for the build machine, not the host.
include(ExternalProject)
ExternalProject_Add(TestingMacros
PREFIX "tm"
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/TestingMacros"
INSTALL_COMMAND "")
ExternalProject_Get_Property(TestingMacros BINARY_DIR)
if(CMAKE_HOST_WIN32)
set(TestingMacrosPath "${BINARY_DIR}/TestingMacros.exe#TestingMacros")
else()
set(TestingMacrosPath "${BINARY_DIR}/TestingMacros#TestingMacros")
endif()

include(AvailabilityDefinitions)
include(CompilerSettings)
add_subdirectory(_TestingInternals)
add_subdirectory(Testing)
105 changes: 105 additions & 0 deletions Sources/Testing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2024 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors

add_library(Testing
EntryPoints/ABIEntryPoint.swift
EntryPoints/ABIv0/ABIv0.Record.swift
EntryPoints/ABIv0/ABIv0.Record+Streaming.swift
EntryPoints/ABIv0/ABIv0.swift
EntryPoints/ABIv0/Encoded/ABIv0.EncodedEvent.swift
EntryPoints/ABIv0/Encoded/ABIv0.EncodedInstant.swift
EntryPoints/ABIv0/Encoded/ABIv0.EncodedIssue.swift
EntryPoints/ABIv0/Encoded/ABIv0.EncodedMessage.swift
EntryPoints/ABIv0/Encoded/ABIv0.EncodedTest.swift
EntryPoints/EntryPoint.swift
EntryPoints/SwiftPMEntryPoint.swift
EntryPoints/XCTestScaffold.swift
Events/Clock.swift
Events/Event.swift
Events/Recorder/Event.ConsoleOutputRecorder.swift
Events/Recorder/Event.HumanReadableOutputRecorder.swift
Events/Recorder/Event.JUnitXMLRecorder.swift
Events/Recorder/Event.Symbol.swift
Events/TimeValue.swift
ExitTests/ExitCondition.swift
ExitTests/ExitTest.swift
ExitTests/WaitFor.swift
Expectations/Expectation.swift
Expectations/Expectation+Macro.swift
Expectations/ExpectationChecking+Macro.swift
Issues/Confirmation.swift
Issues/ErrorSnapshot.swift
Issues/Issue.swift
Issues/Issue+Recording.swift
Issues/KnownIssue.swift
Parameterization/CustomTestArgumentEncodable.swift
Parameterization/Test.Case.Generator.swift
Parameterization/Test.Case.ID.swift
Parameterization/Test.Case.swift
Parameterization/TypeInfo.swift
Running/Configuration.swift
Running/Configuration.TestFilter.swift
Running/Configuration+EventHandling.swift
Running/Runner.Plan.swift
Running/Runner.Plan+Dumping.swift
Running/Runner.RuntimeState.swift
Running/Runner.swift
Running/SkipInfo.swift
SourceAttribution/Backtrace.swift
SourceAttribution/CustomTestStringConvertible.swift
SourceAttribution/Expression.swift
SourceAttribution/Expression+Macro.swift
SourceAttribution/SourceContext.swift
SourceAttribution/SourceLocation.swift
Support/Additions/ArrayAdditions.swift
Support/Additions/CollectionDifferenceAdditions.swift
Support/Additions/CommandLineAdditions.swift
Support/Additions/NumericAdditions.swift
Support/Additions/ResultAdditions.swift
Support/Additions/StringAdditions.swift
Support/CartesianProduct.swift
Support/CError.swift
Support/Environment.swift
Support/FileHandle.swift
Support/Graph.swift
Support/JSON.swift
Support/Locked.swift
Support/SystemError.swift
Support/UncheckedSendable.swift
Support/Versions.swift
Test.ID.Selection.swift
Test.ID.swift
Test.swift
Test+Discovery.swift
Test+Macro.swift
Traits/Bug.swift
Traits/Comment.swift
Traits/Comment+Macro.swift
Traits/ConditionTrait.swift
Traits/ConditionTrait+Macro.swift
Traits/HiddenTrait.swift
Traits/ParallelizationTrait.swift
Traits/SPIAwareTrait.swift
Traits/Tags/Tag.Color.swift
Traits/Tags/Tag.Color+Loading.swift
Traits/Tags/Tag.List.swift
Traits/Tags/Tag.swift
Traits/Tags/Tag+Macro.swift
Traits/Tags/Tag+Predefined.swift
Traits/TimeLimitTrait.swift
Traits/Trait.swift)
target_link_libraries(Testing PRIVATE
_TestingInternals)
add_dependencies(Testing
TestingMacros)
target_compile_definitions(Testing PRIVATE
SWT_BUILDING_WITH_CMAKE)
target_compile_options(Testing PUBLIC
-load-plugin-executable "${TestingMacrosPath}")
target_compile_options(Testing PRIVATE
-enable-library-evolution)
4 changes: 4 additions & 0 deletions Sources/Testing/EntryPoints/EntryPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

/// The common implementation of the entry point functions in this file.
///
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/EntryPoints/SwiftPMEntryPoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

/// The entry point to the testing library used by Swift Package Manager.
///
Expand Down
6 changes: 6 additions & 0 deletions Sources/Testing/EntryPoints/XCTestScaffold.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
//

#if !SWT_NO_XCTEST_SCAFFOLDING && canImport(XCTest)

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

public import XCTest

#if SWT_TARGET_OS_APPLE
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/Events/Clock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

@_spi(Experimental) @_spi(ForToolsIntegrationOnly)
extension Test {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/Events/TimeValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@

// `internal` because `TimeValue.init(_ timespec:)` below is internal and
// references a type (`timespec`) which comes from this import.
#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
internal import _TestingInternals
#endif

/// A container type representing a time value that is suitable for storage,
/// conversion, encoding, and decoding.
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/ExitTests/ExitCondition.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

/// An enumeration describing possible conditions under which an exit test will
/// succeed or fail.
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/ExitTests/ExitTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

#if !SWT_NO_EXIT_TESTS
/// A type describing an exit test.
Expand Down
5 changes: 5 additions & 0 deletions Sources/Testing/ExitTests/WaitFor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
//

#if !SWT_NO_EXIT_TESTS

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
internal import _TestingInternals
#endif

#if SWT_TARGET_OS_APPLE || os(Linux)
/// Block the calling thread, wait for the target process to exit, and return
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/SourceAttribution/Backtrace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

/// A type representing a backtrace or stack trace.
public struct Backtrace: Sendable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

extension CommandLine {
/// Get the command-line arguments passed to this process.
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/Support/Additions/StringAdditions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
private import _TestingInternals
#endif

extension String {
init?(validatingUTF8CString cString: UnsafePointer<CChar>) {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Testing/Support/CError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

#if SWT_BUILDING_WITH_CMAKE
@_implementationOnly import _TestingInternals
#else
internal import _TestingInternals
#endif

/// A type representing an error from a C function such as `fopen()`.
///
Expand Down
Loading