Skip to content

Commit 6fe1481

Browse files
committed
Allow running tests on Windows by using SWIFTSYNTAX_BUILD_DYNAMIC_LIBRARY
Also, fix two minor Windows test failures.
1 parent 213b62f commit 6fe1481

File tree

4 files changed

+42
-25
lines changed

4 files changed

+42
-25
lines changed

CONTRIBUTING.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,20 @@ $ swift build -Xcxx -I/usr/lib/swift -Xcxx -I/usr/lib/swift/Block
3838
3939
### Windows
4040

41-
You must provide the following dependencies for SourceKit-LSP:
42-
- SQLite3 ninja
41+
To build SourceKit-LSP on Windows, the swift-syntax libraries need to be built as dynamic libraries so we do not exceed the maximum symbol limit in a single binary. Additionally, the equivalent search paths to the linux build need to be passed. Run the following in Command Prompt.
4342

4443
```cmd
45-
> swift build -Xcc -I<absolute path to SQLite header search path> -Xlinker -L<absolute path to SQLite library search path> -Xcc -I%SDKROOT%\usr\include -Xcc -I%SDKROOT%\usr\include\Block
44+
> set SWIFTSYNTAX_BUILD_DYNAMIC_LIBRARY=1
45+
> swift build -Xcc -I%SDKROOT%\usr\include -Xcc -I%SDKROOT%\usr\include\Block
4646
```
4747

48-
The header and library search paths must be passed to the build by absolute path. This allows the clang importer and linker to find the dependencies.
48+
To work on SourceKit-LSP in VS Code, add the following to your `settings.json`, for other editors ensure that the `SWIFTSYNTAX_BUILD_DYNAMIC_LIBRARY` environment variable is set when launching `sourcekit-lsp`.
4949

50-
Additionally, as SourceKit-LSP depends on libdispatch and the Blocks runtime, which are part of the SDK, but not in the default search path, need to be explicitly added.
50+
```json
51+
"swift.swiftEnvironmentVariables": {
52+
"SWIFTSYNTAX_BUILD_DYNAMIC_LIBRARY": "1"
53+
},
54+
```
5155

5256
### Devcontainer
5357

Package.swift

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,8 @@ let package = Package(
128128
"SwiftExtensions",
129129
"ToolchainRegistry",
130130
.product(name: "ArgumentParser", package: "swift-argument-parser"),
131-
.product(name: "SwiftIDEUtils", package: "swift-syntax"),
132-
.product(name: "SwiftSyntax", package: "swift-syntax"),
133-
.product(name: "SwiftParser", package: "swift-syntax"),
134131
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
135-
],
132+
] + swiftSyntaxDependencies(["SwiftIDEUtils", "SwiftSyntax", "SwiftParser"]),
136133
exclude: ["CMakeLists.txt"],
137134
swiftSettings: globalSwiftSettings
138135
),
@@ -360,17 +357,14 @@ let package = Package(
360357
"SwiftExtensions",
361358
"ToolchainRegistry",
362359
.product(name: "IndexStoreDB", package: "indexstore-db"),
363-
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
364360
.product(name: "Crypto", package: "swift-crypto"),
365-
.product(name: "SwiftDiagnostics", package: "swift-syntax"),
366-
.product(name: "SwiftIDEUtils", package: "swift-syntax"),
367-
.product(name: "SwiftParser", package: "swift-syntax"),
368-
.product(name: "SwiftParserDiagnostics", package: "swift-syntax"),
369-
.product(name: "SwiftRefactor", package: "swift-syntax"),
370-
.product(name: "SwiftSyntax", package: "swift-syntax"),
371361
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
372362
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
373-
],
363+
]
364+
+ swiftSyntaxDependencies([
365+
"SwiftBasicFormat", "SwiftDiagnostics", "SwiftIDEUtils", "SwiftParser", "SwiftParserDiagnostics",
366+
"SwiftRefactor", "SwiftSyntax",
367+
]),
374368
exclude: ["CMakeLists.txt"],
375369
swiftSettings: globalSwiftSettings
376370
),
@@ -391,14 +385,10 @@ let package = Package(
391385
"ToolchainRegistry",
392386
.product(name: "IndexStoreDB", package: "indexstore-db"),
393387
.product(name: "ISDBTestSupport", package: "indexstore-db"),
394-
.product(name: "SwiftParser", package: "swift-syntax"),
395-
.product(name: "SwiftSyntax", package: "swift-syntax"),
396388
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
397389
// Depend on `SwiftCompilerPlugin` and `SwiftSyntaxMacros` so the modules are built before running tests and can
398-
// be used by test cases that test macros (see `SwiftPMTestProject.macroPackageManifest`).
399-
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
400-
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
401-
],
390+
// be used by test cases that test macros (see `SwiftPMTestProject.macroPackageManifest`)
391+
] + swiftSyntaxDependencies(["SwiftParser", "SwiftSyntax", "SwiftCompilerPlugin", "SwiftSyntaxMacros"]),
402392
swiftSettings: globalSwiftSettings
403393
),
404394

@@ -440,6 +430,14 @@ let package = Package(
440430
swiftLanguageVersions: [.v5, .version("6")]
441431
)
442432

433+
func swiftSyntaxDependencies(_ names: [String]) -> [Target.Dependency] {
434+
if buildDynamicSwiftSyntaxLibrary {
435+
return [.product(name: "_SwiftSyntaxDynamic", package: "swift-syntax")]
436+
} else {
437+
return names.map { .product(name: $0, package: "swift-syntax") }
438+
}
439+
}
440+
443441
// MARK: - Parse build arguments
444442

445443
func hasEnvironmentVariable(_ name: String) -> Bool {
@@ -460,6 +458,13 @@ var installAction: Bool { hasEnvironmentVariable("SOURCEKIT_LSP_CI_INSTALL") }
460458
/// remote dependency.
461459
var useLocalDependencies: Bool { hasEnvironmentVariable("SWIFTCI_USE_LOCAL_DEPS") }
462460

461+
/// Whether swift-syntax is being built as a single dynamic library instead of as a separate library per module.
462+
///
463+
/// This means that the swift-syntax symbols don't need to be statically linked, which allows us to stay below the
464+
/// maximum number of exported symbols on Windows, in turn allowing us to build sourcekit-lsp using SwiftPM on Windows
465+
/// and run its tests.
466+
var buildDynamicSwiftSyntaxLibrary: Bool { hasEnvironmentVariable("SWIFTSYNTAX_BUILD_DYNAMIC_LIBRARY") }
467+
463468
// MARK: - Dependencies
464469

465470
// When building with the swift build-script, use local dependencies whose contents are controlled

Tests/SourceKitLSPTests/PullDiagnosticsTests.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import SourceKitLSP
1717
import SwiftExtensions
1818
import XCTest
1919

20+
#if os(Windows)
21+
import WinSDK
22+
#endif
23+
2024
final class PullDiagnosticsTests: XCTestCase {
2125
func testUnknownIdentifierDiagnostic() async throws {
2226
let testClient = try await TestSourceKitLSPClient()
@@ -309,7 +313,11 @@ final class PullDiagnosticsTests: XCTestCase {
309313
if Task.isCancelled {
310314
break
311315
}
312-
usleep(10_000)
316+
#if os(Windows)
317+
Sleep(10 /*ms*/)
318+
#else
319+
usleep(10_000 /*µs*/)
320+
#endif
313321
}
314322
}
315323
let project = try await SwiftPMTestProject(

Tests/SourceKitLSPTests/SwiftInterfaceTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ final class SwiftInterfaceTests: XCTestCase {
3434
)
3535
)
3636
let location = try XCTUnwrap(resp?.locations?.only)
37-
XCTAssertTrue(location.uri.pseudoPath.hasSuffix("/Foundation.swiftinterface"))
37+
XCTAssertTrue(location.uri.pseudoPath.hasSuffix("Foundation.swiftinterface"))
3838
let fileContents = try XCTUnwrap(location.uri.fileURL.flatMap({ try String(contentsOf: $0, encoding: .utf8) }))
3939
// Sanity-check that the generated Swift Interface contains Swift code
4040
XCTAssert(

0 commit comments

Comments
 (0)