Skip to content

Commit 5aeca6f

Browse files
authored
Exclude additional directories from VALIDATE_DEPENDENCIES analysis (#348)
rdar://147840711
1 parent cd407fd commit 5aeca6f

File tree

4 files changed

+26
-20
lines changed

4 files changed

+26
-20
lines changed

Sources/SWBTaskExecution/BuildDescription.swift

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ package final class BuildDescription: Serializable, Sendable, Encodable, Cacheab
138138
private let allOutputPaths: Set<Path>
139139

140140
private let rootPathsPerTarget: [ConfiguredTarget: [Path]]
141-
private let moduleCachePathPerTarget: [ConfiguredTarget: Path]
141+
private let moduleCachePathsPerTarget: [ConfiguredTarget: [Path]]
142142

143143
private let dependencyValidationPerTarget: [ConfiguredTarget: BooleanWarningLevel]
144144

@@ -192,13 +192,13 @@ package final class BuildDescription: Serializable, Sendable, Encodable, Cacheab
192192
package let emitFrontendCommandLines: Bool
193193

194194
/// Load a build description from the given path.
195-
fileprivate init(inDir dir: Path, signature: BuildDescriptionSignature, taskStore: FrozenTaskStore, allOutputPaths: Set<Path>, rootPathsPerTarget: [ConfiguredTarget: [Path]], moduleCachePathPerTarget: [ConfiguredTarget: Path], settingsPerTarget: [ConfiguredTarget: Settings], enableStaleFileRemoval: Bool = true, taskActionMap: [String: TaskAction.Type], targetTaskCounts: [ConfiguredTarget: Int], moduleSessionFilePath: Path?, diagnostics: [ConfiguredTarget?: [Diagnostic]], fs: any FSProxy, invalidationPaths: [Path], recursiveSearchPathResults: [RecursiveSearchPathResolver.CachedResult], copiedPathMap: [String: String], targetDependencies: [TargetDependencyRelationship], definingTargetsByModuleName: [String: OrderedSet<ConfiguredTarget>], capturedBuildInfo: CapturedBuildInfo?, bypassActualTasks: Bool, targetsBuildInParallel: Bool, emitFrontendCommandLines: Bool) throws {
195+
fileprivate init(inDir dir: Path, signature: BuildDescriptionSignature, taskStore: FrozenTaskStore, allOutputPaths: Set<Path>, rootPathsPerTarget: [ConfiguredTarget: [Path]], moduleCachePathsPerTarget: [ConfiguredTarget: [Path]], settingsPerTarget: [ConfiguredTarget: Settings], enableStaleFileRemoval: Bool = true, taskActionMap: [String: TaskAction.Type], targetTaskCounts: [ConfiguredTarget: Int], moduleSessionFilePath: Path?, diagnostics: [ConfiguredTarget?: [Diagnostic]], fs: any FSProxy, invalidationPaths: [Path], recursiveSearchPathResults: [RecursiveSearchPathResolver.CachedResult], copiedPathMap: [String: String], targetDependencies: [TargetDependencyRelationship], definingTargetsByModuleName: [String: OrderedSet<ConfiguredTarget>], capturedBuildInfo: CapturedBuildInfo?, bypassActualTasks: Bool, targetsBuildInParallel: Bool, emitFrontendCommandLines: Bool) throws {
196196
self.dir = dir
197197
self.signature = signature
198198
self.taskStore = taskStore
199199
self.allOutputPaths = allOutputPaths
200200
self.rootPathsPerTarget = rootPathsPerTarget
201-
self.moduleCachePathPerTarget = moduleCachePathPerTarget
201+
self.moduleCachePathsPerTarget = moduleCachePathsPerTarget
202202
self.dependencyValidationPerTarget = settingsPerTarget.mapValues { $0.globalScope.evaluate(BuiltinMacros.VALIDATE_DEPENDENCIES) }
203203
self.taskActionMap = taskActionMap
204204
self.targetTaskCounts = targetTaskCounts
@@ -271,8 +271,10 @@ package final class BuildDescription: Serializable, Sendable, Encodable, Cacheab
271271
}
272272

273273
// Only consider paths which _aren't_ in the module cache, which isn't tracked by the build system at present (this may change in future with explicit modules). Normally such paths would be excluded by the root paths check below, but the module cache path may be under one of the other root paths in certain configurations (e.g. overridden SYMROOT).
274-
if moduleCachePathPerTarget[target]?.isAncestor(of: path) == true {
275-
return false
274+
for cachePath in moduleCachePathsPerTarget[target, default: []] {
275+
if cachePath.isAncestor(of: path) == true {
276+
return false
277+
}
276278
}
277279

278280
// Only consider build directories as those which the build system itself has created.
@@ -323,7 +325,7 @@ package final class BuildDescription: Serializable, Sendable, Encodable, Cacheab
323325
// Serialize the tasks first so we can index into this array during deserialization.
324326
serializer.serialize(allOutputPaths)
325327
serializer.serialize(rootPathsPerTarget)
326-
serializer.serialize(moduleCachePathPerTarget)
328+
serializer.serialize(moduleCachePathsPerTarget)
327329
serializer.serialize(dependencyValidationPerTarget)
328330
serializer.beginAggregate(taskActionMap.count)
329331
for (tool, taskActionClass) in taskActionMap.sorted(byKey: <) {
@@ -361,7 +363,7 @@ package final class BuildDescription: Serializable, Sendable, Encodable, Cacheab
361363
self.signature = try deserializer.deserialize()
362364
self.allOutputPaths = try deserializer.deserialize()
363365
self.rootPathsPerTarget = try deserializer.deserialize()
364-
self.moduleCachePathPerTarget = try deserializer.deserialize()
366+
self.moduleCachePathsPerTarget = try deserializer.deserialize()
365367
self.dependencyValidationPerTarget = try deserializer.deserialize()
366368
var taskActionMap = [String: TaskAction.Type]()
367369
let taskActionMapCount = try deserializer.beginAggregate()
@@ -528,7 +530,7 @@ package final class BuildDescriptionBuilder {
528530
private let rootPathsPerTarget: [ConfiguredTarget: [Path]]
529531

530532
// The map of module cache path per configured target.
531-
private let moduleCachePathPerTarget: [ConfiguredTarget: Path]
533+
private let moduleCachePathsPerTarget: [ConfiguredTarget: [Path]]
532534

533535
// The map of stale file removal identifier per configured target.
534536
private let staleFileRemovalIdentifierPerTarget: [ConfiguredTarget?: String]
@@ -547,7 +549,7 @@ package final class BuildDescriptionBuilder {
547549
/// - Parameters:
548550
/// - path: The path of a directory to store the build description to.
549551
/// - bypassActualTasks: If enabled, replace tasks with fake ones (`/usr/bin/true`).
550-
init(path: Path, signature: BuildDescriptionSignature, buildCommand: BuildCommand, taskAdditionalInputs: [Ref<any PlannedTask>: NodeList], mutatedNodes: Set<Ref<any PlannedNode>>, mutatingTasks: [Ref<any PlannedTask>: MutatingTaskInfo], bypassActualTasks: Bool, targetsBuildInParallel: Bool, emitFrontendCommandLines: Bool, moduleSessionFilePath: Path?, invalidationPaths: [Path], recursiveSearchPathResults: [RecursiveSearchPathResolver.CachedResult], copiedPathMap: [String: String], outputPathsPerTarget: [ConfiguredTarget?: [Path]], allOutputPaths: Set<Path>, rootPathsPerTarget: [ConfiguredTarget: [Path]], moduleCachePathPerTarget: [ConfiguredTarget: Path], staleFileRemovalIdentifierPerTarget: [ConfiguredTarget?: String], settingsPerTarget: [ConfiguredTarget: Settings], targetDependencies: [TargetDependencyRelationship], definingTargetsByModuleName: [String: OrderedSet<ConfiguredTarget>], workspace: Workspace, capturedBuildInfo: CapturedBuildInfo?) {
552+
init(path: Path, signature: BuildDescriptionSignature, buildCommand: BuildCommand, taskAdditionalInputs: [Ref<any PlannedTask>: NodeList], mutatedNodes: Set<Ref<any PlannedNode>>, mutatingTasks: [Ref<any PlannedTask>: MutatingTaskInfo], bypassActualTasks: Bool, targetsBuildInParallel: Bool, emitFrontendCommandLines: Bool, moduleSessionFilePath: Path?, invalidationPaths: [Path], recursiveSearchPathResults: [RecursiveSearchPathResolver.CachedResult], copiedPathMap: [String: String], outputPathsPerTarget: [ConfiguredTarget?: [Path]], allOutputPaths: Set<Path>, rootPathsPerTarget: [ConfiguredTarget: [Path]], moduleCachePathsPerTarget: [ConfiguredTarget: [Path]], staleFileRemovalIdentifierPerTarget: [ConfiguredTarget?: String], settingsPerTarget: [ConfiguredTarget: Settings], targetDependencies: [TargetDependencyRelationship], definingTargetsByModuleName: [String: OrderedSet<ConfiguredTarget>], workspace: Workspace, capturedBuildInfo: CapturedBuildInfo?) {
551553
self.path = path
552554
self.signature = signature
553555
self.taskAdditionalInputs = taskAdditionalInputs
@@ -563,7 +565,7 @@ package final class BuildDescriptionBuilder {
563565
self.outputPathsPerTarget = outputPathsPerTarget
564566
self.allOutputPaths = allOutputPaths
565567
self.rootPathsPerTarget = rootPathsPerTarget
566-
self.moduleCachePathPerTarget = moduleCachePathPerTarget
568+
self.moduleCachePathsPerTarget = moduleCachePathsPerTarget
567569
self.staleFileRemovalIdentifierPerTarget = staleFileRemovalIdentifierPerTarget
568570
self.settingsPerTarget = settingsPerTarget
569571
self.targetDependencies = targetDependencies
@@ -676,7 +678,7 @@ package final class BuildDescriptionBuilder {
676678
// Create the build description.
677679
let buildDescription: BuildDescription
678680
do {
679-
buildDescription = try BuildDescription(inDir: path, signature: signature, taskStore: frozenTaskStore, allOutputPaths: allOutputPaths, rootPathsPerTarget: rootPathsPerTarget, moduleCachePathPerTarget: moduleCachePathPerTarget, settingsPerTarget: settingsPerTarget, taskActionMap: taskActionMap, targetTaskCounts: targetTaskCounts, moduleSessionFilePath: moduleSessionFilePath, diagnostics: diagnosticsEngines.mapValues { engine in engine.diagnostics }, fs: fs, invalidationPaths: invalidationPaths, recursiveSearchPathResults: recursiveSearchPathResults, copiedPathMap: copiedPathMap, targetDependencies: targetDependencies, definingTargetsByModuleName: definingTargetsByModuleName, capturedBuildInfo: capturedBuildInfo, bypassActualTasks: bypassActualTasks, targetsBuildInParallel: targetsBuildInParallel, emitFrontendCommandLines: emitFrontendCommandLines)
681+
buildDescription = try BuildDescription(inDir: path, signature: signature, taskStore: frozenTaskStore, allOutputPaths: allOutputPaths, rootPathsPerTarget: rootPathsPerTarget, moduleCachePathsPerTarget: moduleCachePathsPerTarget, settingsPerTarget: settingsPerTarget, taskActionMap: taskActionMap, targetTaskCounts: targetTaskCounts, moduleSessionFilePath: moduleSessionFilePath, diagnostics: diagnosticsEngines.mapValues { engine in engine.diagnostics }, fs: fs, invalidationPaths: invalidationPaths, recursiveSearchPathResults: recursiveSearchPathResults, copiedPathMap: copiedPathMap, targetDependencies: targetDependencies, definingTargetsByModuleName: definingTargetsByModuleName, capturedBuildInfo: capturedBuildInfo, bypassActualTasks: bypassActualTasks, targetsBuildInParallel: targetsBuildInParallel, emitFrontendCommandLines: emitFrontendCommandLines)
680682
}
681683
catch {
682684
throw StubError.error("unable to create build description: \(error)")
@@ -1006,7 +1008,7 @@ extension BuildDescription {
10061008
// FIXME: Bypass actual tasks should go away, eventually.
10071009
//
10081010
// FIXME: This layering isn't working well, we are plumbing a bunch of stuff through here just because we don't want to talk to TaskConstruction.
1009-
static package func construct(workspace: Workspace, tasks: [any PlannedTask], path: Path, signature: BuildDescriptionSignature, buildCommand: BuildCommand, diagnostics: [ConfiguredTarget?: [Diagnostic]] = [:], indexingInfo: [(forTarget: ConfiguredTarget?, path: Path, indexingInfo: any SourceFileIndexingInfo)] = [], fs: any FSProxy = localFS, bypassActualTasks: Bool = false, targetsBuildInParallel: Bool = true, emitFrontendCommandLines: Bool = false, moduleSessionFilePath: Path? = nil, invalidationPaths: [Path] = [], recursiveSearchPathResults: [RecursiveSearchPathResolver.CachedResult] = [], copiedPathMap: [String: String] = [:], rootPathsPerTarget: [ConfiguredTarget:[Path]] = [:], moduleCachePathPerTarget: [ConfiguredTarget: Path] = [:], staleFileRemovalIdentifierPerTarget: [ConfiguredTarget?: String] = [:], settingsPerTarget: [ConfiguredTarget: Settings] = [:], delegate: any BuildDescriptionConstructionDelegate, targetDependencies: [TargetDependencyRelationship] = [], definingTargetsByModuleName: [String: OrderedSet<ConfiguredTarget>], capturedBuildInfo: CapturedBuildInfo?, userPreferences: UserPreferences) async throws -> BuildDescription? {
1011+
static package func construct(workspace: Workspace, tasks: [any PlannedTask], path: Path, signature: BuildDescriptionSignature, buildCommand: BuildCommand, diagnostics: [ConfiguredTarget?: [Diagnostic]] = [:], indexingInfo: [(forTarget: ConfiguredTarget?, path: Path, indexingInfo: any SourceFileIndexingInfo)] = [], fs: any FSProxy = localFS, bypassActualTasks: Bool = false, targetsBuildInParallel: Bool = true, emitFrontendCommandLines: Bool = false, moduleSessionFilePath: Path? = nil, invalidationPaths: [Path] = [], recursiveSearchPathResults: [RecursiveSearchPathResolver.CachedResult] = [], copiedPathMap: [String: String] = [:], rootPathsPerTarget: [ConfiguredTarget:[Path]] = [:], moduleCachePathsPerTarget: [ConfiguredTarget: [Path]] = [:], staleFileRemovalIdentifierPerTarget: [ConfiguredTarget?: String] = [:], settingsPerTarget: [ConfiguredTarget: Settings] = [:], delegate: any BuildDescriptionConstructionDelegate, targetDependencies: [TargetDependencyRelationship] = [], definingTargetsByModuleName: [String: OrderedSet<ConfiguredTarget>], capturedBuildInfo: CapturedBuildInfo?, userPreferences: UserPreferences) async throws -> BuildDescription? {
10101012
var diagnostics = diagnostics
10111013

10121014
// We operate on the sorted tasks here to ensure that the list of task additional inputs is deterministic.
@@ -1269,7 +1271,7 @@ extension BuildDescription {
12691271
}
12701272

12711273
// Create the builder.
1272-
let builder = BuildDescriptionBuilder(path: path, signature: signature, buildCommand: buildCommand, taskAdditionalInputs: taskAdditionalInputs, mutatedNodes: Set(mutableNodes.keys), mutatingTasks: mutatingTasks, bypassActualTasks: bypassActualTasks, targetsBuildInParallel: targetsBuildInParallel, emitFrontendCommandLines: emitFrontendCommandLines, moduleSessionFilePath: moduleSessionFilePath, invalidationPaths: invalidationPaths, recursiveSearchPathResults: recursiveSearchPathResults, copiedPathMap: copiedPathMap, outputPathsPerTarget: outputPathsPerTarget, allOutputPaths: Set(producers.keys.map { $0.instance.path }), rootPathsPerTarget: rootPathsPerTarget, moduleCachePathPerTarget: moduleCachePathPerTarget, staleFileRemovalIdentifierPerTarget: staleFileRemovalIdentifierPerTarget, settingsPerTarget: settingsPerTarget, targetDependencies: targetDependencies, definingTargetsByModuleName: definingTargetsByModuleName, workspace: workspace, capturedBuildInfo: capturedBuildInfo)
1274+
let builder = BuildDescriptionBuilder(path: path, signature: signature, buildCommand: buildCommand, taskAdditionalInputs: taskAdditionalInputs, mutatedNodes: Set(mutableNodes.keys), mutatingTasks: mutatingTasks, bypassActualTasks: bypassActualTasks, targetsBuildInParallel: targetsBuildInParallel, emitFrontendCommandLines: emitFrontendCommandLines, moduleSessionFilePath: moduleSessionFilePath, invalidationPaths: invalidationPaths, recursiveSearchPathResults: recursiveSearchPathResults, copiedPathMap: copiedPathMap, outputPathsPerTarget: outputPathsPerTarget, allOutputPaths: Set(producers.keys.map { $0.instance.path }), rootPathsPerTarget: rootPathsPerTarget, moduleCachePathsPerTarget: moduleCachePathsPerTarget, staleFileRemovalIdentifierPerTarget: staleFileRemovalIdentifierPerTarget, settingsPerTarget: settingsPerTarget, targetDependencies: targetDependencies, definingTargetsByModuleName: definingTargetsByModuleName, workspace: workspace, capturedBuildInfo: capturedBuildInfo)
12731275
for (target, diagnostics) in diagnostics {
12741276
let engine = builder.diagnosticsEngines.getOrInsert(target, { DiagnosticsEngine() })
12751277
for diag in diagnostics {

Sources/SWBTaskExecution/BuildDescriptionManager.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ package final class BuildDescriptionManager: Sendable {
176176
var staleFileRemovalIdentifierPerTarget = [ConfiguredTarget?: String]()
177177
var settingsPerTarget = [ConfiguredTarget:Settings]()
178178
var rootPathsPerTarget = [ConfiguredTarget:[Path]]()
179-
var moduleCachePathPerTarget = [ConfiguredTarget: Path]()
179+
var moduleCachePathsPerTarget = [ConfiguredTarget: [Path]]()
180180
let buildGraph = planRequest.buildGraph
181181

182182
// Add the SFR identifier for target-independent tasks.
@@ -190,7 +190,11 @@ package final class BuildDescriptionManager: Sendable {
190190
settings.globalScope.evaluate(BuiltinMacros.SYMROOT),
191191
]
192192

193-
moduleCachePathPerTarget[target] = settings.globalScope.evaluate(BuiltinMacros.MODULE_CACHE_DIR)
193+
moduleCachePathsPerTarget[target] = [
194+
settings.globalScope.evaluate(BuiltinMacros.MODULE_CACHE_DIR),
195+
Path(settings.globalScope.evaluate(BuiltinMacros.SWIFT_EXPLICIT_MODULES_OUTPUT_PATH)),
196+
Path(settings.globalScope.evaluate(BuiltinMacros.CLANG_EXPLICIT_MODULES_OUTPUT_PATH)),
197+
]
194198

195199
staleFileRemovalIdentifierPerTarget[target] = plan.staleFileRemovalTaskIdentifier(for: target)
196200
settingsPerTarget[target] = settings
@@ -224,7 +228,7 @@ package final class BuildDescriptionManager: Sendable {
224228
}
225229

226230
// Create the build description.
227-
return try await BuildDescription.construct(workspace: buildGraph.workspaceContext.workspace, tasks: plan.tasks, path: path, signature: signature, buildCommand: planRequest.buildRequest.buildCommand, diagnostics: planningDiagnostics, indexingInfo: [], fs: fs, bypassActualTasks: bypassActualTasks, targetsBuildInParallel: buildGraph.targetsBuildInParallel, emitFrontendCommandLines: plan.emitFrontendCommandLines, moduleSessionFilePath: planRequest.workspaceContext.getModuleSessionFilePath(planRequest.buildRequest.parameters), invalidationPaths: plan.invalidationPaths, recursiveSearchPathResults: plan.recursiveSearchPathResults, copiedPathMap: plan.copiedPathMap, rootPathsPerTarget: rootPathsPerTarget, moduleCachePathPerTarget: moduleCachePathPerTarget, staleFileRemovalIdentifierPerTarget: staleFileRemovalIdentifierPerTarget, settingsPerTarget: settingsPerTarget, delegate: delegate, targetDependencies: buildGraph.targetDependenciesByGuid, definingTargetsByModuleName: definingTargetsByModuleName, capturedBuildInfo: capturedBuildInfo, userPreferences: buildGraph.workspaceContext.userPreferences)
231+
return try await BuildDescription.construct(workspace: buildGraph.workspaceContext.workspace, tasks: plan.tasks, path: path, signature: signature, buildCommand: planRequest.buildRequest.buildCommand, diagnostics: planningDiagnostics, indexingInfo: [], fs: fs, bypassActualTasks: bypassActualTasks, targetsBuildInParallel: buildGraph.targetsBuildInParallel, emitFrontendCommandLines: plan.emitFrontendCommandLines, moduleSessionFilePath: planRequest.workspaceContext.getModuleSessionFilePath(planRequest.buildRequest.parameters), invalidationPaths: plan.invalidationPaths, recursiveSearchPathResults: plan.recursiveSearchPathResults, copiedPathMap: plan.copiedPathMap, rootPathsPerTarget: rootPathsPerTarget, moduleCachePathsPerTarget: moduleCachePathsPerTarget, staleFileRemovalIdentifierPerTarget: staleFileRemovalIdentifierPerTarget, settingsPerTarget: settingsPerTarget, delegate: delegate, targetDependencies: buildGraph.targetDependenciesByGuid, definingTargetsByModuleName: definingTargetsByModuleName, capturedBuildInfo: capturedBuildInfo, userPreferences: buildGraph.workspaceContext.userPreferences)
228232
}
229233

230234
/// Encapsulates the two ways `getNewOrCachedBuildDescription` can be called, whether we want to retrieve or create a build description based on a plan or whether we have an explicit build description ID that we want to retrieve and we don't need to create a new one.

0 commit comments

Comments
 (0)