Skip to content

Commit 9387af3

Browse files
authored
Merge branch 'main' into maxd/platform-version-provider
2 parents f8aee43 + e9fa373 commit 9387af3

28 files changed

+1111
-595
lines changed

CMakeLists.txt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,35 @@
66
# See http://swift.org/LICENSE.txt for license information
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9+
if(POLICY CMP0091)
10+
cmake_policy(SET CMP0091 NEW)
11+
endif()
12+
913
cmake_minimum_required(VERSION 3.19)
1014

1115
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
1216

1317
project(SwiftPM LANGUAGES C Swift)
1418

19+
option(BUILD_SHARED_LIBS "Build shared libraries by default" YES)
20+
option(FIND_PM_DEPS "Search for all external Package Manager dependencies" YES)
21+
1522
set(CMAKE_Swift_LANGUAGE_VERSION 5)
1623
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
24+
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
1725

1826
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
1927
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
2028
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
2129

22-
option(BUILD_SHARED_LIBS "Build shared libraries by default" YES)
23-
option(FIND_PM_DEPS "Search for all external Package Manager dependencies" YES)
30+
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
31+
set(CMAKE_POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})
2432

2533
string(COMPARE EQUAL ${CMAKE_SYSTEM_NAME} Windows CMAKE_INSTALL_DEFAULT)
2634
option(USE_CMAKE_INSTALL
2735
"Install build products using cmake's install() instead of the bootstrap script's install()"
2836
${CMAKE_INSTALL_DEFAULT})
2937

30-
if(BUILD_SHARED_LIBS)
31-
set(CMAKE_POSITION_INDEPENDENT_CODE YES)
32-
endif()
33-
3438
add_compile_options(-DUSE_IMPL_ONLY_IMPORTS)
3539

3640
if(FIND_PM_DEPS)

Sources/Basics/Concurrency/ConcurrencyHelpers.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ extension DispatchQueue {
4848
}
4949

5050
/// Bridges between potentially blocking methods that take a result completion closure and async/await
51-
public func safe_async<T, ErrorType: Error>(_ body: @Sendable @escaping (@Sendable @escaping (Result<T, ErrorType>) -> Void) -> Void) async throws -> T {
51+
public func safe_async<T, ErrorType: Error>(
52+
_ body: @Sendable @escaping (@Sendable @escaping (Result<T, ErrorType>) -> Void) -> Void
53+
) async throws -> T {
5254
try await withCheckedThrowingContinuation { continuation in
53-
// It is possible that body make block indefinitely on a lock, sempahore,
54-
// or similar then synchrously call the completion handler. For full safety
55+
// It is possible that body make block indefinitely on a lock, semaphore,
56+
// or similar then synchronously call the completion handler. For full safety
5557
// it is essential to move the execution off the swift concurrency pool
5658
DispatchQueue.sharedConcurrent.async {
5759
body {

Sources/Build/BuildManifest/LLBuildManifestBuilder.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ public class LLBuildManifestBuilder {
117117
}
118118
}
119119

120-
try self.addTestDiscoveryGenerationCommand()
120+
if self.buildParameters.testingParameters.library == .xctest {
121+
try self.addTestDiscoveryGenerationCommand()
122+
}
121123
try self.addTestEntryPointGenerationCommand()
122124

123125
// Create command for all products in the plan.
@@ -266,8 +268,9 @@ extension LLBuildManifestBuilder {
266268

267269
let outputs = testEntryPointTarget.target.sources.paths
268270

269-
guard let mainOutput = (outputs.first { $0.basename == TestEntryPointTool.mainFileName }) else {
270-
throw InternalError("main output (\(TestEntryPointTool.mainFileName)) not found")
271+
let mainFileName = TestEntryPointTool.mainFileName(for: buildParameters.testingParameters.library)
272+
guard let mainOutput = (outputs.first { $0.basename == mainFileName }) else {
273+
throw InternalError("main output (\(mainFileName)) not found")
271274
}
272275
let cmdName = mainOutput.pathString
273276
self.manifest.addTestEntryPointCmd(

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,15 +200,22 @@ final class TestDiscoveryCommand: CustomLLBuildCommand, TestBuildCommand {
200200
}
201201
}
202202

203+
extension TestEntryPointTool {
204+
public static func mainFileName(for library: BuildParameters.Testing.Library) -> String {
205+
"runner-\(library).swift"
206+
}
207+
}
208+
203209
final class TestEntryPointCommand: CustomLLBuildCommand, TestBuildCommand {
204210
private func execute(fileSystem: Basics.FileSystem, tool: TestEntryPointTool) throws {
205211
let outputs = tool.outputs.compactMap { try? AbsolutePath(validating: $0.name) }
206212

207213
// Find the main output file
214+
let mainFileName = TestEntryPointTool.mainFileName(for: self.context.buildParameters.testingParameters.library)
208215
guard let mainFile = outputs.first(where: { path in
209-
path.basename == TestEntryPointTool.mainFileName
216+
path.basename == mainFileName
210217
}) else {
211-
throw InternalError("main file output (\(TestEntryPointTool.mainFileName)) not found")
218+
throw InternalError("main file output (\(mainFileName)) not found")
212219
}
213220

214221
// Write the main file.
@@ -393,7 +400,8 @@ public struct BuildDescription: Codable {
393400
return try BuiltTestProduct(
394401
productName: desc.product.name,
395402
binaryPath: desc.binaryPath,
396-
packagePath: desc.package.path
403+
packagePath: desc.package.path,
404+
library: desc.buildParameters.testingParameters.library
397405
)
398406
}
399407
self.pluginDescriptions = pluginDescriptions

Sources/Build/BuildPlan/BuildPlan+Test.swift

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -105,21 +105,25 @@ extension BuildPlan {
105105

106106
/// Generates a synthesized test entry point target, consisting of a single "main" file which calls the test entry
107107
/// point API and leverages the test discovery target to reference which tests to run.
108-
func generateSynthesizedEntryPointTarget(discoveryTarget: SwiftTarget, discoveryResolvedTarget: ResolvedTarget) throws -> SwiftTargetBuildDescription {
108+
func generateSynthesizedEntryPointTarget(
109+
swiftTargetDependencies: [Target.Dependency],
110+
resolvedTargetDependencies: [ResolvedTarget.Dependency]
111+
) throws -> SwiftTargetBuildDescription {
109112
let entryPointDerivedDir = buildParameters.buildPath.appending(components: "\(testProduct.name).derived")
110-
let entryPointMainFile = entryPointDerivedDir.appending(component: TestEntryPointTool.mainFileName)
113+
let entryPointMainFileName = TestEntryPointTool.mainFileName(for: buildParameters.testingParameters.library)
114+
let entryPointMainFile = entryPointDerivedDir.appending(component: entryPointMainFileName)
111115
let entryPointSources = Sources(paths: [entryPointMainFile], root: entryPointDerivedDir)
112116

113117
let entryPointTarget = SwiftTarget(
114118
name: testProduct.name,
115119
type: .library,
116-
dependencies: testProduct.underlyingProduct.targets.map { .target($0, conditions: []) } + [.target(discoveryTarget, conditions: [])],
120+
dependencies: testProduct.underlyingProduct.targets.map { .target($0, conditions: []) } + swiftTargetDependencies,
117121
packageAccess: true, // test target is allowed access to package decls
118122
testEntryPointSources: entryPointSources
119123
)
120124
let entryPointResolvedTarget = ResolvedTarget(
121125
target: entryPointTarget,
122-
dependencies: testProduct.targets.map { .target($0, conditions: []) } + [.target(discoveryResolvedTarget, conditions: [])],
126+
dependencies: testProduct.targets.map { .target($0, conditions: []) } + resolvedTargetDependencies,
123127
defaultLocalization: testProduct.defaultLocalization,
124128
supportedPlatforms: testProduct.supportedPlatforms,
125129
platformVersionProvider: testProduct.platformVersionProvider
@@ -135,21 +139,34 @@ extension BuildPlan {
135139
)
136140
}
137141

142+
let discoveryTargets: (target: SwiftTarget, resolved: ResolvedTarget, buildDescription: SwiftTargetBuildDescription)?
143+
let swiftTargetDependencies: [Target.Dependency]
144+
let resolvedTargetDependencies: [ResolvedTarget.Dependency]
145+
146+
switch buildParameters.testingParameters.library {
147+
case .xctest:
148+
discoveryTargets = try generateDiscoveryTargets()
149+
swiftTargetDependencies = [.target(discoveryTargets!.target, conditions: [])]
150+
resolvedTargetDependencies = [.target(discoveryTargets!.resolved, conditions: [])]
151+
case .swiftTesting:
152+
discoveryTargets = nil
153+
swiftTargetDependencies = testProduct.targets.map { .target($0.underlyingTarget, conditions: []) }
154+
resolvedTargetDependencies = testProduct.targets.map { .target($0, conditions: []) }
155+
}
156+
138157
if let entryPointResolvedTarget = testProduct.testEntryPointTarget {
139158
if isEntryPointPathSpecifiedExplicitly || explicitlyEnabledDiscovery {
140-
let discoveryTargets = try generateDiscoveryTargets()
141-
142159
if isEntryPointPathSpecifiedExplicitly {
143160
// Allow using the explicitly-specified test entry point target, but still perform test discovery and thus declare a dependency on the discovery targets.
144161
let entryPointTarget = SwiftTarget(
145162
name: entryPointResolvedTarget.underlyingTarget.name,
146-
dependencies: entryPointResolvedTarget.underlyingTarget.dependencies + [.target(discoveryTargets.target, conditions: [])],
163+
dependencies: entryPointResolvedTarget.underlyingTarget.dependencies + swiftTargetDependencies,
147164
packageAccess: entryPointResolvedTarget.packageAccess,
148165
testEntryPointSources: entryPointResolvedTarget.underlyingTarget.sources
149166
)
150167
let entryPointResolvedTarget = ResolvedTarget(
151168
target: entryPointTarget,
152-
dependencies: entryPointResolvedTarget.dependencies + [.target(discoveryTargets.resolved, conditions: [])],
169+
dependencies: entryPointResolvedTarget.dependencies + resolvedTargetDependencies,
153170
defaultLocalization: testProduct.defaultLocalization,
154171
supportedPlatforms: testProduct.supportedPlatforms,
155172
platformVersionProvider: testProduct.platformVersionProvider
@@ -164,11 +181,14 @@ extension BuildPlan {
164181
observabilityScope: observabilityScope
165182
)
166183

167-
result.append((testProduct, discoveryTargets.buildDescription, entryPointTargetBuildDescription))
184+
result.append((testProduct, discoveryTargets?.buildDescription, entryPointTargetBuildDescription))
168185
} else {
169186
// Ignore test entry point and synthesize one, declaring a dependency on the test discovery targets created above.
170-
let entryPointTargetBuildDescription = try generateSynthesizedEntryPointTarget(discoveryTarget: discoveryTargets.target, discoveryResolvedTarget: discoveryTargets.resolved)
171-
result.append((testProduct, discoveryTargets.buildDescription, entryPointTargetBuildDescription))
187+
let entryPointTargetBuildDescription = try generateSynthesizedEntryPointTarget(
188+
swiftTargetDependencies: swiftTargetDependencies,
189+
resolvedTargetDependencies: resolvedTargetDependencies
190+
)
191+
result.append((testProduct, discoveryTargets?.buildDescription, entryPointTargetBuildDescription))
172192
}
173193
} else {
174194
// Use the test entry point as-is, without performing test discovery.
@@ -185,9 +205,11 @@ extension BuildPlan {
185205
}
186206
} else {
187207
// Synthesize a test entry point target, declaring a dependency on the test discovery targets.
188-
let discoveryTargets = try generateDiscoveryTargets()
189-
let entryPointTargetBuildDescription = try generateSynthesizedEntryPointTarget(discoveryTarget: discoveryTargets.target, discoveryResolvedTarget: discoveryTargets.resolved)
190-
result.append((testProduct, discoveryTargets.buildDescription, entryPointTargetBuildDescription))
208+
let entryPointTargetBuildDescription = try generateSynthesizedEntryPointTarget(
209+
swiftTargetDependencies: swiftTargetDependencies,
210+
resolvedTargetDependencies: resolvedTargetDependencies
211+
)
212+
result.append((testProduct, discoveryTargets?.buildDescription, entryPointTargetBuildDescription))
191213
}
192214
}
193215

Sources/Commands/Utilities/PluginDelegate.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import SPMBuildCore
1818

1919
import class TSCBasic.BufferedOutputByteStream
2020
import class TSCBasic.Process
21+
import struct TSCBasic.ProcessResult
2122

2223
final class PluginDelegate: PluginInvocationDelegate {
2324
let swiftTool: SwiftTool
@@ -376,14 +377,18 @@ final class PluginDelegate: PluginInvocationDelegate {
376377
try swiftTool.fileSystem.removeFileTree(outputDir)
377378

378379
// Run the symbol graph extractor on the target.
379-
try symbolGraphExtractor.extractSymbolGraph(
380+
let result = try symbolGraphExtractor.extractSymbolGraph(
380381
target: target,
381382
buildPlan: try buildSystem.buildPlan,
382383
outputRedirection: .collect,
383384
outputDirectory: outputDir,
384385
verboseOutput: self.swiftTool.logLevel <= .info
385386
)
386387

388+
guard result.exitStatus == .terminated(code: 0) else {
389+
throw ProcessResult.Error.nonZeroExit(result)
390+
}
391+
387392
// Return the results to the plugin.
388393
return PluginInvocationSymbolGraphResult(directoryPath: outputDir.pathString)
389394
}

Sources/LLBuildManifest/Tools.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public struct TestDiscoveryTool: ToolProtocol {
6363

6464
public struct TestEntryPointTool: ToolProtocol {
6565
public static let name: String = "test-entry-point-tool"
66-
public static let mainFileName: String = "runner.swift"
6766

6867
public var inputs: [Node]
6968
public var outputs: [Node]

0 commit comments

Comments
 (0)