Skip to content

Commit 0fc317a

Browse files
authored
Merge pull request #197 from owenv/sourceinfo-fixes
Fix .swiftsourceinfo output path when the build system provides a Project/ dir
2 parents 777a4bb + 476ea42 commit 0fc317a

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
@@ -421,13 +421,17 @@ public struct Driver {
421421
compilerMode: compilerMode,
422422
outputFileMap: self.outputFileMap,
423423
moduleName: moduleOutputInfo.name)
424+
let projectDirectory = Self.computeProjectDirectoryPath(
425+
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
426+
fileSystem: self.fileSystem)
424427
self.moduleSourceInfoPath = try Self.computeModuleSourceInfoOutputPath(
425428
&parsedOptions,
426429
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
427430
compilerOutputType: compilerOutputType,
428431
compilerMode: compilerMode,
429432
outputFileMap: self.outputFileMap,
430-
moduleName: moduleOutputInfo.name)
433+
moduleName: moduleOutputInfo.name,
434+
projectDirectory: projectDirectory)
431435
self.swiftInterfacePath = try Self.computeSupplementaryOutputPath(
432436
&parsedOptions, type: .swiftInterface, isOutputOptions: [.emitModuleInterface],
433437
outputPath: .emitModuleInterfacePath,
@@ -1732,6 +1736,19 @@ extension Driver {
17321736
return try VirtualPath(path: moduleName.appendingFileTypeExtension(type))
17331737
}
17341738

1739+
/// Determine if the build system has created a Project/ directory for auxilary outputs.
1740+
static func computeProjectDirectoryPath(moduleOutputPath: VirtualPath?,
1741+
fileSystem: FileSystem) -> VirtualPath? {
1742+
let potentialProjectDirectory = moduleOutputPath?
1743+
.parentDirectory
1744+
.appending(component: "Project")
1745+
.absolutePath
1746+
guard let projectDirectory = potentialProjectDirectory, fileSystem.exists(projectDirectory) else {
1747+
return nil
1748+
}
1749+
return .absolute(projectDirectory)
1750+
}
1751+
17351752
/// Determine the output path for a module documentation.
17361753
static func computeModuleDocOutputPath(
17371754
_ parsedOptions: inout ParsedOptions,
@@ -1759,7 +1776,8 @@ extension Driver {
17591776
compilerOutputType: FileType?,
17601777
compilerMode: CompilerMode,
17611778
outputFileMap: OutputFileMap?,
1762-
moduleName: String
1779+
moduleName: String,
1780+
projectDirectory: VirtualPath?
17631781
) throws -> VirtualPath? {
17641782
guard !parsedOptions.hasArgument(.avoidEmitModuleSourceInfo) else { return nil }
17651783
return try computeModuleAuxiliaryOutputPath(&parsedOptions,
@@ -1770,7 +1788,8 @@ extension Driver {
17701788
compilerOutputType: compilerOutputType,
17711789
compilerMode: compilerMode,
17721790
outputFileMap: outputFileMap,
1773-
moduleName: moduleName)
1791+
moduleName: moduleName,
1792+
projectDirectory: projectDirectory)
17741793
}
17751794

17761795

@@ -1784,7 +1803,8 @@ extension Driver {
17841803
compilerOutputType: FileType?,
17851804
compilerMode: CompilerMode,
17861805
outputFileMap: OutputFileMap?,
1787-
moduleName: String
1806+
moduleName: String,
1807+
projectDirectory: VirtualPath? = nil
17881808
) throws -> VirtualPath? {
17891809
// If there is an explicit argument for the output path, use that
17901810
if let outputPathArg = parsedOptions.getLastArgument(outputPath) {
@@ -1809,26 +1829,22 @@ extension Driver {
18091829
_ = parsedOptions.hasArgument(isOutput)
18101830
}
18111831

1812-
return try moduleOutputPath.replacingExtension(with: type)
1832+
var parentPath: VirtualPath
1833+
if let projectDirectory = projectDirectory {
1834+
// If the build system has created a Project dir for us to include the file, use it.
1835+
parentPath = projectDirectory
1836+
} else {
1837+
parentPath = moduleOutputPath.parentDirectory
1838+
}
1839+
1840+
return try parentPath.appending(component: moduleName).replacingExtension(with: type)
18131841
}
18141842

18151843
// If the output option was not provided, don't produce this output at all.
18161844
guard let isOutput = isOutput, parsedOptions.hasArgument(isOutput) else {
18171845
return nil
18181846
}
18191847

1820-
// If there is an output argument, derive the name from there.
1821-
if let outputPathArg = parsedOptions.getLastArgument(.o) {
1822-
let path = try VirtualPath(path: outputPathArg.asSingle)
1823-
1824-
// If the compiler output is of this type, use the argument directly.
1825-
if type == compilerOutputType {
1826-
return path
1827-
}
1828-
1829-
return try path.replacingExtension(with: type)
1830-
}
1831-
18321848
return try VirtualPath(path: moduleName.appendingFileTypeExtension(type))
18331849
}
18341850
}

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2515,6 +2515,23 @@ final class SwiftDriverTests: XCTestCase {
25152515
XCTAssertEqual(compileJob.outputs[1].file, .temporary(RelativePath("foo.swiftdoc")))
25162516
XCTAssertEqual(compileJob.outputs[2].file, .temporary(RelativePath("foo.swiftsourceinfo")))
25172517
}
2518+
// implicit with Project/ Directory
2519+
do {
2520+
try withTemporaryDirectory { path in
2521+
let projectDirPath = path.appending(component: "Project")
2522+
try localFileSystem.createDirectory(projectDirPath)
2523+
var driver = try Driver(args: ["swiftc", "-emit-module",
2524+
path.appending(component: "foo.swift").description,
2525+
"-o", path.appending(component: "foo.swiftmodule").description])
2526+
let plannedJobs = try driver.planBuild()
2527+
let mergeModuleJob = plannedJobs[1]
2528+
XCTAssertTrue(mergeModuleJob.commandLine.contains(.flag("-emit-module-source-info-path")))
2529+
XCTAssertEqual(mergeModuleJob.outputs.count, 3)
2530+
XCTAssertEqual(mergeModuleJob.outputs[0].file, .absolute(path.appending(component: "foo.swiftmodule")))
2531+
XCTAssertEqual(mergeModuleJob.outputs[1].file, .absolute(path.appending(component: "foo.swiftdoc")))
2532+
XCTAssertEqual(mergeModuleJob.outputs[2].file, .absolute(projectDirPath.appending(component: "foo.swiftsourceinfo")))
2533+
}
2534+
}
25182535
// avoid implicit swiftsourceinfo
25192536
do {
25202537
var driver = try Driver(args: ["swiftc", "-emit-module", "-avoid-emit-module-source-info", "foo.swift"])

0 commit comments

Comments
 (0)