Skip to content

Commit 476ea42

Browse files
committed
Fix .swiftsourceinfo output path when the build system provides a Project/ directory
1 parent fba6877 commit 476ea42

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -415,13 +415,17 @@ public struct Driver {
415415
compilerMode: compilerMode,
416416
outputFileMap: self.outputFileMap,
417417
moduleName: moduleOutputInfo.name)
418+
let projectDirectory = Self.computeProjectDirectoryPath(
419+
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
420+
fileSystem: self.fileSystem)
418421
self.moduleSourceInfoPath = try Self.computeModuleSourceInfoOutputPath(
419422
&parsedOptions,
420423
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
421424
compilerOutputType: compilerOutputType,
422425
compilerMode: compilerMode,
423426
outputFileMap: self.outputFileMap,
424-
moduleName: moduleOutputInfo.name)
427+
moduleName: moduleOutputInfo.name,
428+
projectDirectory: projectDirectory)
425429
self.swiftInterfacePath = try Self.computeSupplementaryOutputPath(
426430
&parsedOptions, type: .swiftInterface, isOutputOptions: [.emitModuleInterface],
427431
outputPath: .emitModuleInterfacePath,
@@ -1719,6 +1723,19 @@ extension Driver {
17191723
return try VirtualPath(path: moduleName.appendingFileTypeExtension(type))
17201724
}
17211725

1726+
/// Determine if the build system has created a Project/ directory for auxilary outputs.
1727+
static func computeProjectDirectoryPath(moduleOutputPath: VirtualPath?,
1728+
fileSystem: FileSystem) -> VirtualPath? {
1729+
let potentialProjectDirectory = moduleOutputPath?
1730+
.parentDirectory
1731+
.appending(component: "Project")
1732+
.absolutePath
1733+
guard let projectDirectory = potentialProjectDirectory, fileSystem.exists(projectDirectory) else {
1734+
return nil
1735+
}
1736+
return .absolute(projectDirectory)
1737+
}
1738+
17221739
/// Determine the output path for a module documentation.
17231740
static func computeModuleDocOutputPath(
17241741
_ parsedOptions: inout ParsedOptions,
@@ -1746,7 +1763,8 @@ extension Driver {
17461763
compilerOutputType: FileType?,
17471764
compilerMode: CompilerMode,
17481765
outputFileMap: OutputFileMap?,
1749-
moduleName: String
1766+
moduleName: String,
1767+
projectDirectory: VirtualPath?
17501768
) throws -> VirtualPath? {
17511769
guard !parsedOptions.hasArgument(.avoidEmitModuleSourceInfo) else { return nil }
17521770
return try computeModuleAuxiliaryOutputPath(&parsedOptions,
@@ -1757,7 +1775,8 @@ extension Driver {
17571775
compilerOutputType: compilerOutputType,
17581776
compilerMode: compilerMode,
17591777
outputFileMap: outputFileMap,
1760-
moduleName: moduleName)
1778+
moduleName: moduleName,
1779+
projectDirectory: projectDirectory)
17611780
}
17621781

17631782

@@ -1771,7 +1790,8 @@ extension Driver {
17711790
compilerOutputType: FileType?,
17721791
compilerMode: CompilerMode,
17731792
outputFileMap: OutputFileMap?,
1774-
moduleName: String
1793+
moduleName: String,
1794+
projectDirectory: VirtualPath? = nil
17751795
) throws -> VirtualPath? {
17761796
// If there is an explicit argument for the output path, use that
17771797
if let outputPathArg = parsedOptions.getLastArgument(outputPath) {
@@ -1796,26 +1816,22 @@ extension Driver {
17961816
_ = parsedOptions.hasArgument(isOutput)
17971817
}
17981818

1799-
return try moduleOutputPath.replacingExtension(with: type)
1819+
var parentPath: VirtualPath
1820+
if let projectDirectory = projectDirectory {
1821+
// If the build system has created a Project dir for us to include the file, use it.
1822+
parentPath = projectDirectory
1823+
} else {
1824+
parentPath = moduleOutputPath.parentDirectory
1825+
}
1826+
1827+
return try parentPath.appending(component: moduleName).replacingExtension(with: type)
18001828
}
18011829

18021830
// If the output option was not provided, don't produce this output at all.
18031831
guard let isOutput = isOutput, parsedOptions.hasArgument(isOutput) else {
18041832
return nil
18051833
}
18061834

1807-
// If there is an output argument, derive the name from there.
1808-
if let outputPathArg = parsedOptions.getLastArgument(.o) {
1809-
let path = try VirtualPath(path: outputPathArg.asSingle)
1810-
1811-
// If the compiler output is of this type, use the argument directly.
1812-
if type == compilerOutputType {
1813-
return path
1814-
}
1815-
1816-
return try path.replacingExtension(with: type)
1817-
}
1818-
18191835
return try VirtualPath(path: moduleName.appendingFileTypeExtension(type))
18201836
}
18211837
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2484,6 +2484,23 @@ final class SwiftDriverTests: XCTestCase {
24842484
XCTAssertEqual(compileJob.outputs[1].file, .temporary(RelativePath("foo.swiftdoc")))
24852485
XCTAssertEqual(compileJob.outputs[2].file, .temporary(RelativePath("foo.swiftsourceinfo")))
24862486
}
2487+
// implicit with Project/ Directory
2488+
do {
2489+
try withTemporaryDirectory { path in
2490+
let projectDirPath = path.appending(component: "Project")
2491+
try localFileSystem.createDirectory(projectDirPath)
2492+
var driver = try Driver(args: ["swiftc", "-emit-module",
2493+
path.appending(component: "foo.swift").description,
2494+
"-o", path.appending(component: "foo.swiftmodule").description])
2495+
let plannedJobs = try driver.planBuild()
2496+
let mergeModuleJob = plannedJobs[1]
2497+
XCTAssertTrue(mergeModuleJob.commandLine.contains(.flag("-emit-module-source-info-path")))
2498+
XCTAssertEqual(mergeModuleJob.outputs.count, 3)
2499+
XCTAssertEqual(mergeModuleJob.outputs[0].file, .absolute(path.appending(component: "foo.swiftmodule")))
2500+
XCTAssertEqual(mergeModuleJob.outputs[1].file, .absolute(path.appending(component: "foo.swiftdoc")))
2501+
XCTAssertEqual(mergeModuleJob.outputs[2].file, .absolute(projectDirPath.appending(component: "foo.swiftsourceinfo")))
2502+
}
2503+
}
24872504
// avoid implicit swiftsourceinfo
24882505
do {
24892506
var driver = try Driver(args: ["swiftc", "-emit-module", "-avoid-emit-module-source-info", "foo.swift"])

0 commit comments

Comments
 (0)