Skip to content

Commit 32ac44e

Browse files
author
David Ungar
committed
honor !-driver-continue-building-after-errors
1 parent 8101d69 commit 32ac44e

File tree

3 files changed

+64
-17
lines changed

3 files changed

+64
-17
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -859,12 +859,14 @@ extension Driver {
859859
recordedInputModificationDates: recordedInputModificationDates)
860860
return
861861
}
862-
863-
try performTheBuild(allJobs: jobs, forceResponseFiles: forceResponseFiles)
864-
865-
buildRecordInfo?.writeBuildRecord(
866-
jobs,
867-
incrementalCompilationState?.skippedCompilationInputs)
862+
do {
863+
defer {
864+
buildRecordInfo?.writeBuildRecord(
865+
jobs,
866+
incrementalCompilationState?.skippedCompilationInputs)
867+
}
868+
try performTheBuild(allJobs: jobs, forceResponseFiles: forceResponseFiles)
869+
}
868870

869871
// If requested, warn for options that weren't used by the driver after the build is finished.
870872
if parsedOptions.hasArgument(.driverWarnUnusedOptions) {
@@ -896,8 +898,11 @@ extension Driver {
896898
allJobs: [Job],
897899
forceResponseFiles: Bool
898900
) throws {
901+
let continueBuildingAfterErrors = parsedOptions.contains(.continueBuildingAfterErrors)
899902
try executor.execute(
900-
workload: .init(allJobs, incrementalCompilationState),
903+
workload: .init(allJobs,
904+
incrementalCompilationState,
905+
continueBuildingAfterErrors: continueBuildingAfterErrors),
901906
delegate: createToolExecutionDelegate(),
902907
numParallelJobs: numParallelJobs ?? 1,
903908
forceResponseFiles: forceResponseFiles,

Sources/SwiftDriver/Execution/DriverExecutor.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,26 @@ public protocol DriverExecutor {
4747
func description(of job: Job, forceResponseFiles: Bool) throws -> String
4848
}
4949

50-
public enum DriverExecutorWorkload {
51-
case all([Job])
52-
case incremental(IncrementalCompilationState)
50+
public struct DriverExecutorWorkload {
51+
public let continueBuildingAfterErrors: Bool
52+
public enum Kind {
53+
case all([Job])
54+
case incremental(IncrementalCompilationState)
55+
}
56+
public let kind: Kind
57+
58+
public init(_ allJobs: [Job],
59+
_ incrementalCompilationState: IncrementalCompilationState?,
60+
continueBuildingAfterErrors: Bool
61+
) {
62+
self.continueBuildingAfterErrors = continueBuildingAfterErrors
63+
self.kind = incrementalCompilationState
64+
.map {.incremental($0)}
65+
?? .all(allJobs)
66+
}
5367

54-
init(_ allJobs: [Job], _ incrementalCompilationState: IncrementalCompilationState?) {
55-
self = incrementalCompilationState.map {.incremental($0)} ?? .all(allJobs)
68+
static public func all(_ jobs: [Job]) -> Self {
69+
.init(jobs, nil, continueBuildingAfterErrors: false)
5670
}
5771
}
5872

Sources/SwiftDriverExecution/MultiJobExecutor.swift

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ public final class MultiJobExecutor {
8787
/// any newly-required job. Set only once.
8888
private(set) var executeAllJobsTaskBuildEngine: LLTaskBuildEngine? = nil
8989

90+
/// If a job fails, the driver needs to stop running jobs.
91+
private(set) var shouldStopRunningJobs = false
92+
93+
/// The value of the option
94+
let continueBuildingAfterErrors: Bool
95+
9096

9197
init(
9298
argsResolver: ArgsResolver,
@@ -106,7 +112,8 @@ public final class MultiJobExecutor {
106112
producerMap: self.producerMap,
107113
primaryIndices: self.primaryIndices,
108114
postCompileIndices: self.postCompileIndices,
109-
incrementalCompilationState: self.incrementalCompilationState
115+
incrementalCompilationState: self.incrementalCompilationState,
116+
continueBuildingAfterErrors: self.continueBuildingAfterErrors
110117
) = Self.fillInJobsAndProducers(workload)
111118

112119
self.argsResolver = argsResolver
@@ -131,20 +138,21 @@ public final class MultiJobExecutor {
131138
producerMap: [VirtualPath: Int],
132139
primaryIndices: Range<Int>,
133140
postCompileIndices: Range<Int>,
134-
incrementalCompilationState: IncrementalCompilationState?)
141+
incrementalCompilationState: IncrementalCompilationState?,
142+
continueBuildingAfterErrors: Bool)
135143
{
136144
var jobs = [Job]()
137145
var producerMap = [VirtualPath: Int]()
138146
let primaryIndices, postCompileIndices: Range<Int>
139147
let incrementalCompilationState: IncrementalCompilationState?
140-
switch workload {
148+
switch workload.kind {
141149
case let .incremental(ics):
142150
incrementalCompilationState = ics
143151
primaryIndices = Self.addJobs(
144152
ics.mandatoryPreOrCompileJobsInOrder,
145153
to: &jobs,
146154
producing: &producerMap
147-
)
155+
)
148156
postCompileIndices = Self.addJobs(
149157
ics.postCompileJobs,
150158
to: &jobs,
@@ -161,7 +169,8 @@ public final class MultiJobExecutor {
161169
producerMap: producerMap,
162170
primaryIndices: primaryIndices,
163171
postCompileIndices: postCompileIndices,
164-
incrementalCompilationState: incrementalCompilationState)
172+
incrementalCompilationState: incrementalCompilationState,
173+
continueBuildingAfterErrors: workload.continueBuildingAfterErrors)
165174
}
166175

167176
/// Allow for dynamically adding jobs, since some compile jobs are added dynamically.
@@ -225,6 +234,19 @@ public final class MultiJobExecutor {
225234
executeAllJobsTaskBuildEngine!.taskNeedsInput(key, inputID: index)
226235
}
227236
}
237+
238+
fileprivate func decideIfShouldStopRunningJobs(_ result: ProcessResult) {
239+
switch (result.exitStatus, continueBuildingAfterErrors) {
240+
case (.terminated(let code), false) where code != EXIT_SUCCESS:
241+
shouldStopRunningJobs = true
242+
#if !os(Windows)
243+
case (.signalled, _):
244+
shouldStopRunningJobs = true
245+
#endif
246+
default:
247+
break
248+
}
249+
}
228250
}
229251

230252
/// The work to be done.
@@ -472,6 +494,10 @@ class ExecuteJobRule: LLBuildRule {
472494
let value: DriverBuildValue
473495
var pid = 0
474496
do {
497+
if context.shouldStopRunningJobs {
498+
engine.taskIsComplete(DriverBuildValue.jobExecution(success: false))
499+
return
500+
}
475501
let arguments: [String] = try resolver.resolveArgumentList(for: job,
476502
forceResponseFiles: context.forceResponseFiles)
477503

@@ -514,6 +540,8 @@ class ExecuteJobRule: LLBuildRule {
514540
context.executorDelegate.jobFinished(job: job, result: result, pid: pid)
515541
}
516542
value = .jobExecution(success: success)
543+
544+
context.decideIfShouldStopRunningJobs(result)
517545
} catch {
518546
if error is DiagnosticData {
519547
context.diagnosticsEngine.emit(error)

0 commit comments

Comments
 (0)