Skip to content

Commit ed363ec

Browse files
committed
Response files should be named using the hash of the command line arguments only
1 parent 5e9abc0 commit ed363ec

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

Sources/SwiftDriver/Execution/ArgsResolver.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import class Foundation.NSLock
1515
import func TSCBasic.withTemporaryDirectory
1616
import protocol TSCBasic.FileSystem
1717
import struct TSCBasic.AbsolutePath
18+
import struct TSCBasic.SHA256
1819

1920
@_implementationOnly import Yams
2021

@@ -208,7 +209,8 @@ public final class ArgsResolver {
208209
assert(!forceResponseFiles || job.supportsResponseFiles,
209210
"Platform does not support response files for job: \(job)")
210211
// Match the integrated driver's behavior, which uses response file names of the form "arguments-[0-9a-zA-Z].resp".
211-
let responseFilePath = temporaryDirectory.appending(component: "arguments-\(abs(job.hashValue)).resp")
212+
let hash = SHA256().hash(resolvedArguments.joined(separator: " ")).hexadecimalRepresentation
213+
let responseFilePath = temporaryDirectory.appending(component: "arguments-\(hash).resp")
212214

213215
// FIXME: Need a way to support this for distributed build systems...
214216
if let absPath = responseFilePath.absolutePath {

Tests/SwiftDriverTests/SwiftDriverTests.swift

+21
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,27 @@ final class SwiftDriverTests: XCTestCase {
17121712
XCTAssertFalse(resolvedArgs.contains { $0.hasPrefix("@") })
17131713
}
17141714
}
1715+
1716+
func testResponseFileDeterministicNaming() throws {
1717+
#if !os(macOS)
1718+
throw XCTSkip("Test assumes macOS response file quoting behavior")
1719+
#endif
1720+
do {
1721+
let testJob = Job(moduleName: "Foo",
1722+
kind: .compile,
1723+
tool: .init(path: try AbsolutePath(validating: "/swiftc"), supportsResponseFiles: true),
1724+
commandLine: (1...20000).map { .flag("-DTEST_\($0)") },
1725+
inputs: [],
1726+
primaryInputs: [],
1727+
outputs: [])
1728+
let resolver = try ArgsResolver(fileSystem: localFileSystem)
1729+
let resolvedArgs: [String] = try resolver.resolveArgumentList(for: testJob)
1730+
XCTAssertTrue(resolvedArgs.count == 3)
1731+
XCTAssertEqual(resolvedArgs[2].first, "@")
1732+
let responseFilePath = try AbsolutePath(validating: String(resolvedArgs[2].dropFirst()))
1733+
XCTAssertEqual(responseFilePath.basename, "arguments-847d15e70d97df7c18033735497ca8dcc4441f461d5a9c2b764b127004524e81.resp")
1734+
}
1735+
}
17151736

17161737
func testSpecificJobsResponseFiles() throws {
17171738
// The jobs below often take large command lines (e.g., when passing a large number of Clang

0 commit comments

Comments
 (0)