Skip to content

Commit 6cfb030

Browse files
authored
Merge pull request #705 from artemcm/ExplicitSwiftDependencyContextHash
[Explicit Module Builds] Use context hash in Swift dependency module file names
2 parents 29ee108 + 2e2e088 commit 6cfb030

File tree

6 files changed

+207
-121
lines changed

6 files changed

+207
-121
lines changed

Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public struct Driver {
3737
case malformedModuleDependency(String, String)
3838
case missingPCMArguments(String)
3939
case missingModuleDependency(String)
40+
case missingContextHashOnSwiftDependency(String)
4041
case dependencyScanningFailure(Int, String)
4142
case missingExternalDependency(String)
4243

@@ -88,6 +89,8 @@ public struct Driver {
8889
return "Missing extraPcmArgs to build Clang module: \(moduleName)"
8990
case .missingModuleDependency(let moduleName):
9091
return "Missing Module Dependency Info: \(moduleName)"
92+
case .missingContextHashOnSwiftDependency(let moduleName):
93+
return "Missing Context Hash for Swift dependency: \(moduleName)"
9194
case .dependencyScanningFailure(let code, let error):
9295
return "Module Dependency Scanner returned with non-zero exit status: \(code), \(error)"
9396
case .unableToLoadOutputFileMap(let path):

Sources/SwiftDriver/ExplicitModuleBuilds/InterModuleDependencies/InterModuleDependencyGraph.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public struct SwiftModuleDetails: Codable {
9797
/// Options to the compile command
9898
public var commandLine: [String]? = []
9999

100+
/// The context hash for this module that encodes the producing interface's path,
101+
/// target triple, etc. This field is optional because it is absent for the ModuleInfo
102+
/// corresponding to the main module being built.
103+
public var contextHash: String?
104+
100105
/// To build a PCM to be used by this Swift module, we need to append these
101106
/// arguments to the generic PCM build arguments reported from the dependency
102107
/// graph.

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ extension Driver {
527527
try resolveVersionedClangDependencies(dependencyGraph: &dependencyGraph)
528528

529529
// Set dependency modules' paths to be saved in the module cache.
530-
try updateDependencyModulesWithModuleCachePath(dependencyGraph: &dependencyGraph)
530+
try resolveDependencyModulePaths(dependencyGraph: &dependencyGraph)
531531

532532
// Update the dependency oracle, adding this new dependency graph to its store
533533
try interModuleDependencyOracle.mergeModules(from: dependencyGraph)
@@ -536,29 +536,61 @@ extension Driver {
536536
}
537537

538538
/// Update the given inter-module dependency graph to set module paths to be within the module cache,
539-
/// if one is present.
540-
private mutating func updateDependencyModulesWithModuleCachePath(dependencyGraph:
541-
inout InterModuleDependencyGraph)
539+
/// if one is present, and for Swift modules to use the context hash in the file name.
540+
private mutating func resolveDependencyModulePaths(dependencyGraph: inout InterModuleDependencyGraph)
542541
throws {
543-
let moduleCachePath = parsedOptions.getLastArgument(.moduleCachePath)?.asSingle
544-
if moduleCachePath != nil {
545-
for (moduleId, moduleInfo) in dependencyGraph.modules {
546-
// Output path on the main module is determined by the invocation arguments.
547-
guard moduleId.moduleName != dependencyGraph.mainModuleName else {
548-
continue
549-
}
550-
let modulePath = VirtualPath.lookup(moduleInfo.modulePath.path)
551-
// Only update paths on modules which do not already specify a path beyond their module name
552-
// and a file extension.
553-
if modulePath.description == moduleId.moduleName + ".swiftmodule" ||
554-
modulePath.description == moduleId.moduleName + ".pcm" {
555-
// Use VirtualPath to get the OS-specific path separators right.
556-
let modulePathInCache =
557-
try VirtualPath(path: moduleCachePath!)
558-
.appending(component: modulePath.description)
559-
dependencyGraph.modules[moduleId]!.modulePath =
560-
TextualVirtualPath(path: modulePathInCache.intern())
561-
}
542+
// For Swift module dependencies, set the output path to include
543+
// the module's context hash
544+
try resolveSwiftDependencyModuleFileNames(dependencyGraph: &dependencyGraph)
545+
546+
// If a module cache path is specified, update all module dependencies
547+
// to be output into it.
548+
if let moduleCachePath = parsedOptions.getLastArgument(.moduleCachePath)?.asSingle {
549+
try resolveDependencyModulePathsRelativeToModuleCache(dependencyGraph: &dependencyGraph,
550+
moduleCachePath: moduleCachePath)
551+
}
552+
}
553+
554+
/// For Swift module dependencies, set the output path to include the module's context hash
555+
private mutating func resolveSwiftDependencyModuleFileNames(dependencyGraph: inout InterModuleDependencyGraph)
556+
throws {
557+
for (moduleId, moduleInfo) in dependencyGraph.modules {
558+
// Output path on the main module is determined by the invocation arguments.
559+
guard moduleId.moduleName != dependencyGraph.mainModuleName else {
560+
continue
561+
}
562+
guard case .swift(let swiftDetails) = moduleInfo.details else {
563+
continue
564+
}
565+
guard let contextHash = swiftDetails.contextHash else {
566+
throw Driver.Error.missingContextHashOnSwiftDependency(moduleId.moduleName)
567+
}
568+
let plainPath = VirtualPath.lookup(dependencyGraph.modules[moduleId]!.modulePath.path)
569+
let updatedPath = plainPath.parentDirectory.appending(component: "\(plainPath.basenameWithoutExt)-\(contextHash).\(plainPath.extension!)")
570+
dependencyGraph.modules[moduleId]!.modulePath = TextualVirtualPath(path: updatedPath.intern())
571+
}
572+
}
573+
574+
/// Resolve all paths to dependency binary module files to be relative to the module cache path.
575+
private mutating func resolveDependencyModulePathsRelativeToModuleCache(dependencyGraph: inout InterModuleDependencyGraph,
576+
moduleCachePath: String)
577+
throws {
578+
for (moduleId, moduleInfo) in dependencyGraph.modules {
579+
// Output path on the main module is determined by the invocation arguments.
580+
guard moduleId.moduleName != dependencyGraph.mainModuleName else {
581+
continue
582+
}
583+
let modulePath = VirtualPath.lookup(moduleInfo.modulePath.path)
584+
// Only update paths on modules which do not already specify a path beyond their module name
585+
// and a file extension.
586+
if modulePath.description == moduleId.moduleName + ".swiftmodule" ||
587+
modulePath.description == moduleId.moduleName + ".pcm" {
588+
// Use VirtualPath to get the OS-specific path separators right.
589+
let modulePathInCache =
590+
try VirtualPath(path: moduleCachePath)
591+
.appending(component: modulePath.description)
592+
dependencyGraph.modules[moduleId]!.modulePath =
593+
TextualVirtualPath(path: modulePathInCache.intern())
562594
}
563595
}
564596
}

Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,17 @@ private extension SwiftScan {
158158
try getStringArrayDetail(from: moduleDetailsRef,
159159
using: api.swiftscan_swift_textual_detail_get_extra_pcm_args,
160160
fieldName: "extraPCMArgs")
161+
let contextHash =
162+
try getOptionalStringDetail(from: moduleDetailsRef,
163+
using: api.swiftscan_swift_textual_detail_get_context_hash)
161164
let isFramework = api.swiftscan_swift_textual_detail_get_is_framework(moduleDetailsRef)
165+
162166
return SwiftModuleDetails(moduleInterfacePath: moduleInterfacePath,
163167
compiledModuleCandidates: compiledModuleCandidates,
164168
bridgingHeaderPath: bridgingHeaderPath,
165169
bridgingSourceFiles: bridgingSourceFiles,
166170
commandLine: commandLine,
171+
contextHash: contextHash,
167172
extraPcmArgs: extraPcmArgs,
168173
isFramework: isFramework)
169174
}

0 commit comments

Comments
 (0)