Skip to content

Commit 17536f7

Browse files
authored
Merge pull request #809 from owenv/owenv/driver-response-name
Adopt uniquely-named driver response files
2 parents b00a22c + 113e24f commit 17536f7

File tree

2 files changed

+56
-19
lines changed

2 files changed

+56
-19
lines changed

Sources/SWBCore/LibSwiftDriver/PlannedBuild.swift

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
8080
public let outputs: [Path]
8181
/// The command line to execute for this job
8282
public let commandLine: [SWBUtil.ByteString]
83+
/// The signature uniquely identifying the command line, looking through any indirection through response files.
84+
public let commandLineSignature: SWBUtil.ByteString
8385
/// Cache keys for the swift-frontend invocation (one key per output producing input)
8486
public let cacheKeys: [String]
8587

@@ -91,27 +93,43 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
9193
self.displayInputs = try job.displayInputs.map { try Path(resolver.resolve(.path($0.file))) }
9294
self.outputs = try job.outputs.map { try Path(resolver.resolve(.path($0.file))) }
9395
self.descriptionForLifecycle = job.descriptionForLifecycle
94-
if categorizer.isExplicitDependencyBuild {
95-
self.commandLine = try explicitModulesResolver.resolveArgumentList(for: job, useResponseFiles: .heuristic).map { ByteString(encodingAsUTF8: $0) }
96-
self.kind = .explicitModule(uniqueID: commandLine.hashValue)
97-
} else {
98-
self.commandLine = try resolver.resolveArgumentList(for: job, useResponseFiles: .heuristic).map { ByteString(encodingAsUTF8: $0) }
99-
self.kind = .target
96+
let chosenResolver = categorizer.isExplicitDependencyBuild ? explicitModulesResolver : resolver
97+
let args: ResolvedCommandLine = try chosenResolver.resolveArgumentList(for: job, useResponseFiles: .heuristic)
98+
switch args {
99+
case .plain(let args):
100+
self.commandLine = args.map { ByteString(encodingAsUTF8: $0) }
101+
let ctx = InsecureHashContext()
102+
for arg in args {
103+
ctx.add(string: arg)
104+
}
105+
self.commandLineSignature = ctx.signature
106+
self.kind = categorizer.isExplicitDependencyBuild ? .explicitModule(uniqueID: args.hashValue) : .target
107+
case .usingResponseFile(resolved: let args, responseFileContents: let responseFileContents):
108+
// When using a response file, jobs should be uniqued based on the contents of the response file
109+
self.commandLine = args.map { ByteString(encodingAsUTF8: $0) }
110+
let ctx = InsecureHashContext()
111+
for arg in responseFileContents {
112+
ctx.add(string: arg)
113+
}
114+
self.commandLineSignature = ctx.signature
115+
self.kind = categorizer.isExplicitDependencyBuild ? .explicitModule(uniqueID: responseFileContents.hashValue) : .target
100116
}
117+
101118
self.cacheKeys = job.outputCacheKeys.reduce(into: [String]()) { result, key in
102119
result.append(key.value)
103120
}.sorted()
104121
}
105122

106123
public func serialize<T>(to serializer: T) where T : Serializer {
107-
serializer.serializeAggregate(9) {
124+
serializer.serializeAggregate(10) {
108125
serializer.serialize(kind)
109126
serializer.serialize(ruleInfoType)
110127
serializer.serialize(moduleName)
111128
serializer.serialize(inputs)
112129
serializer.serialize(displayInputs)
113130
serializer.serialize(outputs)
114131
serializer.serialize(commandLine)
132+
serializer.serialize(commandLineSignature)
115133
serializer.serialize(descriptionForLifecycle)
116134
serializer.serialize(cacheKeys)
117135
}
@@ -126,6 +144,7 @@ public struct SwiftDriverJob: Serializable, CustomDebugStringConvertible {
126144
try self.displayInputs = deserializer.deserialize()
127145
try self.outputs = deserializer.deserialize()
128146
try self.commandLine = deserializer.deserialize()
147+
try self.commandLineSignature = deserializer.deserialize()
129148
try self.descriptionForLifecycle = deserializer.deserialize()
130149
try self.cacheKeys = deserializer.deserialize()
131150
}
@@ -173,9 +192,7 @@ extension LibSwiftDriver {
173192
self.dependencies = dependencies
174193
self.workingDirectory = workingDirectory
175194
let md5 = InsecureHashContext()
176-
for arg in driverJob.commandLine {
177-
md5.add(bytes: arg)
178-
}
195+
md5.add(bytes: driverJob.commandLineSignature)
179196
md5.add(string: workingDirectory.str)
180197
md5.add(number: dependencies.hashValue)
181198
self.signature = md5.signature

Tests/SWBBuildSystemTests/SwiftDriverTests.swift

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,6 +1441,7 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
14411441
children: [
14421442
TestFile("file1.swift"),
14431443
TestFile("file2.swift"),
1444+
TestFile("file3.swift"),
14441445
]),
14451446
buildConfigurations: [
14461447
TestBuildConfiguration(
@@ -1451,11 +1452,23 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
14511452
"BUILD_VARIANTS": "normal",
14521453
"SWIFT_USE_INTEGRATED_DRIVER": "YES",
14531454
"SWIFT_ENABLE_EXPLICIT_MODULES": "YES",
1455+
"BUILD_LIBRARY_FOR_DISTRIBUTION": "YES",
14541456
// Force use of a response file
1455-
"GCC_PREPROCESSOR_DEFINITIONS": Array(repeating: "ABCD=1", count: 10000).joined(separator: " ")
1457+
"GCC_PREPROCESSOR_DEFINITIONS": Array(repeating: "ABCD=1", count: 10000).joined(separator: " "),
1458+
"OTHER_SWIFT_FLAGS": "-Xfrontend -module-load-mode -Xfrontend only-interface"
14561459
])
14571460
],
14581461
targets: [
1462+
TestStandardTarget("TargetC",
1463+
type: .framework,
1464+
buildConfigurations: [
1465+
TestBuildConfiguration("Debug"),
1466+
],
1467+
buildPhases: [
1468+
TestSourcesBuildPhase([
1469+
"file3.swift",
1470+
]),
1471+
]),
14591472
TestStandardTarget("TargetA",
14601473
type: .framework,
14611474
buildConfigurations: [
@@ -1465,7 +1478,7 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
14651478
TestSourcesBuildPhase([
14661479
"file1.swift",
14671480
]),
1468-
], dependencies: ["TargetB"]),
1481+
], dependencies: ["TargetB", "TargetC"]),
14691482
TestStandardTarget("TargetB",
14701483
type: .framework,
14711484
buildConfigurations: [
@@ -1475,12 +1488,11 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
14751488
TestSourcesBuildPhase([
14761489
"file2.swift"
14771490
]),
1478-
])
1491+
], dependencies: ["TargetC"])
14791492
])
14801493
])
14811494

14821495
let tester = try await BuildOperationTester(getCore(), testWorkspace, simulated: false)
1483-
tester.userInfo = tester.userInfo.withAdditionalEnvironment(environment: ["SWIFT_FORCE_MODULE_LOADING": "only-interface"])
14841496
try tester.fs.createDirectory(moduleCacheDir)
14851497
let parameters = BuildParameters(configuration: "Debug")
14861498
let targetsToBuild = tester.workspace.projects.flatMap { project in project.targets.map({ BuildRequest.BuildTargetInfo(parameters: parameters, target: $0) }) }
@@ -1491,21 +1503,29 @@ fileprivate struct SwiftDriverTests: CoreBasedTests {
14911503
try await tester.fs.writeFileContents(SRCROOTA.join("Sources/file1.swift")) { file in
14921504
file <<<
14931505
"""
1494-
import Foundation
1506+
import TargetC
1507+
func foo() { baz() }
14951508
"""
14961509
}
14971510
try await tester.fs.writeFileContents(SRCROOTA.join("Sources/file2.swift")) { file in
14981511
file <<<
14991512
"""
1500-
import Foundation
1513+
import TargetC
1514+
func bar() { baz() }
1515+
"""
1516+
}
1517+
try await tester.fs.writeFileContents(SRCROOTA.join("Sources/file3.swift")) { file in
1518+
file <<<
1519+
"""
1520+
public func baz() {}
15011521
"""
15021522
}
15031523

15041524
try await tester.checkBuild(runDestination: .macOS, buildRequest: buildRequest, persistent: true) { results in
15051525
results.checkNoErrors()
1506-
results.checkTasks(.matchRulePattern(["SwiftExplicitDependencyCompileModuleFromInterface", "normal", .any, .contains("SwiftExplicitPrecompiledModules/Foundation-")])) { compileFoundationTasks in
1507-
// We only expect to need one variant of Foundation
1508-
#expect(compileFoundationTasks.count == 1)
1526+
results.checkTasks(.matchRulePattern(["SwiftExplicitDependencyCompileModuleFromInterface", .any, .contains("SwiftExplicitPrecompiledModules/TargetC-")])) { compileTasks in
1527+
// We only expect to need one variant of TargetC
1528+
#expect(compileTasks.count == 1)
15091529
}
15101530
}
15111531
}

0 commit comments

Comments
 (0)