Skip to content

Commit 52eff70

Browse files
authored
Merge pull request #21 from cltnschlosser/cs_emitPCH
Add generate PCH job
2 parents 96c0438 + 339020a commit 52eff70

File tree

8 files changed

+372
-8
lines changed

8 files changed

+372
-8
lines changed

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ public struct Driver {
124124
/// The path to the imported Objective-C header.
125125
public let importedObjCHeader: VirtualPath?
126126

127+
/// The path to the pch for the imported Objective-C header.
128+
public let bridgingPrecompiledHeader: VirtualPath?
129+
127130
/// Path to the dependencies file.
128131
public let dependenciesFilePath: VirtualPath?
129132

@@ -289,6 +292,9 @@ public struct Driver {
289292
self.sdkPath = Self.computeSDKPath(&parsedOptions, compilerMode: compilerMode, toolchain: toolchain, diagnosticsEngine: diagnosticEngine, env: env)
290293

291294
self.importedObjCHeader = try Self.computeImportedObjCHeader(&parsedOptions, compilerMode: compilerMode, diagnosticEngine: diagnosticEngine)
295+
self.bridgingPrecompiledHeader = try Self.computeBridgingPrecompiledHeader(&parsedOptions,
296+
importedObjCHeader: importedObjCHeader,
297+
outputFileMap: outputFileMap)
292298

293299
self.enabledSanitizers = try Self.parseSanitizerArgValues(&parsedOptions, diagnosticEngine: diagnosticEngine, toolchain: toolchain, targetTriple: targetTriple)
294300

@@ -1332,9 +1338,29 @@ extension Driver {
13321338
diagnosticEngine.emit(.error_bridging_header_module_interface)
13331339
}
13341340

1335-
let objcHeaderPath = try VirtualPath(path: objcHeaderPathArg.asSingle)
1336-
// FIXME: Precompile bridging header if requested.
1337-
return objcHeaderPath
1341+
return try VirtualPath(path: objcHeaderPathArg.asSingle)
1342+
}
1343+
1344+
/// Compute the path of the generated bridging PCH for the Objective-C header.
1345+
static func computeBridgingPrecompiledHeader(_ parsedOptions: inout ParsedOptions,
1346+
importedObjCHeader: VirtualPath?,
1347+
outputFileMap: OutputFileMap?) throws -> VirtualPath? {
1348+
guard let input = importedObjCHeader,
1349+
parsedOptions.hasFlag(positive: .enableBridgingPch, negative: .disableBridgingPch, default: true) else {
1350+
return nil
1351+
}
1352+
1353+
if let outputPath = outputFileMap?.existingOutput(inputFile: input, outputType: .pch) {
1354+
return outputPath
1355+
}
1356+
1357+
// FIXME: should have '-.*' at the end of the filename, similar to llvm::sys::fs::createTemporaryFile
1358+
let pchFileName = input.basenameWithoutExt.appendingFileTypeExtension(.pch)
1359+
if let outputDirectory = parsedOptions.getLastArgument(.pchOutputDir)?.asSingle {
1360+
return try VirtualPath(path: outputDirectory).appending(component: pchFileName)
1361+
} else {
1362+
return .temporary(RelativePath(pchFileName))
1363+
}
13381364
}
13391365
}
13401366

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extension Driver {
2626
}
2727

2828
/// Add the compiler inputs for a frontend compilation job, and return the corresponding primary set of outputs.
29-
mutating func addCompileInputs(primaryInputs: [TypedVirtualPath], inputs: inout [TypedVirtualPath], commandLine: inout [Job.ArgTemplate]) -> [TypedVirtualPath] {
29+
func addCompileInputs(primaryInputs: [TypedVirtualPath], inputs: inout [TypedVirtualPath], commandLine: inout [Job.ArgTemplate]) -> [TypedVirtualPath] {
3030
// Collect the set of input files that are part of the Swift compilation.
3131
let swiftInputFiles: [TypedVirtualPath] = inputFiles.compactMap { inputFile in
3232
if inputFile.type.isPartOfSwiftCompilation {

Sources/SwiftDriver/Jobs/FrontendJobHelpers.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ fileprivate func shouldColorDiagnostics() -> Bool {
2222

2323
extension Driver {
2424
/// Add frontend options that are common to different frontend invocations.
25-
mutating func addCommonFrontendOptions(commandLine: inout [Job.ArgTemplate]) throws {
25+
mutating func addCommonFrontendOptions(commandLine: inout [Job.ArgTemplate],
26+
requestPrecompiledObjCHeader: Bool = true) throws {
2627
// Only pass -target to the REPL or immediate modes if it was explicitly
2728
// specified on the command line.
2829
switch compilerMode {
@@ -157,7 +158,22 @@ extension Driver {
157158

158159
if let importedObjCHeader = importedObjCHeader {
159160
commandLine.appendFlag(.importObjcHeader)
160-
commandLine.appendPath(importedObjCHeader)
161+
if requestPrecompiledObjCHeader, let pch = bridgingPrecompiledHeader {
162+
if parsedOptions.contains(.pchOutputDir) {
163+
commandLine.appendPath(importedObjCHeader)
164+
switch compilerMode {
165+
case .standardCompile, .batchCompile, .repl, .immediate:
166+
commandLine.appendFlag(.pchDisableValidation)
167+
case .singleCompile:
168+
// Don't disable validation for single compile
169+
break
170+
}
171+
} else {
172+
commandLine.appendPath(pch)
173+
}
174+
} else {
175+
commandLine.appendPath(importedObjCHeader)
176+
}
161177
}
162178

163179
// Repl Jobs may include -module-name depending on the selected REPL (LLDB or integrated).
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//===--------------- GeneratePCHJob.swift - Generate PCH Job ----===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import TSCBasic
14+
import TSCUtility
15+
16+
extension Driver {
17+
mutating func generatePCHJob(input: TypedVirtualPath, output: TypedVirtualPath) throws -> Job {
18+
var inputs = [TypedVirtualPath]()
19+
var outputs = [TypedVirtualPath]()
20+
21+
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
22+
23+
inputs.append(input)
24+
commandLine.appendPath(input.file)
25+
commandLine.appendFlag(.emitPch)
26+
27+
outputs.append(output)
28+
29+
try addCommonFrontendOptions(commandLine: &commandLine, requestPrecompiledObjCHeader: false)
30+
31+
try commandLine.appendLast(.indexStorePath, from: &parsedOptions)
32+
33+
// TODO: Should this just be pch output with extension changed?
34+
if parsedOptions.hasArgument(.serializeDiagnostics), let outputDirectory = parsedOptions.getLastArgument(.pchOutputDir)?.asSingle {
35+
commandLine.appendFlag(.serializeDiagnosticsPath)
36+
let path: VirtualPath
37+
if let outputPath = outputFileMap?.existingOutput(inputFile: input.file, outputType: .diagnostics) {
38+
path = outputPath
39+
} else if let modulePath = parsedOptions.getLastArgument(.emitModulePath) {
40+
// TODO: does this hash need to be persistent?
41+
let code = UInt(bitPattern: modulePath.asSingle.hashValue)
42+
let outputName = input.file.basenameWithoutExt + "-" + String(code, radix: 36)
43+
path = try VirtualPath(path: outputDirectory).appending(component: outputName.appendingFileTypeExtension(.diagnostics))
44+
} else {
45+
// FIXME: should have '-.*' at the end of the filename, similar to llvm::sys::fs::createTemporaryFile
46+
path = .temporary(RelativePath(input.file.basenameWithoutExt.appendingFileTypeExtension(.diagnostics)))
47+
}
48+
commandLine.appendPath(path)
49+
outputs.append(.init(file: path, type: .diagnostics))
50+
}
51+
52+
if parsedOptions.hasArgument(.pchOutputDir) {
53+
try commandLine.appendLast(.pchOutputDir, from: &parsedOptions)
54+
} else {
55+
commandLine.appendFlag(.o)
56+
commandLine.appendPath(output.file)
57+
}
58+
59+
return Job(
60+
kind: .generatePCH,
61+
tool: .absolute(try toolchain.getToolPath(.swiftCompiler)),
62+
commandLine: commandLine,
63+
displayInputs: [],
64+
inputs: inputs,
65+
outputs: outputs
66+
)
67+
}
68+
}

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public struct Job: Codable, Equatable {
2020
case generateDSYM = "generate-dsym"
2121
case autolinkExtract = "autolink-extract"
2222
case emitModule = "emit-module"
23+
case generatePCH = "generate-pch"
2324
case interpret
2425
case repl
2526
case verifyDebugInfo = "verify-debug-info"

Sources/SwiftDriver/Jobs/Planning.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ extension Driver {
4545
}
4646
}
4747
}
48+
49+
if let importedObjCHeader = importedObjCHeader,
50+
let bridgingPrecompiledHeader = bridgingPrecompiledHeader {
51+
jobs.append(try generatePCHJob(input: .init(file: importedObjCHeader, type: .objcHeader),
52+
output: .init(file: bridgingPrecompiledHeader, type: .pch)))
53+
}
4854

4955
// If we should create emit module job, do so.
5056
if shouldCreateEmitModuleJob {

Sources/SwiftDriver/Utilities/VirtualPath.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,24 @@ public enum VirtualPath: Hashable {
9191
return ""
9292
}
9393
}
94+
95+
/// Returns the virtual path with an additional literal component appended.
96+
///
97+
/// This should not be used with `.standardInput` or `.standardOutput`.
98+
public func appending(component: String) -> VirtualPath {
99+
switch self {
100+
case .absolute(let path):
101+
return .absolute(path.appending(component: component))
102+
case .relative(let path):
103+
// FIXME: TSCBasic should probably have RelativePath.appending(component:)
104+
return .relative(RelativePath(path.pathString + "/" + component))
105+
case .temporary(let path):
106+
return .temporary(RelativePath(path.pathString + "/" + component))
107+
case .standardInput, .standardOutput:
108+
assertionFailure("Can't append path component to standard in/out")
109+
return self
110+
}
111+
}
94112
}
95113

96114
extension VirtualPath: Codable {

0 commit comments

Comments
 (0)