@@ -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 isBuildCancelled = 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 cancelBuildIfNeeded( _ result: ProcessResult ) {
239+ switch ( result. exitStatus, continueBuildingAfterErrors) {
240+ case ( . terminated( let code) , false ) where code != EXIT_SUCCESS:
241+ isBuildCancelled = true
242+ #if !os(Windows)
243+ case ( . signalled, _) :
244+ isBuildCancelled = true
245+ #endif
246+ default :
247+ break
248+ }
249+ }
228250 }
229251
230252 /// The work to be done.
@@ -426,8 +448,8 @@ class ExecuteJobRule: LLBuildRule {
426448 rememberIfInputSucceeded ( engine, value: value)
427449 }
428450
451+ /// Called when the build engine thinks all inputs are available in order to run the job.
429452 override func inputsAvailable( _ engine: LLTaskBuildEngine ) {
430- // Return early any of the input failed.
431453 guard allInputsSucceeded else {
432454 return engine. taskIsComplete ( DriverBuildValue . jobExecution ( success: false ) )
433455 }
@@ -464,6 +486,10 @@ class ExecuteJobRule: LLBuildRule {
464486 }
465487
466488 private func executeJob( _ engine: LLTaskBuildEngine ) {
489+ if context. isBuildCancelled {
490+ engine. taskIsComplete ( DriverBuildValue . jobExecution ( success: false ) )
491+ return
492+ }
467493 let context = self . context
468494 let resolver = context. argsResolver
469495 let job = myJob
@@ -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. cancelBuildIfNeeded ( result)
517545 } catch {
518546 if error is DiagnosticData {
519547 context. diagnosticsEngine. emit ( error)
0 commit comments