Skip to content

Commit ac330c3

Browse files
committed
Build plugin executables with debug symbols
This seems like the better default until we might add a dedicated debugging feature for plugins.
1 parent 309e231 commit ac330c3

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

Sources/SPMTestSupport/Toolchain.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Foundation
1414
import PackageModel
1515
import Workspace
1616
import TSCBasic
17+
import struct TSCUtility.SerializedDiagnostics
1718

1819
#if os(macOS)
1920
private func macOSBundleRoot() throws -> AbsolutePath {
@@ -93,5 +94,28 @@ extension UserToolchain {
9394
return true
9495
#endif
9596
}
96-
97+
98+
/// Helper function to determine whether serialized diagnostics work properly in the current environment.
99+
public func supportsSerializedDiagnostics(otherSwiftFlags: [String] = []) -> Bool {
100+
do {
101+
try testWithTemporaryDirectory { tmpPath in
102+
let inputPath = tmpPath.appending(component: "best.swift")
103+
try localFileSystem.writeFileContents(inputPath, string: "func foo() -> Bool {\nvar unused: Int\nreturn true\n}\n")
104+
let outputPath = tmpPath.appending(component: "foo")
105+
let serializedDiagnosticsPath = tmpPath.appending(component: "out.dia")
106+
let toolchainPath = self.swiftCompilerPath.parentDirectory.parentDirectory
107+
try Process.checkNonZeroExit(arguments: ["/usr/bin/xcrun", "--toolchain", toolchainPath.pathString, "swiftc", inputPath.pathString, "-Xfrontend", "-serialize-diagnostics-path", "-Xfrontend", serializedDiagnosticsPath.pathString, "-g", "-o", outputPath.pathString] + otherSwiftFlags)
108+
try Process.checkNonZeroExit(arguments: [outputPath.pathString])
109+
110+
let diaFileContents = try localFileSystem.readFileContents(serializedDiagnosticsPath)
111+
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
112+
if diagnosticsSet.diagnostics.isEmpty {
113+
throw StringError("does not support diagnostics")
114+
}
115+
}
116+
return true
117+
} catch {
118+
return false
119+
}
120+
}
97121
}

Sources/Workspace/DefaultPluginScriptRunner.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import PackageModel
1717
import SPMBuildCore
1818
import TSCBasic
1919

20+
import struct TSCUtility.SerializedDiagnostics
2021
import struct TSCUtility.Triple
2122

2223
/// A plugin script runner that compiles the plugin source files as an executable binary for the host platform, and invokes it as a subprocess.
@@ -121,6 +122,8 @@ public struct DefaultPluginScriptRunner: PluginScriptRunner, Cancellable {
121122

122123
// We use the toolchain's Swift compiler for compiling the plugin.
123124
var commandLine = [self.toolchain.swiftCompilerPathForManifests.pathString]
125+
126+
observabilityScope.emit(debug: "Using compiler \(self.toolchain.swiftCompilerPathForManifests.pathString)")
124127

125128
// Get access to the path containing the PackagePlugin module and library.
126129
let pluginLibraryPath = self.toolchain.swiftPMLibrariesLocation.pluginLibraryPath
@@ -166,6 +169,8 @@ public struct DefaultPluginScriptRunner: PluginScriptRunner, Cancellable {
166169
// Add any extra flags required as indicated by the ManifestLoader.
167170
commandLine += self.toolchain.swiftCompilerFlags
168171

172+
commandLine.append("-g")
173+
169174
// Add the Swift language version implied by the package tools version.
170175
commandLine += ["-swift-version", toolsVersion.swiftLanguageVersion.rawValue]
171176

Tests/SPMBuildCoreTests/PluginInvocationTests.swift

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -412,12 +412,14 @@ class PluginInvocationTests: XCTestCase {
412412
XCTAssertEqual(delegate.compiledResult, result)
413413
XCTAssertNil(delegate.cachedResult)
414414

415-
// Check the serialized diagnostics. We should no longer have an error but now have a warning.
416-
let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile)
417-
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
418-
XCTAssertEqual(diagnosticsSet.diagnostics.count, 1)
419-
let warningDiagnostic = try XCTUnwrap(diagnosticsSet.diagnostics.first)
420-
XCTAssertTrue(warningDiagnostic.text.hasPrefix("variable \'unused\' was never used"), "\(warningDiagnostic)")
415+
if try UserToolchain.default.supportsSerializedDiagnostics() {
416+
// Check the serialized diagnostics. We should no longer have an error but now have a warning.
417+
let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile)
418+
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
419+
XCTAssertEqual(diagnosticsSet.diagnostics.count, 1, "unexpected diagnostics count in \(diagnosticsSet.diagnostics) from \(result.diagnosticsFile.pathString)")
420+
let warningDiagnostic = try XCTUnwrap(diagnosticsSet.diagnostics.first)
421+
XCTAssertTrue(warningDiagnostic.text.hasPrefix("variable \'unused\' was never used"), "\(warningDiagnostic)")
422+
}
421423

422424
// Check that the executable file exists.
423425
XCTAssertTrue(localFileSystem.exists(result.executableFile), "\(result.executableFile.pathString)")
@@ -455,12 +457,14 @@ class PluginInvocationTests: XCTestCase {
455457
XCTAssertNil(delegate.compiledResult)
456458
XCTAssertEqual(delegate.cachedResult, result)
457459

458-
// Check that the diagnostics still have the same warning as before.
459-
let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile)
460-
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
461-
XCTAssertEqual(diagnosticsSet.diagnostics.count, 1)
462-
let warningDiagnostic = try XCTUnwrap(diagnosticsSet.diagnostics.first)
463-
XCTAssertTrue(warningDiagnostic.text.hasPrefix("variable \'unused\' was never used"), "\(warningDiagnostic)")
460+
if try UserToolchain.default.supportsSerializedDiagnostics() {
461+
// Check that the diagnostics still have the same warning as before.
462+
let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile)
463+
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
464+
XCTAssertEqual(diagnosticsSet.diagnostics.count, 1)
465+
let warningDiagnostic = try XCTUnwrap(diagnosticsSet.diagnostics.first)
466+
XCTAssertTrue(warningDiagnostic.text.hasPrefix("variable \'unused\' was never used"), "\(warningDiagnostic)")
467+
}
464468

465469
// Check that the executable file exists.
466470
XCTAssertTrue(localFileSystem.exists(result.executableFile), "\(result.executableFile.pathString)")

0 commit comments

Comments
 (0)