Skip to content

Commit 0500996

Browse files
committed
Still emit per-task C diagnostics if errors are requested
We want to group diagnostics to avoid duplicates, but also avoid building the entire target if we already know about errors. So for C compiles specifically, we'll continue emitting diagnostics per-task if errors are enabled. Additionally, this PR fixes up the signature data related to dependency diagnostics. The `ValidateDependencies` task needs to depend on the `MODULE_DEPENDENCIES` build setting, but the Swift planning task shouldn't anymore. For Clang tasks, this is now also dependent on whether errors are enabled or not.
1 parent db3a4e3 commit 0500996

File tree

7 files changed

+61
-29
lines changed

7 files changed

+61
-29
lines changed

Sources/SWBBuildSystem/BuildOperation.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,10 @@ extension BuildOperation: TaskExecutionDelegate {
10021002
package var emitFrontendCommandLines: Bool {
10031003
buildDescription.emitFrontendCommandLines
10041004
}
1005+
1006+
package var continueBuildingAfterErrors: Bool {
1007+
request.continueBuildingAfterErrors
1008+
}
10051009
}
10061010

10071011
// BuildOperation uses reference semantics.

Sources/SWBCore/SpecImplementations/Tools/CCompiler.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,8 @@ public class ClangCompilerSpec : CompilerSpec, SpecIdentifierType, GCCCompatible
13681368
extraInputs = []
13691369
}
13701370

1371-
if let moduleDependenciesContext {
1371+
// If validation is set to `YES_ERROR`, individual Clang tasks emit diagnostics, so they need this data in their signature. Otherwise, diagnostics are handled by the per-target validation action so individual compiles are not affected by changes to validation-related build settings.
1372+
if let moduleDependenciesContext, moduleDependenciesContext.validate == .yesError {
13721373
do {
13731374
let jsonData = try JSONEncoder(outputFormatting: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]).encode(moduleDependenciesContext)
13741375
guard let signature = String(data: jsonData, encoding: .utf8) else {

Sources/SWBCore/SpecImplementations/Tools/SwiftCompiler.swift

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,25 +2405,8 @@ public final class SwiftCompilerSpec : CompilerSpec, SpecIdentifierType, SwiftDi
24052405
dependencyData = nil
24062406
}
24072407

2408-
let compilationRequirementAdditionalSignatureData: String
2409-
if let moduleDependenciesContext = cbc.producer.moduleDependenciesContext {
2410-
do {
2411-
let jsonData = try JSONEncoder(outputFormatting: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]).encode(moduleDependenciesContext)
2412-
guard let signature = String(data: jsonData, encoding: .utf8) else {
2413-
throw StubError.error("non-UTF-8 data")
2414-
}
2415-
compilationRequirementAdditionalSignatureData = additionalSignatureData + "|\(signature)"
2416-
} catch {
2417-
delegate.error("failed to serialize 'MODULE_DEPENDENCIES' context information: \(error)")
2418-
return
2419-
}
2420-
}
2421-
else {
2422-
compilationRequirementAdditionalSignatureData = additionalSignatureData
2423-
}
2424-
24252408
// Compilation Requirements
2426-
delegate.createTask(type: self, dependencyData: dependencyData, payload: payload, ruleInfo: ruleInfo("SwiftDriver Compilation Requirements", targetName), additionalSignatureData: compilationRequirementAdditionalSignatureData, commandLine: ["builtin-Swift-Compilation-Requirements", "--"] + args, environment: environmentBindings, workingDirectory: compilerWorkingDirectory(cbc), inputs: allInputsNodes, outputs: compilationRequirementOutputs, action: delegate.taskActionCreationDelegate.createSwiftCompilationRequirementTaskAction(), execDescription: archSpecificExecutionDescription(cbc.scope.namespace.parseString("Unblock downstream dependents of $PRODUCT_NAME"), cbc, delegate), preparesForIndexing: true, enableSandboxing: enableSandboxing, additionalTaskOrderingOptions: [.compilation, .compilationRequirement, .linkingRequirement, .blockedByTargetHeaders, .compilationForIndexableSourceFile], usesExecutionInputs: true, showInLog: true)
2409+
delegate.createTask(type: self, dependencyData: dependencyData, payload: payload, ruleInfo: ruleInfo("SwiftDriver Compilation Requirements", targetName), additionalSignatureData: additionalSignatureData, commandLine: ["builtin-Swift-Compilation-Requirements", "--"] + args, environment: environmentBindings, workingDirectory: compilerWorkingDirectory(cbc), inputs: allInputsNodes, outputs: compilationRequirementOutputs, action: delegate.taskActionCreationDelegate.createSwiftCompilationRequirementTaskAction(), execDescription: archSpecificExecutionDescription(cbc.scope.namespace.parseString("Unblock downstream dependents of $PRODUCT_NAME"), cbc, delegate), preparesForIndexing: true, enableSandboxing: enableSandboxing, additionalTaskOrderingOptions: [.compilation, .compilationRequirement, .linkingRequirement, .blockedByTargetHeaders, .compilationForIndexableSourceFile], usesExecutionInputs: true, showInLog: true)
24272410

24282411
if case .compile = compilationMode {
24292412
// Unblocking compilation

Sources/SWBCore/SpecImplementations/Tools/ValidateDependencies.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
private import Foundation
1314
public import SWBUtil
1415
import SWBMacro
1516

@@ -39,8 +40,21 @@ public final class ValidateDependenciesSpec: CommandLineToolSpec, SpecImplementa
3940
guard let configuredTarget = cbc.producer.configuredTarget else {
4041
return
4142
}
43+
44+
let jsonData: Data
45+
do {
46+
jsonData = try JSONEncoder(outputFormatting: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes]).encode(payload)
47+
} catch {
48+
delegate.error("Error serializing \(payload): \(error)")
49+
return
50+
}
51+
guard let signature = String(data: jsonData, encoding: .utf8) else {
52+
delegate.error("non-UTF-8 data in signature for ValidateDependencies")
53+
return
54+
}
55+
4256
let output = delegate.createVirtualNode("ValidateDependencies \(configuredTarget.guid)")
43-
delegate.createTask(type: self, payload: payload, ruleInfo: ["ValidateDependencies"], commandLine: ["builtin-validate-dependencies"] + dependencyInfos.map { $0.path.str }, environment: EnvironmentBindings(), workingDirectory: cbc.producer.defaultWorkingDirectory, inputs: dependencyInfos + cbc.commandOrderingInputs, outputs: [output], action: delegate.taskActionCreationDelegate.createValidateDependenciesTaskAction(), preparesForIndexing: false, enableSandboxing: false)
57+
delegate.createTask(type: self, payload: payload, ruleInfo: ["ValidateDependencies"], additionalSignatureData: signature, commandLine: ["builtin-validate-dependencies"] + dependencyInfos.map { $0.path.str }, environment: EnvironmentBindings(), workingDirectory: cbc.producer.defaultWorkingDirectory, inputs: dependencyInfos + cbc.commandOrderingInputs, outputs: [output], action: delegate.taskActionCreationDelegate.createValidateDependenciesTaskAction(), preparesForIndexing: false, enableSandboxing: false)
4458
}
4559
}
4660

Sources/SWBTaskExecution/Task.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,8 @@ public protocol TaskExecutionDelegate
583583

584584
var namespace: MacroNamespace { get }
585585

586+
var continueBuildingAfterErrors: Bool { get }
587+
586588
/// Notifies the delegate that this task has discovered a target dependency which must exist to ensure deterministic builds.
587589
func taskDiscoveredRequiredTargetDependency(target: ConfiguredTarget, antecedent: ConfiguredTarget, reason: RequiredTargetDependencyReason, warningLevel: BooleanWarningLevel)
588590
}

Sources/SWBTaskExecution/TaskActions/ClangCompileTaskAction.swift

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,20 @@ public final class ClangCompileTaskAction: TaskAction, BuildValueValidatingTaskA
261261
moduleDependenciesContext = nil
262262
dependencyValidationOutputPath = nil
263263
}
264+
265+
// Emit per-task diagnostics if validation is set to `YES_ERROR` and we're not continuing to build after errors.
266+
let moduleDependenciesEmitPerTaskDiagnostics = moduleDependenciesContext?.validate == .yesError && !executionDelegate.continueBuildingAfterErrors
267+
if moduleDependenciesEmitPerTaskDiagnostics, let dependencyValidationOutputPath {
268+
// Since we're emitting per task diagnostics, communicate empty diagnostics to the validation task.
269+
let validationInfo = DependencyValidationInfo(payload: .clangDependencies(files: []))
270+
_ = try executionDelegate.fs.writeIfChanged(
271+
dependencyValidationOutputPath,
272+
contents: ByteString(
273+
JSONEncoder(outputFormatting: .sortedKeys).encode(validationInfo)
274+
)
275+
)
276+
}
277+
264278
if let traceFilePath {
265279
// Remove the trace output file if it already exists.
266280
if executionDelegate.fs.exists(traceFilePath) {
@@ -325,28 +339,41 @@ public final class ClangCompileTaskAction: TaskAction, BuildValueValidatingTaskA
325339
}
326340
}
327341

328-
if lastResult == .succeeded {
342+
if lastResult == .succeeded, let moduleDependenciesContext {
329343
// Verify the dependencies from the trace data.
330344
let payload: DependencyValidationInfo.Payload
345+
var allFiles = Set<Path>()
331346
if let traceFilePath {
332347
let fs = executionDelegate.fs
333348
let traceData = try JSONDecoder().decode(Array<TraceData>.self, from: Data(fs.read(traceFilePath)))
334349

335-
var allFiles = Set<Path>()
336350
traceData.forEach { allFiles.formUnion(Set($0.includes)) }
337351
payload = .clangDependencies(files: allFiles.map { $0.str })
338352
} else {
339353
payload = .unsupported
340354
}
341355

342-
if let dependencyValidationOutputPath {
343-
let validationInfo = DependencyValidationInfo(payload: payload)
344-
_ = try executionDelegate.fs.writeIfChanged(
345-
dependencyValidationOutputPath,
346-
contents: ByteString(
347-
JSONEncoder(outputFormatting: .sortedKeys).encode(validationInfo)
356+
if moduleDependenciesEmitPerTaskDiagnostics {
357+
let missingDeps = moduleDependenciesContext.computeMissingDependencies(files: Array(allFiles))
358+
let diagnostics = moduleDependenciesContext.makeDiagnostics(missingDependencies: missingDeps)
359+
360+
for diagnostic in diagnostics {
361+
outputDelegate.emit(diagnostic)
362+
}
363+
364+
if diagnostics.contains(where: { $0.behavior == .error }) {
365+
return .failed
366+
}
367+
} else {
368+
if let dependencyValidationOutputPath {
369+
let validationInfo = DependencyValidationInfo(payload: payload)
370+
_ = try executionDelegate.fs.writeIfChanged(
371+
dependencyValidationOutputPath,
372+
contents: ByteString(
373+
JSONEncoder(outputFormatting: .sortedKeys).encode(validationInfo)
374+
)
348375
)
349-
)
376+
}
350377
}
351378
}
352379

Tests/SWBTaskExecutionTests/InProcessTaskTestSupport.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct MockExecutionDelegate: TaskExecutionDelegate {
4242
var namespace: MacroNamespace
4343
var requestContext: SWBCore.BuildRequestContext { fatalError() }
4444
var emitFrontendCommandLines: Bool { false }
45+
var continueBuildingAfterErrors: Bool { false }
4546
private var core: Core?
4647

4748
func taskDiscoveredRequiredTargetDependency(target: ConfiguredTarget, antecedent: ConfiguredTarget, reason: RequiredTargetDependencyReason, warningLevel: BooleanWarningLevel) {}

0 commit comments

Comments
 (0)