Skip to content

Commit ef868d6

Browse files
authored
Merge pull request #53 from DougGregor/moar-output
Plumb through primary files for parsable output
2 parents ba97bc7 + 9e2f497 commit ef868d6

File tree

12 files changed

+118
-96
lines changed

12 files changed

+118
-96
lines changed

Package.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ let package = Package(
1010
.executable(
1111
name: "swift-driver",
1212
targets: ["swift-driver"]),
13+
.library(
14+
name: "SwiftDriver",
15+
targets: ["SwiftDriver"]),
1316
],
1417
dependencies: [
1518
.package(url: "https://github.com/apple/swift-tools-support-core.git", .branch("master")),

Sources/SwiftDriver/Driver/Driver.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ extension Driver {
370370
// Start up an executor and perform the build.
371371
let mainOutput = jobs.last!.outputs.first!
372372
let jobExecutor = JobExecutor(jobs: jobs, resolver: resolver, executorDelegate: executorDelegate)
373-
try jobExecutor.build(mainOutput)
373+
try jobExecutor.build(mainOutput.file)
374374
}
375375

376376
/// Returns the path to the Swift binary.

Sources/SwiftDriver/Driver/ToolExecutionDelegate.swift

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import TSCBasic
22

33
/// Delegate for printing execution information on the command-line.
44
struct ToolExecutionDelegate: JobExecutorDelegate {
5-
65
enum Mode {
76
case verbose
87
case parsableOutput
@@ -20,11 +19,15 @@ struct ToolExecutionDelegate: JobExecutorDelegate {
2019
stdoutStream.flush()
2120
case .parsableOutput:
2221

22+
// Compute the outputs for the message.
23+
let outputs: [BeganMessage.Output] = job.outputs.map {
24+
.init(path: $0.file.name, type: $0.type.rawValue)
25+
}
26+
2327
let beganMessage = BeganMessage(
2428
pid: pid,
25-
// FIXME: This needs to be the primary inputs :/
26-
inputs: job.inputs.map{ $0.name },
27-
outputs: job.outputs.map{ .init(path: $0.name, type: "object") },
29+
inputs: job.displayInputs.map{ $0.file.name },
30+
outputs: outputs,
2831
commandExecutable: arguments[0],
2932
commandArguments: arguments[1...].map{ String($0) }
3033
)
@@ -34,22 +37,24 @@ struct ToolExecutionDelegate: JobExecutorDelegate {
3437
}
3538
}
3639

37-
func jobHadOutput(job: Job, output: String) {
38-
// FIXME: Merge with job finished delegate.
39-
// FIXME: Need to see how current driver handles stdout/stderr.
40-
stdoutStream <<< output
41-
stdoutStream.flush()
42-
}
43-
44-
func jobFinished(job: Job, success: Bool, pid: Int) {
40+
func jobFinished(job: Job, result: ProcessResult, pid: Int) {
4541
switch mode {
4642
case .regular, .verbose:
4743
break
4844
case .parsableOutput:
49-
// FIXME: Get the actual exit status.
50-
let finishedMessage = FinishedMessage(exitStatus: success ? 0 : 1, pid: pid, output: nil)
51-
let message = ParsableMessage.finishedMessage(name: job.kind.rawValue, msg: finishedMessage)
52-
emit(message)
45+
46+
switch result.exitStatus {
47+
case .terminated(let code):
48+
let output = (try? result.utf8Output() + result.utf8stderrOutput()) ?? ""
49+
let finishedMessage = FinishedMessage(exitStatus: Int(code), pid: pid, output: output.isEmpty ? nil : output)
50+
let message = ParsableMessage.finishedMessage(name: job.kind.rawValue, msg: finishedMessage)
51+
emit(message)
52+
53+
case .signalled:
54+
// FIXME: Implement this.
55+
break
56+
}
57+
5358
}
5459
}
5560

Sources/SwiftDriver/Execution/JobExecutor.swift

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,8 @@ public protocol JobExecutorDelegate {
5454
/// Called when a job starts executing.
5555
func jobStarted(job: Job, arguments: [String], pid: Int)
5656

57-
/// Called when job had any output.
58-
func jobHadOutput(job: Job, output: String)
59-
6057
/// Called when a job finished.
61-
func jobFinished(job: Job, success: Bool, pid: Int)
58+
func jobFinished(job: Job, result: ProcessResult, pid: Int)
6259
}
6360

6461
public final class JobExecutor {
@@ -121,8 +118,8 @@ public final class JobExecutor {
121118
var producerMap: [VirtualPath: Job] = [:]
122119
for job in jobs {
123120
for output in job.outputs {
124-
assert(!producerMap.keys.contains(output), "multiple producers for output \(output): \(job) \(producerMap[output]!)")
125-
producerMap[output] = job
121+
assert(!producerMap.keys.contains(output.file), "multiple producers for output \(output): \(job) \(producerMap[output.file]!)")
122+
producerMap[output.file] = job
126123
}
127124
}
128125

@@ -189,7 +186,7 @@ class ExecuteJobRule: LLBuildRule {
189186
let context = engine.jobExecutorContext
190187

191188
for (idx, input) in key.job.inputs.enumerated() {
192-
if let producingJob = context.producerMap[input] {
189+
if let producingJob = context.producerMap[input.file] {
193190
let key = ExecuteJobRule.RuleKey(job: producingJob)
194191
engine.taskNeedsInput(key, inputID: idx)
195192
}
@@ -238,23 +235,25 @@ class ExecuteJobRule: LLBuildRule {
238235
let result = try process.waitUntilExit()
239236
let success = result.exitStatus == .terminated(code: 0)
240237

241-
let output = try result.utf8Output() + result.utf8stderrOutput()
242-
243-
// FIXME: We should stream this.
238+
// Inform the delegate about job finishing.
244239
context.delegateQueue.async {
245-
context.executorDelegate?.jobHadOutput(job: job, output: output)
240+
context.executorDelegate?.jobFinished(job: job, result: result, pid: pid)
246241
}
247242

248243
value = .jobExecution(success: success)
249244
} catch {
245+
context.delegateQueue.async {
246+
let result = ProcessResult(
247+
arguments: [],
248+
exitStatus: .terminated(code: 1),
249+
output: Result.success([]),
250+
stderrOutput: Result.success([])
251+
)
252+
context.executorDelegate?.jobFinished(job: job, result: result, pid: 0)
253+
}
250254
value = .jobExecution(success: false)
251255
}
252256

253-
// Inform the delegate about job finishing.
254-
context.delegateQueue.async {
255-
context.executorDelegate?.jobFinished(job: job, success: value.success, pid: pid)
256-
}
257-
258257
engine.taskIsComplete(value)
259258
}
260259
}

Sources/SwiftDriver/Jobs/CompileJob.swift

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ extension Driver {
1515
}
1616

1717
/// Add the compiler inputs for a frontend compilation job, and return the corresponding primary set of outputs.
18-
mutating func addCompileInputs(primaryInputs: [TypedVirtualPath], inputs: inout [VirtualPath], commandLine: inout [Job.ArgTemplate]) -> [TypedVirtualPath] {
18+
mutating func addCompileInputs(primaryInputs: [TypedVirtualPath], inputs: inout [TypedVirtualPath], commandLine: inout [Job.ArgTemplate]) -> [TypedVirtualPath] {
1919
// Collect the set of input files that are part of the Swift compilation.
20-
let swiftInputFiles: [VirtualPath] = inputFiles.compactMap { inputFile in
20+
let swiftInputFiles: [TypedVirtualPath] = inputFiles.compactMap { inputFile in
2121
if inputFile.type.isPartOfSwiftCompilation {
22-
return inputFile.file
22+
return inputFile
2323
}
2424

2525
return nil
@@ -29,7 +29,7 @@ extension Driver {
2929
// we can check more quickly.
3030
let usesPrimaryFileInputs = compilerMode.usesPrimaryFileInputs
3131
assert(!usesPrimaryFileInputs || !primaryInputs.isEmpty)
32-
let primaryInputFiles: Set<VirtualPath> = usesPrimaryFileInputs ? Set(primaryInputs.map { $0.file }) : Set()
32+
let primaryInputFiles = usesPrimaryFileInputs ? Set(primaryInputs) : Set()
3333

3434
// Add each of the input files.
3535
// FIXME: Use/create input file lists and primary input file lists.
@@ -41,14 +41,15 @@ extension Driver {
4141
if isPrimary {
4242
commandLine.appendFlag(.primary_file)
4343
}
44-
commandLine.append(.path(input))
44+
commandLine.append(.path(input.file))
4545

4646
// If there is a primary output, add it.
4747
if isPrimary, let compilerOutputType = compilerOutputType {
48-
primaryOutputs.append(
49-
TypedVirtualPath(
50-
file: (outputFileMap ?? OutputFileMap()).getOutput(inputFile: input, outputType: compilerOutputType),
51-
type: compilerOutputType))
48+
let output = (outputFileMap ?? OutputFileMap()).getOutput(
49+
inputFile: input.file,
50+
outputType: compilerOutputType
51+
)
52+
primaryOutputs.append(TypedVirtualPath(file: output, type: compilerOutputType))
5253
}
5354
}
5455

@@ -59,7 +60,7 @@ extension Driver {
5960
mutating func compileJob(primaryInputs: [TypedVirtualPath], outputType: FileType?,
6061
allOutputs: inout [TypedVirtualPath]) throws -> Job {
6162
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
62-
var inputs: [VirtualPath] = []
63+
var inputs: [TypedVirtualPath] = []
6364
var outputs: [TypedVirtualPath] = []
6465

6566
commandLine.appendFlag("-frontend")
@@ -123,7 +124,14 @@ extension Driver {
123124
try commandLine.appendLast(.disable_autolinking_runtime_compatibility_dynamic_replacements, from: &parsedOptions)
124125

125126
allOutputs += outputs
126-
return Job(kind: .compile, tool: swiftCompiler, commandLine: commandLine, inputs: inputs, outputs: outputs.map { $0.file })
127+
return Job(
128+
kind: .compile,
129+
tool: swiftCompiler,
130+
commandLine: commandLine,
131+
displayInputs: primaryInputs,
132+
inputs: inputs,
133+
outputs: outputs
134+
)
127135
}
128136
}
129137

Sources/SwiftDriver/Jobs/Job.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ public struct Job: Codable, Equatable {
2323
/// The command-line arguments of the job.
2424
public var commandLine: [ArgTemplate]
2525

26+
/// The list of inputs to use for displaying purposes.
27+
public var displayInputs: [TypedVirtualPath]
28+
2629
/// The list of inputs for this job.
27-
// FIXME: Figure out the exact type that is required here.
28-
public var inputs: [VirtualPath]
30+
public var inputs: [TypedVirtualPath]
2931

3032
/// The outputs produced by the job.
31-
// FIXME: Figure out the exact type that is required here.
32-
public var outputs: [VirtualPath]
33+
public var outputs: [TypedVirtualPath]
3334

3435
/// The kind of job.
3536
public var kind: Kind
@@ -38,12 +39,14 @@ public struct Job: Codable, Equatable {
3839
kind: Kind,
3940
tool: VirtualPath,
4041
commandLine: [ArgTemplate],
41-
inputs: [VirtualPath],
42-
outputs: [VirtualPath]
42+
displayInputs: [TypedVirtualPath]? = nil,
43+
inputs: [TypedVirtualPath],
44+
outputs: [TypedVirtualPath]
4345
) {
4446
self.kind = kind
4547
self.tool = tool
4648
self.commandLine = commandLine
49+
self.displayInputs = displayInputs ?? []
4750
self.inputs = inputs
4851
self.outputs = outputs
4952
}

Sources/SwiftDriver/Jobs/LinkJob.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ extension Driver {
364364
}
365365

366366
// Add inputs.
367-
let inputFiles = inputs.map { $0.file }
368-
commandLine.append(contentsOf: inputFiles.map { .path($0) })
367+
let inputFiles = inputs
368+
commandLine.append(contentsOf: inputFiles.map { .path($0.file) })
369369

370370
// Add the output
371371
commandLine.appendFlag("-o")
@@ -382,7 +382,7 @@ extension Driver {
382382
tool: .absolute(try toolchain.getToolPath(linkerTool)),
383383
commandLine: commandLine,
384384
inputs: inputFiles,
385-
outputs: [outputFile]
385+
outputs: [.init(file: outputFile, type: .object)]
386386
)
387387
}
388388
}

Sources/SwiftDriver/Jobs/MergeModuleJob.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import TSCBasic
33
extension Driver {
44
mutating func mergeModuleJob(inputs allInputs: [TypedVirtualPath]) throws -> Job {
55
var commandLine: [Job.ArgTemplate] = swiftCompilerPrefixArgs.map { Job.ArgTemplate.flag($0) }
6-
var inputs: [VirtualPath] = []
7-
var outputs: [VirtualPath] = [moduleOutput!.outputPath]
6+
var inputs: [TypedVirtualPath] = []
7+
var outputs: [TypedVirtualPath] = [
8+
TypedVirtualPath(file: moduleOutput!.outputPath, type: .swiftModule)
9+
]
810

911
commandLine.appendFlags("-frontend", "-merge-modules", "-emit-module")
1012

@@ -14,7 +16,7 @@ extension Driver {
1416
for input in allInputs {
1517
assert(input.type == .swiftModule)
1618
commandLine.append(.path(input.file))
17-
inputs.append(input.file)
19+
inputs.append(input)
1820
}
1921

2022
// Tell all files to parse as library, which is necessary to load them as
@@ -33,19 +35,19 @@ extension Driver {
3335
// FIXME: Add MSVC runtime library flags
3436

3537
// Add suppplementable outputs.
36-
func addSupplementalOutput(path: VirtualPath?, flag: String) {
38+
func addSupplementalOutput(path: VirtualPath?, flag: String, type: FileType) {
3739
guard let path = path else { return }
3840

3941
commandLine.appendFlag(flag)
4042
commandLine.appendPath(path)
41-
outputs.append(path)
43+
outputs.append(.init(file: path, type: type))
4244
}
4345

44-
addSupplementalOutput(path: moduleDocOutputPath, flag: "-emit-module-doc-path")
45-
addSupplementalOutput(path: swiftInterfacePath, flag: "-emit-module-interface-path")
46-
addSupplementalOutput(path: serializedDiagnosticsFilePath, flag: "-serialize-diagnostics-path")
47-
addSupplementalOutput(path: objcGeneratedHeaderPath, flag: "-emit-objc-header-path")
48-
addSupplementalOutput(path: tbdPath, flag: "-emit-tbd-path")
46+
addSupplementalOutput(path: moduleDocOutputPath, flag: "-emit-module-doc-path", type: .swiftDocumentation)
47+
addSupplementalOutput(path: swiftInterfacePath, flag: "-emit-module-interface-path", type: .swiftInterface)
48+
addSupplementalOutput(path: serializedDiagnosticsFilePath, flag: "-serialize-diagnostics-path", type: .diagnostics)
49+
addSupplementalOutput(path: objcGeneratedHeaderPath, flag: "-emit-objc-header-path", type: .objcHeader)
50+
addSupplementalOutput(path: tbdPath, flag: "-emit-tbd-path", type: .tbd)
4951

5052
commandLine.appendFlag(.o)
5153
commandLine.appendPath(moduleOutput!.outputPath)

Sources/SwiftDriver/Utilities/FileType.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
///
33
/// The raw values for these enumerations describe the default extension for]
44
/// the file type.
5-
public enum FileType: String, Hashable, CaseIterable {
5+
public enum FileType: String, Hashable, CaseIterable, Codable {
66
/// Swift source file.
77
case swift
88

Sources/SwiftDriver/Utilities/TypedVirtualPath.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/// A path for which the type of the input is known.
2-
public struct TypedVirtualPath: Hashable {
2+
public struct TypedVirtualPath: Hashable, Codable {
33
/// The file this input refers to.
44
public let file: VirtualPath
55

0 commit comments

Comments
 (0)