Skip to content

Fix .swiftsourceinfo output path when the build system provides a Project/ dir #197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 33 additions & 17 deletions Sources/SwiftDriver/Driver/Driver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,17 @@ public struct Driver {
compilerMode: compilerMode,
outputFileMap: self.outputFileMap,
moduleName: moduleOutputInfo.name)
let projectDirectory = Self.computeProjectDirectoryPath(
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
fileSystem: self.fileSystem)
self.moduleSourceInfoPath = try Self.computeModuleSourceInfoOutputPath(
&parsedOptions,
moduleOutputPath: self.moduleOutputInfo.output?.outputPath,
compilerOutputType: compilerOutputType,
compilerMode: compilerMode,
outputFileMap: self.outputFileMap,
moduleName: moduleOutputInfo.name)
moduleName: moduleOutputInfo.name,
projectDirectory: projectDirectory)
self.swiftInterfacePath = try Self.computeSupplementaryOutputPath(
&parsedOptions, type: .swiftInterface, isOutputOptions: [.emitModuleInterface],
outputPath: .emitModuleInterfacePath,
Expand Down Expand Up @@ -1719,6 +1723,19 @@ extension Driver {
return try VirtualPath(path: moduleName.appendingFileTypeExtension(type))
}

/// Determine if the build system has created a Project/ directory for auxilary outputs.
static func computeProjectDirectoryPath(moduleOutputPath: VirtualPath?,
fileSystem: FileSystem) -> VirtualPath? {
let potentialProjectDirectory = moduleOutputPath?
.parentDirectory
.appending(component: "Project")
.absolutePath
guard let projectDirectory = potentialProjectDirectory, fileSystem.exists(projectDirectory) else {
return nil
}
return .absolute(projectDirectory)
}

/// Determine the output path for a module documentation.
static func computeModuleDocOutputPath(
_ parsedOptions: inout ParsedOptions,
Expand Down Expand Up @@ -1746,7 +1763,8 @@ extension Driver {
compilerOutputType: FileType?,
compilerMode: CompilerMode,
outputFileMap: OutputFileMap?,
moduleName: String
moduleName: String,
projectDirectory: VirtualPath?
) throws -> VirtualPath? {
guard !parsedOptions.hasArgument(.avoidEmitModuleSourceInfo) else { return nil }
return try computeModuleAuxiliaryOutputPath(&parsedOptions,
Expand All @@ -1757,7 +1775,8 @@ extension Driver {
compilerOutputType: compilerOutputType,
compilerMode: compilerMode,
outputFileMap: outputFileMap,
moduleName: moduleName)
moduleName: moduleName,
projectDirectory: projectDirectory)
}


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

return try moduleOutputPath.replacingExtension(with: type)
var parentPath: VirtualPath
if let projectDirectory = projectDirectory {
// If the build system has created a Project dir for us to include the file, use it.
parentPath = projectDirectory
} else {
parentPath = moduleOutputPath.parentDirectory
}

return try parentPath.appending(component: moduleName).replacingExtension(with: type)
}

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

// If there is an output argument, derive the name from there.
if let outputPathArg = parsedOptions.getLastArgument(.o) {
let path = try VirtualPath(path: outputPathArg.asSingle)

// If the compiler output is of this type, use the argument directly.
if type == compilerOutputType {
return path
}

return try path.replacingExtension(with: type)
}

Comment on lines -1807 to -1818
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this logic is no longer used due to improvements in the module output path computation since it was written. Removing it didn't introduce any regressions in the integration tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like dead code to me, thanks!

return try VirtualPath(path: moduleName.appendingFileTypeExtension(type))
}
}
17 changes: 17 additions & 0 deletions Tests/SwiftDriverTests/SwiftDriverTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2484,6 +2484,23 @@ final class SwiftDriverTests: XCTestCase {
XCTAssertEqual(compileJob.outputs[1].file, .temporary(RelativePath("foo.swiftdoc")))
XCTAssertEqual(compileJob.outputs[2].file, .temporary(RelativePath("foo.swiftsourceinfo")))
}
// implicit with Project/ Directory
do {
try withTemporaryDirectory { path in
let projectDirPath = path.appending(component: "Project")
try localFileSystem.createDirectory(projectDirPath)
var driver = try Driver(args: ["swiftc", "-emit-module",
path.appending(component: "foo.swift").description,
"-o", path.appending(component: "foo.swiftmodule").description])
let plannedJobs = try driver.planBuild()
let mergeModuleJob = plannedJobs[1]
XCTAssertTrue(mergeModuleJob.commandLine.contains(.flag("-emit-module-source-info-path")))
XCTAssertEqual(mergeModuleJob.outputs.count, 3)
XCTAssertEqual(mergeModuleJob.outputs[0].file, .absolute(path.appending(component: "foo.swiftmodule")))
XCTAssertEqual(mergeModuleJob.outputs[1].file, .absolute(path.appending(component: "foo.swiftdoc")))
XCTAssertEqual(mergeModuleJob.outputs[2].file, .absolute(projectDirPath.appending(component: "foo.swiftsourceinfo")))
}
}
// avoid implicit swiftsourceinfo
do {
var driver = try Driver(args: ["swiftc", "-emit-module", "-avoid-emit-module-source-info", "foo.swift"])
Expand Down