Skip to content

Commit 231952e

Browse files
committed
Only make input paths absolute when -working-directory is passed
1 parent 2a49cfe commit 231952e

File tree

5 files changed

+112
-31
lines changed

5 files changed

+112
-31
lines changed

Sources/SwiftDriver/Driver/Driver.swift

+13-10
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,8 @@ public struct Driver {
329329
case .absolute(let path):
330330
return path
331331
case .relative(let path):
332-
return workingDirectory.map { AbsolutePath($0, path) }
332+
let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory
333+
return cwd.map { AbsolutePath($0, path) }
333334
case .standardInput, .standardOutput, .temporary, .temporaryWithKnownContents, .fileList:
334335
fatalError("Frontend target information will never include a path of this type.")
335336
}
@@ -688,14 +689,14 @@ public struct Driver {
688689
compilerMode: compilerMode)
689690

690691
// Compute the working directory.
691-
let cwd = fileSystem.currentWorkingDirectory
692-
workingDirectory = try parsedOptions.getLastArgument(.workingDirectory).map { workingDirectoryArg in
692+
self.workingDirectory = try parsedOptions.getLastArgument(.workingDirectory).map { workingDirectoryArg in
693+
let cwd = fileSystem.currentWorkingDirectory
693694
return try cwd.map{ try AbsolutePath(validating: workingDirectoryArg.asSingle, relativeTo: $0) } ?? AbsolutePath(validating: workingDirectoryArg.asSingle)
694-
} ?? cwd
695-
696-
// Apply the working directory to the parsed options.
697-
if let workingDirectory = self.workingDirectory {
698-
try Self.applyWorkingDirectory(workingDirectory, to: &self.parsedOptions)
695+
}
696+
697+
if let specifiedWorkingDir = self.workingDirectory {
698+
// Apply the working directory to the parsed options if passed explicitly.
699+
try Self.applyWorkingDirectory(specifiedWorkingDir, to: &self.parsedOptions)
699700
}
700701

701702
let staticExecutable = parsedOptions.hasFlag(positive: .staticExecutable,
@@ -776,6 +777,8 @@ public struct Driver {
776777
}
777778

778779
if let workingDirectory = self.workingDirectory {
780+
// Input paths are prefixed with the working directory when specified,
781+
// apply the same logic to the output file map keys.
779782
self.outputFileMap = outputFileMap?.resolveRelativePaths(relativeTo: workingDirectory)
780783
} else {
781784
self.outputFileMap = outputFileMap
@@ -854,7 +857,7 @@ public struct Driver {
854857
self.buildRecordInfo = BuildRecordInfo(
855858
actualSwiftVersion: self.frontendTargetInfo.compilerVersion,
856859
compilerOutputType: compilerOutputType,
857-
workingDirectory: self.workingDirectory,
860+
workingDirectory: self.workingDirectory ?? fileSystem.currentWorkingDirectory,
858861
diagnosticEngine: diagnosticEngine,
859862
fileSystem: fileSystem,
860863
moduleOutputInfo: moduleOutputInfo,
@@ -3099,7 +3102,7 @@ extension Driver {
30993102
}
31003103

31013104
if let profileArgs = parsedOptions.getLastArgument(.profileUse)?.asMultiple,
3102-
let workingDirectory = workingDirectory {
3105+
let workingDirectory = workingDirectory ?? fileSystem.currentWorkingDirectory {
31033106
for profilingData in profileArgs {
31043107
if let path = try? AbsolutePath(validating: profilingData,
31053108
relativeTo: workingDirectory) {

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public extension Driver {
184184

185185
if supportInProcessSwiftScanQueries {
186186
var scanDiagnostics: [ScannerDiagnosticPayload] = []
187-
guard let cwd = workingDirectory else {
187+
guard let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory else {
188188
throw DependencyScanningError.dependencyScanFailed("cannot determine working directory")
189189
}
190190
var command = try Self.itemizedJobCommand(of: preScanJob,
@@ -260,7 +260,7 @@ public extension Driver {
260260

261261
if supportInProcessSwiftScanQueries {
262262
var scanDiagnostics: [ScannerDiagnosticPayload] = []
263-
guard let cwd = workingDirectory else {
263+
guard let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory else {
264264
throw DependencyScanningError.dependencyScanFailed("cannot determine working directory")
265265
}
266266
var command = try Self.itemizedJobCommand(of: scannerJob,
@@ -298,7 +298,7 @@ public extension Driver {
298298

299299
if supportInProcessSwiftScanQueries {
300300
var scanDiagnostics: [ScannerDiagnosticPayload] = []
301-
guard let cwd = workingDirectory else {
301+
guard let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory else {
302302
throw DependencyScanningError.dependencyScanFailed("cannot determine working directory")
303303
}
304304
var command = try Self.itemizedJobCommand(of: batchScanningJob,

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ extension Driver {
401401
if let compilationDir = parsedOptions.getLastArgument(.fileCompilationDir)?.asSingle {
402402
let compDirPath = try VirtualPath.intern(path: compilationDir)
403403
try addPathArgument(VirtualPath.lookup(compDirPath), to:&commandLine, remap: jobNeedPathRemap)
404-
} else if let cwd = workingDirectory {
404+
} else if let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory {
405405
let compDirPath = VirtualPath.absolute(cwd)
406406
try addPathArgument(compDirPath, to:&commandLine, remap: jobNeedPathRemap)
407407
}
@@ -837,7 +837,7 @@ extension Driver {
837837

838838
extension Driver {
839839
private func getAbsolutePathFromVirtualPath(_ path: VirtualPath) -> AbsolutePath? {
840-
guard let cwd = workingDirectory else {
840+
guard let cwd = workingDirectory ?? fileSystem.currentWorkingDirectory else {
841841
return nil
842842
}
843843
return path.resolvedRelativePath(base: cwd).absolutePath

Sources/SwiftDriver/Jobs/PrintTargetInfoJob.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ extension Driver {
186186
fileSystem: FileSystem,
187187
workingDirectory: AbsolutePath?,
188188
invocationCommand: [String]) throws -> FrontendTargetInfo {
189-
let cwd = try workingDirectory ?? fileSystem.tempDirectory
189+
let cwd = try workingDirectory ?? fileSystem.currentWorkingDirectory ?? fileSystem.tempDirectory
190190
let compilerExecutablePath = try toolchain.resolvedTool(.swiftCompiler).path
191191
let targetInfoData =
192192
try libSwiftScanInstance.queryTargetInfoJSON(workingDirectory: cwd,

Tests/SwiftDriverTests/SwiftDriverTests.swift

+93-15
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,15 @@ private var testInputsPath: AbsolutePath {
4545
}
4646
}
4747

48-
func toPath(_ path: String, base: AbsolutePath = localFileSystem.currentWorkingDirectory!) throws -> VirtualPath {
49-
return try VirtualPath(path: path).resolvedRelativePath(base: base)
48+
func toPath(_ path: String, isRelative: Bool = true) throws -> VirtualPath {
49+
if isRelative {
50+
return VirtualPath.relative(try .init(validating: path))
51+
}
52+
return try VirtualPath(path: path).resolvedRelativePath(base: localFileSystem.currentWorkingDirectory!)
5053
}
5154

52-
func toPathOption(_ path: String, base: AbsolutePath = localFileSystem.currentWorkingDirectory!) throws -> Job.ArgTemplate {
53-
return .path(try toPath(path, base: base))
55+
func toPathOption(_ path: String, isRelative: Bool = true) throws -> Job.ArgTemplate {
56+
return .path(try toPath(path, isRelative: isRelative))
5457
}
5558

5659
final class SwiftDriverTests: XCTestCase {
@@ -351,7 +354,7 @@ final class SwiftDriverTests: XCTestCase {
351354
])
352355
XCTAssertEqual(driver.recordedInputModificationDates, [
353356
.init(file: VirtualPath.absolute(main).intern(), type: .swift) : mainMDate,
354-
.init(file: VirtualPath.absolute(util).intern(), type: .swift) : utilMDate,
357+
.init(file: VirtualPath.relative(utilRelative).intern(), type: .swift) : utilMDate,
355358
])
356359
}
357360
}
@@ -1295,12 +1298,11 @@ final class SwiftDriverTests: XCTestCase {
12951298
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
12961299
XCTAssertEqual(plannedJobs.count, 3)
12971300
XCTAssertEqual(plannedJobs[0].kind, .compile)
1298-
XCTAssertTrue(plannedJobs[0].primaryInputs.map{ $0.file.description }.elementsEqual([rebase("foo.swift"),
1299-
rebase("bar.swift")]))
1301+
XCTAssertTrue(plannedJobs[0].primaryInputs.map{ $0.file.description }.elementsEqual(["foo.swift", "bar.swift"]))
13001302
XCTAssertTrue(plannedJobs[0].commandLine.contains("-emit-const-values-path"))
13011303
XCTAssertEqual(plannedJobs[0].outputs.filter({ $0.type == .swiftConstValues }).count, 2)
13021304
XCTAssertEqual(plannedJobs[1].kind, .compile)
1303-
XCTAssertTrue(plannedJobs[1].primaryInputs.map{ $0.file.description }.elementsEqual([rebase("baz.swift")]))
1305+
XCTAssertTrue(plannedJobs[1].primaryInputs.map{ $0.file.description }.elementsEqual(["baz.swift"]))
13041306
XCTAssertTrue(plannedJobs[1].commandLine.contains("-emit-const-values-path"))
13051307
XCTAssertEqual(plannedJobs[1].outputs.filter({ $0.type == .swiftConstValues }).count, 1)
13061308
XCTAssertEqual(plannedJobs[2].kind, .link)
@@ -1331,13 +1333,12 @@ final class SwiftDriverTests: XCTestCase {
13311333
let plannedJobs = try driver.planBuild().removingAutolinkExtractJobs()
13321334
XCTAssertEqual(plannedJobs.count, 3)
13331335
XCTAssertEqual(plannedJobs[0].kind, .compile)
1334-
XCTAssertTrue(plannedJobs[0].primaryInputs.map{ $0.file.description }.elementsEqual([rebase("foo.swift"),
1335-
rebase("bar.swift")]))
1336+
XCTAssertTrue(plannedJobs[0].primaryInputs.map{ $0.file.description }.elementsEqual(["foo.swift", "bar.swift"]))
13361337
XCTAssertTrue(plannedJobs[0].commandLine.contains(subsequence: [.flag("-emit-const-values-path"), .path(.absolute(try .init(validating: "/tmp/foo.build/foo.swiftconstvalues")))]))
13371338
XCTAssertTrue(plannedJobs[0].commandLine.contains(subsequence: [.flag("-emit-const-values-path"), .path(.absolute(try .init(validating: "/tmp/foo.build/bar.swiftconstvalues")))]))
13381339
XCTAssertEqual(plannedJobs[0].outputs.filter({ $0.type == .swiftConstValues }).count, 2)
13391340
XCTAssertEqual(plannedJobs[1].kind, .compile)
1340-
XCTAssertTrue(plannedJobs[1].primaryInputs.map{ $0.file.description }.elementsEqual([rebase("baz.swift")]))
1341+
XCTAssertTrue(plannedJobs[1].primaryInputs.map{ $0.file.description }.elementsEqual(["baz.swift"]))
13411342
XCTAssertTrue(plannedJobs[1].commandLine.contains("-emit-const-values-path"))
13421343
XCTAssertEqual(plannedJobs[1].outputs.filter({ $0.type == .swiftConstValues }).count, 1)
13431344
XCTAssertTrue(plannedJobs[1].commandLine.contains(subsequence: [.flag("-emit-const-values-path"), .path(.absolute(try .init(validating: "/tmp/foo.build/baz.swiftconstvalues")))]))
@@ -3039,10 +3040,10 @@ final class SwiftDriverTests: XCTestCase {
30393040
XCTAssertEqual(emitModuleJob.outputs[0].file, try toPath("Test.swiftmodule"))
30403041
XCTAssertEqual(emitModuleJob.outputs[1].file, try toPath("Test.swiftdoc"))
30413042
XCTAssertEqual(emitModuleJob.outputs[2].file, try toPath("Test.swiftsourceinfo"))
3042-
XCTAssertEqual(emitModuleJob.outputs[3].file, try toPath("Test.swiftinterface"))
3043+
XCTAssertEqual(emitModuleJob.outputs[3].file, try VirtualPath(path: "./Test.swiftinterface"))
30433044
XCTAssertEqual(emitModuleJob.outputs[4].file, try toPath("Test.private.swiftinterface"))
30443045
XCTAssertEqual(emitModuleJob.outputs[5].file, try toPath("Test-Swift.h"))
3045-
XCTAssertEqual(emitModuleJob.outputs[6].file, try toPath("Test.tbd"))
3046+
XCTAssertEqual(emitModuleJob.outputs[6].file, try VirtualPath(path: "./Test.tbd"))
30463047
if driver1.targetTriple.isDarwin {
30473048
XCTAssertEqual(emitModuleJob.outputs[7].file, try toPath("Test.abi.json"))
30483049
}
@@ -5188,7 +5189,7 @@ final class SwiftDriverTests: XCTestCase {
51885189
// Reset the temporary store to ensure predictable results.
51895190
VirtualPath.resetTemporaryFileStore()
51905191
var driver = try Driver(args: [
5191-
"swiftc", "-emit-executable", "test.swift", "-emit-module", "-avoid-emit-module-source-info", "-experimental-emit-module-separately"
5192+
"swiftc", "-emit-executable", "test.swift", "-emit-module", "-avoid-emit-module-source-info", "-experimental-emit-module-separately", "-working-directory", localFileSystem.currentWorkingDirectory!.description
51925193
])
51935194
let plannedJobs = try driver.planBuild()
51945195

@@ -7234,6 +7235,83 @@ final class SwiftDriverTests: XCTestCase {
72347235
})
72357236
}
72367237
}
7238+
7239+
func testRelativeInputs() throws {
7240+
do {
7241+
// Inputs with relative paths with no -working-directory flag should remain relative
7242+
var driver = try Driver(args: ["swiftc",
7243+
"-target", "arm64-apple-ios13.1",
7244+
"foo.swift"])
7245+
let plannedJobs = try driver.planBuild()
7246+
let compileJob = plannedJobs[0]
7247+
XCTAssertEqual(compileJob.kind, .compile)
7248+
XCTAssertTrue(compileJob.commandLine.contains(subsequence: ["-primary-file", try toPathOption("foo.swift", isRelative: true)]))
7249+
}
7250+
7251+
do {
7252+
// Inputs with relative paths with -working-directory flag should prefix all inputs
7253+
var driver = try Driver(args: ["swiftc",
7254+
"-target", "arm64-apple-ios13.1",
7255+
"foo.swift",
7256+
"-working-directory", "/foo/bar"])
7257+
let plannedJobs = try driver.planBuild()
7258+
let compileJob = plannedJobs[0]
7259+
XCTAssertEqual(compileJob.kind, .compile)
7260+
XCTAssertTrue(compileJob.commandLine.contains(subsequence: ["-primary-file", try toPathOption("/foo/bar/foo.swift", isRelative: false)]))
7261+
}
7262+
7263+
try withTemporaryFile { fileMapFile in
7264+
let outputMapContents: ByteString = """
7265+
{
7266+
"": {
7267+
"diagnostics": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.dia",
7268+
"emit-module-diagnostics": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.emit-module.dia"
7269+
},
7270+
"foo.swift": {
7271+
"object": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/foo.o"
7272+
}
7273+
}
7274+
"""
7275+
try localFileSystem.writeFileContents(fileMapFile.path, bytes: outputMapContents)
7276+
7277+
// Inputs with relative paths should be found in output file maps
7278+
var driver = try Driver(args: ["swiftc",
7279+
"-target", "arm64-apple-ios13.1",
7280+
"foo.swift",
7281+
"-output-file-map", fileMapFile.path.description])
7282+
let plannedJobs = try driver.planBuild()
7283+
let compileJob = plannedJobs[0]
7284+
XCTAssertEqual(compileJob.kind, .compile)
7285+
XCTAssertTrue(compileJob.commandLine.contains(subsequence: ["-o", try toPathOption("/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/foo.o", isRelative: false)]))
7286+
}
7287+
7288+
try withTemporaryFile { fileMapFile in
7289+
let outputMapContents: ByteString = """
7290+
{
7291+
"": {
7292+
"diagnostics": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.dia",
7293+
"emit-module-diagnostics": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/master.emit-module.dia"
7294+
},
7295+
"/some/workingdir/foo.swift": {
7296+
"object": "/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/foo.o"
7297+
}
7298+
}
7299+
"""
7300+
try localFileSystem.writeFileContents(fileMapFile.path, bytes: outputMapContents)
7301+
7302+
// Inputs with relative paths and working-dir should use absolute paths in output file maps
7303+
var driver = try Driver(args: ["swiftc",
7304+
"-target", "arm64-apple-ios13.1",
7305+
"foo.swift",
7306+
"-working-directory", "/some/workingdir",
7307+
"-output-file-map", fileMapFile.path.description])
7308+
let plannedJobs = try driver.planBuild()
7309+
let compileJob = plannedJobs[0]
7310+
XCTAssertEqual(compileJob.kind, .compile)
7311+
XCTAssertTrue(compileJob.commandLine.contains(subsequence: ["-o", try toPathOption("/tmp/foo/.build/x86_64-apple-macosx/debug/foo.build/foo.o", isRelative: false)]))
7312+
}
7313+
7314+
}
72377315

72387316
func testRelativeResourceDir() throws {
72397317
do {
@@ -7274,7 +7352,7 @@ final class SwiftDriverTests: XCTestCase {
72747352
XCTAssertEqual(compileJob.kind, .compile)
72757353
let linkJob = plannedJobs[1]
72767354
XCTAssertEqual(linkJob.kind, .link)
7277-
XCTAssertTrue(linkJob.commandLine.contains(try toPathOption(sdkRoot.pathString + "/usr/lib/swift/linux/x86_64/swiftrt.o")))
7355+
XCTAssertTrue(linkJob.commandLine.contains(try toPathOption(sdkRoot.pathString + "/usr/lib/swift/linux/x86_64/swiftrt.o", isRelative: false)))
72787356
}
72797357
}
72807358

0 commit comments

Comments
 (0)