-
Notifications
You must be signed in to change notification settings - Fork 216
[Incremental] stop if no -driver-continue-building-after-errors #387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -87,6 +87,12 @@ public final class MultiJobExecutor { | |
| /// any newly-required job. Set only once. | ||
| private(set) var executeAllJobsTaskBuildEngine: LLTaskBuildEngine? = nil | ||
|
|
||
| /// If a job fails, the driver needs to stop running jobs. | ||
| private(set) var isBuildCancelled = false | ||
|
|
||
| /// The value of the option | ||
| let continueBuildingAfterErrors: Bool | ||
|
|
||
|
|
||
| init( | ||
| argsResolver: ArgsResolver, | ||
|
|
@@ -106,7 +112,8 @@ public final class MultiJobExecutor { | |
| producerMap: self.producerMap, | ||
| primaryIndices: self.primaryIndices, | ||
| postCompileIndices: self.postCompileIndices, | ||
| incrementalCompilationState: self.incrementalCompilationState | ||
| incrementalCompilationState: self.incrementalCompilationState, | ||
| continueBuildingAfterErrors: self.continueBuildingAfterErrors | ||
| ) = Self.fillInJobsAndProducers(workload) | ||
|
|
||
| self.argsResolver = argsResolver | ||
|
|
@@ -131,20 +138,21 @@ public final class MultiJobExecutor { | |
| producerMap: [VirtualPath: Int], | ||
| primaryIndices: Range<Int>, | ||
| postCompileIndices: Range<Int>, | ||
| incrementalCompilationState: IncrementalCompilationState?) | ||
| incrementalCompilationState: IncrementalCompilationState?, | ||
| continueBuildingAfterErrors: Bool) | ||
| { | ||
| var jobs = [Job]() | ||
| var producerMap = [VirtualPath: Int]() | ||
| let primaryIndices, postCompileIndices: Range<Int> | ||
| let incrementalCompilationState: IncrementalCompilationState? | ||
| switch workload { | ||
| switch workload.kind { | ||
| case let .incremental(ics): | ||
| incrementalCompilationState = ics | ||
| primaryIndices = Self.addJobs( | ||
| ics.mandatoryPreOrCompileJobsInOrder, | ||
| to: &jobs, | ||
| producing: &producerMap | ||
| ) | ||
| ) | ||
| postCompileIndices = Self.addJobs( | ||
| ics.postCompileJobs, | ||
| to: &jobs, | ||
|
|
@@ -161,7 +169,8 @@ public final class MultiJobExecutor { | |
| producerMap: producerMap, | ||
| primaryIndices: primaryIndices, | ||
| postCompileIndices: postCompileIndices, | ||
| incrementalCompilationState: incrementalCompilationState) | ||
| incrementalCompilationState: incrementalCompilationState, | ||
| continueBuildingAfterErrors: workload.continueBuildingAfterErrors) | ||
| } | ||
|
|
||
| /// Allow for dynamically adding jobs, since some compile jobs are added dynamically. | ||
|
|
@@ -225,6 +234,19 @@ public final class MultiJobExecutor { | |
| executeAllJobsTaskBuildEngine!.taskNeedsInput(key, inputID: index) | ||
| } | ||
| } | ||
|
|
||
| fileprivate func cancelBuildIfNeeded(_ result: ProcessResult) { | ||
| switch (result.exitStatus, continueBuildingAfterErrors) { | ||
| case (.terminated(let code), false) where code != EXIT_SUCCESS: | ||
| isBuildCancelled = true | ||
| #if !os(Windows) | ||
| case (.signalled, _): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing this is more correct than in my solution where I used result.success as the flag and never considered if the failure was due to a signal or not.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks! |
||
| isBuildCancelled = true | ||
| #endif | ||
| default: | ||
| break | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// The work to be done. | ||
|
|
@@ -426,8 +448,8 @@ class ExecuteJobRule: LLBuildRule { | |
| rememberIfInputSucceeded(engine, value: value) | ||
| } | ||
|
|
||
| /// Called when the build engine thinks all inputs are available in order to run the job. | ||
| override func inputsAvailable(_ engine: LLTaskBuildEngine) { | ||
| // Return early any of the input failed. | ||
| guard allInputsSucceeded else { | ||
| return engine.taskIsComplete(DriverBuildValue.jobExecution(success: false)) | ||
| } | ||
|
|
@@ -464,6 +486,10 @@ class ExecuteJobRule: LLBuildRule { | |
| } | ||
|
|
||
| private func executeJob(_ engine: LLTaskBuildEngine) { | ||
| if context.isBuildCancelled { | ||
| engine.taskIsComplete(DriverBuildValue.jobExecution(success: false)) | ||
| return | ||
| } | ||
| let context = self.context | ||
| let resolver = context.argsResolver | ||
| let job = myJob | ||
|
|
@@ -514,6 +540,8 @@ class ExecuteJobRule: LLBuildRule { | |
| context.executorDelegate.jobFinished(job: job, result: result, pid: pid) | ||
| } | ||
| value = .jobExecution(success: success) | ||
|
|
||
| context.cancelBuildIfNeeded(result) | ||
| } catch { | ||
| if error is DiagnosticData { | ||
| context.diagnosticsEngine.emit(error) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do like this better, from a SPM compatibility perspective.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!