Skip to content
Draft
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
21 changes: 17 additions & 4 deletions Sources/BuildServerIntegration/BuildServerManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,17 @@ private extension BuildServerSpec {
selectedBuildSystem = .swiftbuild
case (.native, _):
selectedBuildSystem = .native
// If there is no explicit preference and we're background indexing, default to native
// for now.
// If there is no explicit preference and we're background indexing, use the toolchain version to pick a default.
case (nil, true):
selectedBuildSystem = .native
selectedBuildSystem = await SwiftPMBuildSystem.defaultBuildSystem(toolchainRegistry: toolchainRegistry)
// If there is no explicit preference and we're not background indexing, we should
// attempt to match the user's manually intiated builds to maximize compatibility.
case (nil, false):
selectedBuildSystem = inferredBuildSystem ?? .native
if let inferredBuildSystem {
selectedBuildSystem = inferredBuildSystem
} else {
selectedBuildSystem = await SwiftPMBuildSystem.defaultBuildSystem(toolchainRegistry: toolchainRegistry)
}
}
// Choose the appropiate adapter based on the build system we just selected.
switch selectedBuildSystem {
Expand Down Expand Up @@ -2124,3 +2127,13 @@ private extension OnBuildLogMessageNotification {
}
}
}

extension SwiftPMBuildSystem {
package static func defaultBuildSystem(toolchainRegistry: ToolchainRegistry) async -> SwiftPMBuildSystem {
let toolchain = await toolchainRegistry.preferredToolchain(containing: [\.swift])
guard let swiftVersion = try? await toolchain?.swiftVersion, swiftVersion >= SwiftVersion(6, 5) else {
return .native
}
return .swiftbuild
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ package struct IndexedSingleSwiftFileTestProject {
"-index-store-path", try indexURL.filePath,
"-typecheck",
]
if let globalModuleCache = try globalModuleCache {
let moduleCache = try uniqueTestModuleCache()
if let moduleCache {
compilerArguments += [
"-module-cache-path", try globalModuleCache.filePath,
"-module-cache-path", try moduleCache.filePath,
]
}
if !indexSystemModules {
Expand Down Expand Up @@ -207,6 +208,9 @@ package struct IndexedSingleSwiftFileTestProject {
cleanUp: {
if cleanUp {
try? FileManager.default.removeItem(at: testWorkspaceDirectory)
if let moduleCache {
try? FileManager.default.removeItem(at: moduleCache)
}
}
}
)
Expand Down
21 changes: 17 additions & 4 deletions Sources/SKTestSupport/SwiftPMTestProject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

import BuildServerIntegration
package import Foundation
@_spi(SourceKitLSP) package import LanguageServerProtocol
@_spi(SourceKitLSP) import SKLogging
Expand Down Expand Up @@ -241,9 +242,15 @@ package class SwiftPMTestProject: MultiFileTestProject {
/// Build a SwiftPM package package manifest is located in the directory at `path`.
package static func build(
at path: URL,
buildSystem: SwiftPMBuildSystem = .native,
buildSystem: SwiftPMBuildSystem? = nil,
extraArguments: [String] = []
) async throws {
let resolvedBuildSystem: SwiftPMBuildSystem
if let buildSystem {
resolvedBuildSystem = buildSystem
} else {
resolvedBuildSystem = await SwiftPMBuildSystem.defaultBuildSystem(toolchainRegistry: ToolchainRegistry.forTesting)
}
guard let swift = await ToolchainRegistry.forTesting.default?.swift else {
throw Error.swiftNotFound
}
Expand All @@ -255,11 +262,17 @@ package class SwiftPMTestProject: MultiFileTestProject {
"--build-tests",
"-Xswiftc", "-index-ignore-system-modules",
"-Xcc", "-index-ignore-system-symbols",
"--build-system", buildSystem.rawValue,
"--build-system", resolvedBuildSystem.rawValue,
] + extraArguments
if let globalModuleCache = try globalModuleCache {
let moduleCache = try uniqueTestModuleCache()
defer {
if let moduleCache, cleanScratchDirectories {
try? FileManager.default.removeItem(at: moduleCache)
}
}
if let moduleCache {
arguments += [
"-Xswiftc", "-module-cache-path", "-Xswiftc", try globalModuleCache.filePath,
"-Xswiftc", "-module-cache-path", "-Xswiftc", try moduleCache.filePath,
]
}
let argumentsCopy = arguments
Expand Down
12 changes: 9 additions & 3 deletions Sources/SKTestSupport/TestSourceKitLSPClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,10 @@ package final class TestSourceKitLSPClient: MessageHandler, Sendable {
} else {
try await SourceKitLSPOptions.testDefault()
}
if let globalModuleCache = try globalModuleCache {
let moduleCache = try uniqueTestModuleCache()
if let moduleCache {
options.swiftPMOrDefault.swiftCompilerFlags =
(options.swiftPMOrDefault.swiftCompilerFlags ?? []) + ["-module-cache-path", try globalModuleCache.filePath]
(options.swiftPMOrDefault.swiftCompilerFlags ?? []) + ["-module-cache-path", try moduleCache.filePath]
}
options.backgroundIndexing = enableBackgroundIndexing
if options.sourcekitdRequestTimeout == nil {
Expand All @@ -196,7 +197,12 @@ package final class TestSourceKitLSPClient: MessageHandler, Sendable {
}
)

self.cleanUp = cleanUp
self.cleanUp = {
if let moduleCache, cleanScratchDirectories {
try? FileManager.default.removeItem(at: moduleCache)
}
cleanUp()
}
self.usePullDiagnostics = usePullDiagnostics
self.serverToClientConnection.start(handler: WeakMessageHandler(self))

Expand Down
8 changes: 6 additions & 2 deletions Sources/SKTestSupport/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ package func withTestScratchDir<T>(
return try await body(scratchDirectory)
}

var globalModuleCache: URL? {
private var testModuleCacheRoot: URL? {
get throws {
if let customModuleCache = ProcessInfo.processInfo.environment["SOURCEKIT_LSP_TEST_MODULE_CACHE"] {
if customModuleCache.isEmpty {
Expand All @@ -121,6 +121,10 @@ var globalModuleCache: URL? {
return URL(fileURLWithPath: customModuleCache)
}
return try FileManager.default.temporaryDirectory.realpath
.appending(components: "sourcekit-lsp-test-scratch", "shared-module-cache")
.appending(components: "sourcekit-lsp-test-scratch", "module-caches")
}
}

func uniqueTestModuleCache() throws -> URL? {
return try testModuleCacheRoot?.appending(component: UUID().uuidString, directoryHint: .isDirectory)
}
9 changes: 4 additions & 5 deletions Tests/SourceKitLSPTests/WorkspaceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1394,11 +1394,10 @@ final class WorkspaceTests: SourceKitLSPTestCase {
workspace: DocumentURI(project.scratchDirectory)
)
)
if project.testClient.server.options.swiftPMOrDefault.buildSystem == .swiftbuild {
XCTAssertEqual(outputPaths.outputPaths.map { $0.suffix(7) }.sorted(), ["FileA.o", "FileB.o"])
} else {
XCTAssertEqual(outputPaths.outputPaths.map { $0.suffix(13) }.sorted(), ["FileA.swift.o", "FileB.swift.o"])
}
XCTAssertTrue(
outputPaths.outputPaths.map { $0.suffix(7) }.sorted() == ["FileA.o", "FileB.o"]
|| outputPaths.outputPaths.map { $0.suffix(13) }.sorted() == ["FileA.swift.o", "FileB.swift.o"]
)
}

func testOrphanedClangLanguageServiceShutdown() async throws {
Expand Down