Skip to content

Commit 7bdf134

Browse files
compnerdtomerd
andauthored
Build: adjust the BuildSystemDelegate hander
llbuild does not make guarantees that the output from subcommands are emitted in complete buffers. This shows up particularly well on Windows. clang will emit diagnostics which get read in different chunks. By emitting these eagerly we would print partial messages which would leave the terminal in the improper state due to the message not being complete. With multiple parallel threads writing the messages partially, we would get splits in the message that would yield unreadable messages. Switch to a buffering approach, buffering the entire content until the command exits. At that time we can emit the complete message in a "single" write (which is locked). This ensures that the output is no longer partially emitted and corrects the rendering with the animated emission on Windows. Co-authored-by: tomer doron <[email protected]>
1 parent 434b2b2 commit 7bdf134

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ final class BuildOperationBuildSystemDelegateHandler: LLBuildBuildSystemDelegate
410410
/// Swift parsers keyed by llbuild command name.
411411
private var swiftParsers: [String: SwiftCompilerOutputParser] = [:]
412412

413+
/// Buffer to accumulate non-swift output until command is finished
414+
private var nonSwiftMessageBuffers: [String: [UInt8]] = [:]
415+
413416
/// The build execution context.
414417
private let buildExecutionContext: BuildExecutionContext
415418

@@ -566,9 +569,7 @@ final class BuildOperationBuildSystemDelegateHandler: LLBuildBuildSystemDelegate
566569
swiftParser.parse(bytes: data)
567570
} else {
568571
queue.async {
569-
self.progressAnimation.clear()
570-
self.outputStream <<< data
571-
self.outputStream.flush()
572+
self.nonSwiftMessageBuffers[command.name, default: []] += data
572573
}
573574
}
574575
}
@@ -578,6 +579,14 @@ final class BuildOperationBuildSystemDelegateHandler: LLBuildBuildSystemDelegate
578579
process: ProcessHandle,
579580
result: CommandExtendedResult
580581
) {
582+
if let buffer = self.nonSwiftMessageBuffers[command.name] {
583+
queue.async {
584+
self.progressAnimation.clear()
585+
self.outputStream <<< buffer
586+
self.outputStream.flush()
587+
self.nonSwiftMessageBuffers[command.name] = nil
588+
}
589+
}
581590
if result.result == .failed {
582591
// The command failed, so we queue up an asynchronous task to see if we have any error messages from the target to provide advice about.
583592
queue.async {

0 commit comments

Comments
 (0)