Skip to content

Commit 90c6ece

Browse files
[SwiftCaching] Don't leak output path in the explicit module map JSON
Using an abstract name for the module path for swift caching build because caching build loads modules directly from CAS and the path is insignificant. The abstract module path allows cache hits across different output locations. rdar://149960868
1 parent 19023b0 commit 90c6ece

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ExplicitDependencyBuildPlanner.swift

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
296296
// SwiftModuleArtifactInfo
297297
guard moduleId == .swift(dependencyGraph.mainModuleName) else { return }
298298
let dependencyFileContent =
299-
try serializeModuleDependencies(for: moduleId,
300-
swiftDependencyArtifacts: swiftDependencyArtifacts,
301-
clangDependencyArtifacts: clangDependencyArtifacts)
299+
try serializeModuleDependencies(swiftDependencyArtifacts: swiftDependencyArtifacts,
300+
clangDependencyArtifacts: clangDependencyArtifacts,
301+
cachingEnabled: cas != nil)
302302
if let cas = self.cas {
303303
// When using a CAS, write JSON into CAS and pass the ID on command-line.
304304
let casID = try cas.store(data: dependencyFileContent)
@@ -534,9 +534,9 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
534534
"-Xcc", "-fno-implicit-module-maps")
535535

536536
let dependencyFileContent =
537-
try serializeModuleDependencies(for: mainModuleId,
538-
swiftDependencyArtifacts: swiftDependencyArtifacts,
539-
clangDependencyArtifacts: clangDependencyArtifacts)
537+
try serializeModuleDependencies(swiftDependencyArtifacts: swiftDependencyArtifacts,
538+
clangDependencyArtifacts: clangDependencyArtifacts,
539+
cachingEnabled: false)
540540

541541
let dependencyFile =
542542
try VirtualPath.createUniqueTemporaryFileWithKnownContents(.init(validating: "\(mainModuleId.moduleName)-dependencies.json"),
@@ -548,15 +548,43 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
548548
}
549549

550550
/// Serialize the output file artifacts for a given module in JSON format.
551-
private func serializeModuleDependencies(for moduleId: ModuleDependencyId,
552-
swiftDependencyArtifacts: Set<SwiftModuleArtifactInfo>,
553-
clangDependencyArtifacts: Set<ClangModuleArtifactInfo>
551+
private func serializeModuleDependencies(swiftDependencyArtifacts: Set<SwiftModuleArtifactInfo>,
552+
clangDependencyArtifacts: Set<ClangModuleArtifactInfo>,
553+
cachingEnabled: Bool
554554
) throws -> Data {
555+
// Helper function to abstract the path.
556+
func abstractPath(_ module: String, suffix: String) throws -> TextualVirtualPath {
557+
let path = try VirtualPath(path: module + suffix)
558+
return TextualVirtualPath(path: path.intern())
559+
}
555560
// The module dependency map in CAS needs to be stable.
556-
// Sort the dependencies by name.
561+
// For caching build, updated the dependency info to exclude paths that are compiler outputs from the mapping.
562+
// Use abstract names and paths because caching build loads modules directly from CAS.
557563
let allDependencyArtifacts: [ModuleDependencyArtifactInfo] =
558-
swiftDependencyArtifacts.sorted().map {ModuleDependencyArtifactInfo.swift($0)} +
559-
clangDependencyArtifacts.sorted().map {ModuleDependencyArtifactInfo.clang($0)}
564+
try swiftDependencyArtifacts.sorted().map { info in
565+
if !cachingEnabled {
566+
return ModuleDependencyArtifactInfo.swift(info)
567+
}
568+
let updatedInfo = try SwiftModuleArtifactInfo(name: info.moduleName,
569+
modulePath: abstractPath(info.moduleName, suffix: ".swiftmodule"),
570+
docPath: nil,
571+
sourceInfoPath: nil,
572+
headerDependencies: info.prebuiltHeaderDependencyPaths,
573+
isFramework: info.isFramework,
574+
moduleCacheKey: info.moduleCacheKey)
575+
return ModuleDependencyArtifactInfo.swift(updatedInfo)
576+
} +
577+
clangDependencyArtifacts.sorted().map { info in
578+
if !cachingEnabled {
579+
return ModuleDependencyArtifactInfo.clang(info)
580+
}
581+
let updatedInfo = try ClangModuleArtifactInfo(name: info.moduleName,
582+
modulePath: abstractPath(info.moduleName, suffix: ".pcm"),
583+
moduleMapPath: info.clangModuleMapPath,
584+
moduleCacheKey: info.clangModuleCacheKey,
585+
isBridgingHeaderDependency: info.isBridgingHeaderDependency)
586+
return ModuleDependencyArtifactInfo.clang(updatedInfo)
587+
}
560588
let encoder = JSONEncoder()
561589
// Use sorted key to ensure the order of the keys is stable.
562590
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]

0 commit comments

Comments
 (0)