Skip to content

Commit 93b9142

Browse files
authored
Merge pull request #2946 from owenv/driver-library-split
Replace SwiftDriverExecutor with SPMSwiftDriverExecutor
2 parents 7afc6e2 + 2248570 commit 93b9142

File tree

3 files changed

+101
-11
lines changed

3 files changed

+101
-11
lines changed

Sources/Build/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_library(Build
1111
BuildOperation.swift
1212
BuildPlan.swift
1313
ManifestBuilder.swift
14+
SPMSwiftDriverExecutor.swift
1415
SwiftCompilerOutputParser.swift
1516
XCFrameworkInfo.swift)
1617
target_link_libraries(Build PUBLIC

Sources/Build/ManifestBuilder.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,24 +220,24 @@ extension LLBuildManifestBuilder {
220220
commandLine.append(buildParameters.toolchain.swiftCompiler.pathString)
221221
// FIXME: At some point SwiftPM should provide its own executor for
222222
// running jobs/launching processes during planning
223-
let executor = try SwiftDriverExecutor(diagnosticsEngine: plan.diagnostics,
224-
processSet: ProcessSet(),
225-
fileSystem: target.fs,
226-
env: ProcessEnv.vars)
223+
let resolver = try ArgsResolver(fileSystem: target.fs)
224+
let executor = SPMSwiftDriverExecutor(resolver: resolver,
225+
fileSystem: target.fs,
226+
env: ProcessEnv.vars)
227227
var driver = try Driver(args: commandLine,
228228
diagnosticsEngine: plan.diagnostics,
229229
fileSystem: target.fs,
230230
executor: executor)
231231
let jobs = try driver.planBuild()
232-
try addSwiftDriverJobs(for: target, jobs: jobs, inputs: inputs,
232+
try addSwiftDriverJobs(for: target, jobs: jobs, inputs: inputs, resolver: resolver,
233233
isMainModule: { driver.isExplicitMainModuleJob(job: $0)})
234234
}
235235

236236
private func addSwiftDriverJobs(for targetDescription: SwiftTargetBuildDescription,
237237
jobs: [Job], inputs: [Node],
238+
resolver: ArgsResolver,
238239
isMainModule: (Job) -> Bool) throws {
239240
// Add build jobs to the manifest
240-
let resolver = try ArgsResolver(fileSystem: targetDescription.fs)
241241
for job in jobs {
242242
let tool = try resolver.resolve(.path(job.tool))
243243
let commandLine = try job.commandLine.map{ try resolver.resolve($0) }
@@ -386,10 +386,10 @@ extension LLBuildManifestBuilder {
386386
commandLine.append("-experimental-explicit-module-build")
387387
// FIXME: At some point SwiftPM should provide its own executor for
388388
// running jobs/launching processes during planning
389-
let executor = try SwiftDriverExecutor(diagnosticsEngine: plan.diagnostics,
390-
processSet: ProcessSet(),
391-
fileSystem: targetDescription.fs,
392-
env: ProcessEnv.vars)
389+
let resolver = try ArgsResolver(fileSystem: targetDescription.fs)
390+
let executor = SPMSwiftDriverExecutor(resolver: resolver,
391+
fileSystem: targetDescription.fs,
392+
env: ProcessEnv.vars)
393393
var driver = try Driver(args: commandLine, fileSystem: targetDescription.fs,
394394
executor: executor,
395395
externalModuleDependencies: targetDependencyMap)
@@ -401,7 +401,7 @@ extension LLBuildManifestBuilder {
401401
fatalError("Expected module dependency graph for target: \(targetDescription)")
402402
}
403403
targetDepGraphMap[targetDescription.target] = dependencyGraph
404-
try addSwiftDriverJobs(for: targetDescription, jobs: jobs, inputs: inputs,
404+
try addSwiftDriverJobs(for: targetDescription, jobs: jobs, inputs: inputs, resolver: resolver,
405405
isMainModule: { driver.isExplicitMainModuleJob(job: $0)})
406406
}
407407

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright 2020 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
@_implementationOnly import SwiftDriver
12+
import TSCBasic
13+
import Foundation
14+
15+
final class SPMSwiftDriverExecutor: DriverExecutor {
16+
17+
private enum Error: Swift.Error, DiagnosticData {
18+
case inPlaceExecutionUnsupported
19+
20+
var description: String {
21+
switch self {
22+
case .inPlaceExecutionUnsupported:
23+
return "the integrated Swift driver does not support in-place execution"
24+
}
25+
}
26+
}
27+
28+
let resolver: ArgsResolver
29+
let fileSystem: FileSystem
30+
let env: [String: String]
31+
32+
init(resolver: ArgsResolver,
33+
fileSystem: FileSystem,
34+
env: [String: String]) {
35+
self.resolver = resolver
36+
self.fileSystem = fileSystem
37+
self.env = env
38+
}
39+
40+
func execute(job: Job,
41+
forceResponseFiles: Bool,
42+
recordedInputModificationDates: [TypedVirtualPath : Date]) throws -> ProcessResult {
43+
let arguments: [String] = try resolver.resolveArgumentList(for: job,
44+
forceResponseFiles: forceResponseFiles)
45+
46+
try job.verifyInputsNotModified(since: recordedInputModificationDates,
47+
fileSystem: fileSystem)
48+
49+
if job.requiresInPlaceExecution {
50+
throw Error.inPlaceExecutionUnsupported
51+
}
52+
53+
var childEnv = env
54+
childEnv.merge(job.extraEnvironment, uniquingKeysWith: { (_, new) in new })
55+
56+
let process = try Process.launchProcess(arguments: arguments, env: childEnv)
57+
return try process.waitUntilExit()
58+
}
59+
60+
func execute(jobs: [Job], delegate: JobExecutionDelegate,
61+
numParallelJobs: Int, forceResponseFiles: Bool,
62+
recordedInputModificationDates: [TypedVirtualPath : Date]) throws {
63+
fatalError("Multi-job build plans should be lifted into the SPM build graph.")
64+
}
65+
66+
func checkNonZeroExit(args: String..., environment: [String : String]) throws -> String {
67+
return try Process.checkNonZeroExit(arguments: args, environment: environment)
68+
}
69+
70+
func description(of job: Job, forceResponseFiles: Bool) throws -> String {
71+
// FIXME: This is duplicated from SwiftDriver, maybe it shouldn't be a protocol requirement.
72+
let (args, usedResponseFile) = try resolver.resolveArgumentList(for: job,
73+
forceResponseFiles: forceResponseFiles)
74+
var result = args.joined(separator: " ")
75+
76+
if usedResponseFile {
77+
// Print the response file arguments as a comment.
78+
result += " # \(job.commandLine.joinedArguments)"
79+
}
80+
81+
if !job.extraEnvironment.isEmpty {
82+
result += " #"
83+
for (envVar, val) in job.extraEnvironment {
84+
result += " \(envVar)=\(val)"
85+
}
86+
}
87+
return result
88+
}
89+
}

0 commit comments

Comments
 (0)