Skip to content
Closed
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
9 changes: 3 additions & 6 deletions Sources/Build/BuildPlan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -963,8 +963,7 @@ public final class SwiftTargetBuildDescription {
/// When `scanInvocation` argument is set to `true`, omit the side-effect producing arguments
/// such as emitting a module or supplementary outputs.
public func emitCommandLine(scanInvocation: Bool = false) throws -> [String] {
var result: [String] = []
result.append(buildParameters.toolchain.swiftCompilerPath.pathString)
var result: [String] = buildParameters.toolchain.commandLineForSwiftCompilation(fileSystem: fileSystem)

result.append("-module-name")
result.append(target.c99name)
Expand Down Expand Up @@ -1006,8 +1005,7 @@ public final class SwiftTargetBuildDescription {
throw InternalError("expecting emitSwiftModuleSeparately in build parameters")
}

var result: [String] = []
result.append(buildParameters.toolchain.swiftCompilerPath.pathString)
var result: [String] = buildParameters.toolchain.commandLineForSwiftCompilation(fileSystem: fileSystem)

result.append("-module-name")
result.append(target.c99name)
Expand Down Expand Up @@ -1053,8 +1051,7 @@ public final class SwiftTargetBuildDescription {
throw InternalError("expecting emitSwiftModuleSeparately in build parameters")
}

var result: [String] = []
result.append(buildParameters.toolchain.swiftCompilerPath.pathString)
var result: [String] = buildParameters.toolchain.commandLineForSwiftCompilation(fileSystem: fileSystem)

result.append("-module-name")
result.append(target.c99name)
Expand Down
7 changes: 7 additions & 0 deletions Sources/Build/LLBuildManifestBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,13 @@ extension LLBuildManifestBuilder {
let isLibrary = target.target.type == .library || target.target.type == .test
let cmdName = target.target.getCommandName(config: buildConfig)

let commandLine = buildParameters.toolchain.commandLineForSwiftCompilation(fileSystem: fileSystem)
guard let first = commandLine.first, let executable = try? AbsolutePath(validating: first) else {
throw StringError("empty commandline for Swift compilation")
}

// TODO: `--driver-mode=swiftc` needs to be the first argument, but going through `SwiftCompilerTool` does not allow that
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To fix this we'd need to move off llbuild's built-in tool and instead create a shell command (which is probably better anyway).


manifest.addSwiftCmd(
name: cmdName,
inputs: inputs,
Expand Down
2 changes: 1 addition & 1 deletion Sources/PackageLoading/ManifestLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ public final class ManifestLoader: ManifestLoaderProtocol {
let moduleCachePath = try (ProcessEnv.vars["SWIFTPM_MODULECACHE_OVERRIDE"] ?? ProcessEnv.vars["SWIFTPM_TESTS_MODULECACHE"]).flatMap{ try AbsolutePath(validating: $0) }

var cmd: [String] = []
cmd += [self.toolchain.swiftCompilerPathForManifests.pathString]
cmd += self.toolchain.commandLineForManifestCompilation(fileSystem: localFileSystem)

// if runtimePath is set to "PackageFrameworks" that means we could be developing SwiftPM in Xcode
// which produces a framework for dynamic package products.
Expand Down
20 changes: 20 additions & 0 deletions Sources/PackageModel/Toolchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ public protocol Toolchain {
/// Path of the `swiftc` compiler.
var swiftCompilerPath: AbsolutePath { get }

/// Path of the `swiftc` compiler to use for manifest compilation.
var swiftCompilerPathForManifests: AbsolutePath { get }

/// Path containing the macOS Swift stdlib.
var macosSwiftStdlib: AbsolutePath { get throws }

Expand Down Expand Up @@ -75,4 +78,21 @@ extension Toolchain {
public var extraSwiftCFlags: [String] {
extraFlags.swiftCompilerFlags
}

private static func commandLineForCompilation(compilerPath: AbsolutePath, fileSystem: FileSystem) -> [String] {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: reverse order of arguments

let swiftDriverPath = compilerPath.parentDirectory.appending(component: "swift-driver")
if fileSystem.exists(swiftDriverPath) {
return [swiftDriverPath.pathString, "--driver-mode=swiftc"]
} else {
return [compilerPath.pathString]
}
}

public func commandLineForManifestCompilation(fileSystem: FileSystem) -> [String] {
return Self.commandLineForCompilation(compilerPath: swiftCompilerPathForManifests, fileSystem: fileSystem)
}

public func commandLineForSwiftCompilation(fileSystem: FileSystem) -> [String] {
return Self.commandLineForCompilation(compilerPath: swiftCompilerPath, fileSystem: fileSystem)
}
}
24 changes: 0 additions & 24 deletions Sources/SPMTestSupport/Toolchain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,28 +94,4 @@ extension UserToolchain {
return true
#endif
}

/// Helper function to determine whether serialized diagnostics work properly in the current environment.
public func supportsSerializedDiagnostics(otherSwiftFlags: [String] = []) -> Bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the hope/goal since this was needed because we were using the old driver in CI contexts (which apparently has a bug triggered by some of our tests).

do {
try testWithTemporaryDirectory { tmpPath in
let inputPath = tmpPath.appending(component: "best.swift")
try localFileSystem.writeFileContents(inputPath, string: "func foo() -> Bool {\nvar unused: Int\nreturn true\n}\n")
let outputPath = tmpPath.appending(component: "foo")
let serializedDiagnosticsPath = tmpPath.appending(component: "out.dia")
let toolchainPath = self.swiftCompilerPath.parentDirectory.parentDirectory
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)
try Process.checkNonZeroExit(arguments: [outputPath.pathString])

let diaFileContents = try localFileSystem.readFileContents(serializedDiagnosticsPath)
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
if diagnosticsSet.diagnostics.isEmpty {
throw StringError("does not support diagnostics")
}
}
return true
} catch {
return false
}
}
}
4 changes: 2 additions & 2 deletions Sources/Workspace/DefaultPluginScriptRunner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ public struct DefaultPluginScriptRunner: PluginScriptRunner, Cancellable {
// FIXME: Much of this is similar to what the ManifestLoader is doing. This should be consolidated.

// We use the toolchain's Swift compiler for compiling the plugin.
var commandLine = [self.toolchain.swiftCompilerPathForManifests.pathString]
var commandLine = self.toolchain.commandLineForManifestCompilation(fileSystem: fileSystem)

observabilityScope.emit(debug: "Using compiler \(self.toolchain.swiftCompilerPathForManifests.pathString)")
observabilityScope.emit(debug: "Using compiler command line: \(commandLine)")

// Get access to the path containing the PackagePlugin module and library.
let pluginLibraryPath = self.toolchain.swiftPMLibrariesLocation.pluginLibraryPath
Expand Down
1 change: 1 addition & 0 deletions Tests/BuildTests/MockBuildTestHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct MockToolchain: PackageModel.Toolchain {
let librarianPath = AbsolutePath(path: "/fake/path/to/ar")
#endif
let swiftCompilerPath = AbsolutePath(path: "/fake/path/to/swiftc")
let swiftCompilerPathForManifests = AbsolutePath(path: "/fake/path/to/swiftc")

#if os(macOS)
let extraFlags = BuildFlags(cxxCompilerFlags: ["-lc++"])
Expand Down
28 changes: 12 additions & 16 deletions Tests/SPMBuildCoreTests/PluginInvocationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,12 @@ class PluginInvocationTests: XCTestCase {
XCTAssertEqual(delegate.compiledResult, result)
XCTAssertNil(delegate.cachedResult)

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

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

if try UserToolchain.default.supportsSerializedDiagnostics() {
// Check that the diagnostics still have the same warning as before.
let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile)
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
XCTAssertEqual(diagnosticsSet.diagnostics.count, 1)
let warningDiagnostic = try XCTUnwrap(diagnosticsSet.diagnostics.first)
XCTAssertTrue(warningDiagnostic.text.hasPrefix("variable \'unused\' was never used"), "\(warningDiagnostic)")
}
// Check that the diagnostics still have the same warning as before.
let diaFileContents = try localFileSystem.readFileContents(result.diagnosticsFile)
let diagnosticsSet = try SerializedDiagnostics(bytes: diaFileContents)
XCTAssertEqual(diagnosticsSet.diagnostics.count, 1)
let warningDiagnostic = try XCTUnwrap(diagnosticsSet.diagnostics.first)
XCTAssertTrue(warningDiagnostic.text.hasPrefix("variable \'unused\' was never used"), "\(warningDiagnostic)")

// Check that the executable file exists.
XCTAssertTrue(localFileSystem.exists(result.executableFile), "\(result.executableFile.pathString)")
Expand Down
3 changes: 3 additions & 0 deletions Utilities/bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,9 @@ def build_swiftpm_with_swiftpm(args, integrated_swift_driver):
symlink_force(args.swiftc_path, os.path.join(args.target_dir, args.conf, "swift"))
symlink_force(args.swiftc_path, os.path.join(args.target_dir, args.conf, "swift-autolink-extract"))

# Symlink swift-driver built by CMake into the "fake" toolchain
symlink_force(os.path.join(args.bootstrap_dir, "..", "swift-driver", "bin", "swift-driver"), os.path.join(args.target_dir, args.conf, "swift-driver"))

lib_dir = os.path.join(args.target_dir, "lib", "swift")

# Remove old cruft.
Expand Down