Skip to content

Commit 36f08da

Browse files
committed
[Explicit Module Builds] Rely on Clang dependencies' ContextHash to determine the PCM output filename
The driver previously implemented a scheme where it computed an output path for the PCMs of clang module dependencies by hashing the command-line used to build the PCM plus a set of special arguments determined by the depending Swift module that made the PCM unique to the depending Swift module in the build graph. This was previously done first and foremost to accomodate the fact that we used to have Clang modules built against different target triples in the build graph. The driver would previously execute a dependency scan, and follow it up with a re-scan of relevant clang modules which we require to have dependency info about at a target triple that is different from the main module's target triple. With the introduction of '-clang-target', we are aiming to ensure that '-target' triple of all Clang modules built matches that of the top-level Swift main module being built; therefore, making re-scanning and manual hashing of the PCM output filename unnecessary.
1 parent 36c89c7 commit 36f08da

File tree

3 files changed

+129
-318
lines changed

3 files changed

+129
-318
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ExplicitDependencyBuildPlanner.swift

Lines changed: 16 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,14 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
230230
commandLine: &commandLine)
231231

232232
let moduleMapPath = moduleDetails.moduleMapPath.path
233-
// Encode the target triple pcm args into the output `.pcm` filename
234-
let targetEncodedModulePath =
235-
try targetEncodedClangModuleFilePath(for: moduleInfo,
236-
hashParts: getPCMHashParts(pcmArgs: pcmArgs,
237-
contextHash: moduleDetails.contextHash))
238-
outputs.append(TypedVirtualPath(file: targetEncodedModulePath, type: .pcm))
233+
let modulePCMPath = moduleInfo.modulePath
234+
outputs.append(TypedVirtualPath(file: modulePCMPath.path, type: .pcm))
239235
commandLine.appendFlags("-emit-pcm", "-module-name", moduleId.moduleName,
240-
"-o", targetEncodedModulePath.description)
236+
"-o", modulePCMPath.path.description)
241237

242238
// Fixup "-o -Xcc '<replace-me>'"
243239
if let outputIndex = commandLine.firstIndex(of: .flag("<replace-me>")) {
244-
commandLine[outputIndex] = .path(VirtualPath.lookup(targetEncodedModulePath))
240+
commandLine[outputIndex] = .path(VirtualPath.lookup(modulePCMPath.path))
245241
}
246242

247243
// The only required input is the .modulemap for this module.
@@ -300,21 +296,23 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
300296
let clangModulePath =
301297
TypedVirtualPath(file: moduleArtifactInfo.modulePath.path,
302298
type: .pcm)
299+
let clangModuleMapPath =
300+
TypedVirtualPath(file: moduleArtifactInfo.moduleMapPath.path,
301+
type: .clangModuleMap)
302+
inputs.append(clangModulePath)
303+
inputs.append(clangModuleMapPath)
304+
303305
// If an existing dependency module path stub exists, replace it.
304306
if let existingIndex = commandLine.firstIndex(of: .flag("-fmodule-file=" + moduleArtifactInfo.moduleName + "=<replace-me>")) {
305307
commandLine[existingIndex] = .flag("-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
306-
} else {
308+
} else if case .swift(_) = moduleId {
307309
commandLine.appendFlags("-Xcc",
308310
"-fmodule-file=\(moduleArtifactInfo.moduleName)=\(clangModulePath.file.description)")
309311
}
310-
311-
let clangModuleMapPath =
312-
TypedVirtualPath(file: moduleArtifactInfo.moduleMapPath.path,
313-
type: .clangModuleMap)
314-
commandLine.appendFlags("-Xcc",
315-
"-fmodule-map-file=\(clangModuleMapPath.file.description)")
316-
inputs.append(clangModulePath)
317-
inputs.append(clangModuleMapPath)
312+
if case .swift(_) = moduleId {
313+
commandLine.appendFlags("-Xcc",
314+
"-fmodule-map-file=\(clangModuleMapPath.file.description)")
315+
}
318316
}
319317
}
320318

@@ -346,14 +344,10 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
346344
let dependencyInfo = try dependencyGraph.moduleInfo(of: dependencyId)
347345
let dependencyClangModuleDetails =
348346
try dependencyGraph.clangModuleDetails(of: dependencyId)
349-
let clangModulePath =
350-
try targetEncodedClangModuleFilePath(for: dependencyInfo,
351-
hashParts: getPCMHashParts(pcmArgs: pcmArgs,
352-
contextHash: dependencyClangModuleDetails.contextHash))
353347
// Accumulate the required information about this dependency
354348
clangDependencyArtifacts.append(
355349
ClangModuleArtifactInfo(name: dependencyId.moduleName,
356-
modulePath: TextualVirtualPath(path: clangModulePath),
350+
modulePath: TextualVirtualPath(path: dependencyInfo.modulePath.path),
357351
moduleMapPath: dependencyClangModuleDetails.moduleMapPath))
358352
case .swiftPrebuiltExternal:
359353
let prebuiltModuleDetails = try dependencyGraph.swiftPrebuiltDetails(of: dependencyId)
@@ -435,41 +429,6 @@ public typealias ExternalTargetModuleDetailsMap = [ModuleDependencyId: ExternalT
435429
}
436430
}
437431

438-
/// Utility methods for encoding PCM's target triple into its name.
439-
extension ExplicitDependencyBuildPlanner {
440-
/// Compute a full path to the resulting .pcm file for a given Clang module, with the
441-
/// target triple encoded in the name.
442-
public mutating func targetEncodedClangModuleFilePath(for moduleInfo: ModuleInfo,
443-
hashParts: [String]) throws -> VirtualPath.Handle {
444-
let plainModulePath = VirtualPath.lookup(moduleInfo.modulePath.path)
445-
let targetEncodedBaseName =
446-
try targetEncodedClangModuleName(for: plainModulePath.basenameWithoutExt,
447-
hashParts: hashParts)
448-
let modifiedModulePath =
449-
moduleInfo.modulePath.path.description
450-
.replacingOccurrences(of: plainModulePath.basenameWithoutExt,
451-
with: targetEncodedBaseName)
452-
return try VirtualPath.intern(path: modifiedModulePath)
453-
}
454-
455-
/// Compute the name of a given Clang module, along with a hash of extra PCM build arguments it
456-
/// is to be constructed with.
457-
@_spi(Testing) public mutating func targetEncodedClangModuleName(for moduleName: String,
458-
hashParts: [String])
459-
throws -> String {
460-
let hashInput = hashParts.sorted().joined()
461-
// Hash based on "moduleName + hashInput"
462-
let cacheQuery = moduleName + hashInput
463-
if let previouslyHashsedName = hashedModuleNameCache[cacheQuery] {
464-
return previouslyHashsedName
465-
}
466-
let hashedArguments = SHA256().hash(hashInput).hexadecimalRepresentation
467-
let resultingName = moduleName + "-" + hashedArguments
468-
hashedModuleNameCache[cacheQuery] = resultingName
469-
return resultingName
470-
}
471-
}
472-
473432
/// Encapsulates some of the common queries of the ExplicitDependencyBuildPlanner with error-checking
474433
/// on the dependency graph's structure.
475434
@_spi(Testing) public extension InterModuleDependencyGraph {

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ extension Driver {
647647
}
648648

649649
// Re-scan Clang modules at all the targets they will be built against.
650-
try resolveVersionedClangDependencies(dependencyGraph: &dependencyGraph)
650+
// This is currently disabled because we are investigating it being unnecessary
651+
// try resolveVersionedClangDependencies(dependencyGraph: &dependencyGraph)
651652

652653
// Set dependency modules' paths to be saved in the module cache.
653654
try resolveDependencyModulePaths(dependencyGraph: &dependencyGraph)
@@ -676,28 +677,31 @@ extension Driver {
676677
moduleCachePath: moduleCachePath)
677678
}
678679

679-
// For Swift module dependencies, set the output path to include
680-
// the module's context hash
681-
try resolveSwiftDependencyModuleFileNames(dependencyGraph: &dependencyGraph)
680+
// Set the output path to include the module's context hash
681+
try resolveDependencyModuleFileNamesWithContextHash(dependencyGraph: &dependencyGraph)
682682
}
683683

684684
/// For Swift module dependencies, set the output path to include the module's context hash
685-
private mutating func resolveSwiftDependencyModuleFileNames(dependencyGraph: inout InterModuleDependencyGraph)
685+
private mutating func resolveDependencyModuleFileNamesWithContextHash(dependencyGraph: inout InterModuleDependencyGraph)
686686
throws {
687687
for (moduleId, moduleInfo) in dependencyGraph.modules {
688688
// Output path on the main module is determined by the invocation arguments.
689689
guard moduleId.moduleName != dependencyGraph.mainModuleName else {
690690
continue
691691
}
692-
guard case .swift(let swiftDetails) = moduleInfo.details else {
693-
continue
694-
}
695-
guard let contextHash = swiftDetails.contextHash else {
696-
throw Driver.Error.missingContextHashOnSwiftDependency(moduleId.moduleName)
697-
}
692+
698693
let plainPath = VirtualPath.lookup(dependencyGraph.modules[moduleId]!.modulePath.path)
699-
let updatedPath = plainPath.parentDirectory.appending(component: "\(plainPath.basenameWithoutExt)-\(contextHash).\(plainPath.extension!)")
700-
dependencyGraph.modules[moduleId]!.modulePath = TextualVirtualPath(path: updatedPath.intern())
694+
if case .swift(let swiftDetails) = moduleInfo.details {
695+
guard let contextHash = swiftDetails.contextHash else {
696+
throw Driver.Error.missingContextHashOnSwiftDependency(moduleId.moduleName)
697+
}
698+
let updatedPath = plainPath.parentDirectory.appending(component: "\(plainPath.basenameWithoutExt)-\(contextHash).\(plainPath.extension!)")
699+
dependencyGraph.modules[moduleId]!.modulePath = TextualVirtualPath(path: updatedPath.intern())
700+
} else if case .clang(let clangDetails) = moduleInfo.details {
701+
let contextHash = clangDetails.contextHash
702+
let updatedPath = plainPath.parentDirectory.appending(component: "\(plainPath.basenameWithoutExt)-\(contextHash).\(plainPath.extension!)")
703+
dependencyGraph.modules[moduleId]!.modulePath = TextualVirtualPath(path: updatedPath.intern())
704+
}
701705
}
702706
}
703707

0 commit comments

Comments
 (0)