Skip to content

Commit 24e01f1

Browse files
hartbitaciidgh
authored andcommitted
Enable option to use llbuild as a library
1 parent 8516092 commit 24e01f1

File tree

6 files changed

+349
-40
lines changed

6 files changed

+349
-40
lines changed

Sources/Build/BuildDelegate.swift

Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2018 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Basic
12+
import Utility
13+
import SPMLLBuild
14+
15+
/// Diagnostic error when a llbuild command encounters an error.
16+
struct LLBuildCommandErrorDiagnostic: DiagnosticData {
17+
static let id = DiagnosticID(
18+
type: LLBuildCommandErrorDiagnostic.self,
19+
name: "org.swift.diags.llbuild-command-error",
20+
defaultBehavior: .error,
21+
description: { $0 <<< { $0.message } }
22+
)
23+
24+
let message: String
25+
}
26+
27+
/// Diagnostic warning when a llbuild command encounters a warning.
28+
struct LLBuildCommandWarningDiagnostic: DiagnosticData {
29+
static let id = DiagnosticID(
30+
type: LLBuildCommandWarningDiagnostic.self,
31+
name: "org.swift.diags.llbuild-command-warning",
32+
defaultBehavior: .warning,
33+
description: { $0 <<< { $0.message } }
34+
)
35+
36+
let message: String
37+
}
38+
39+
/// Diagnostic note when a llbuild command encounters a warning.
40+
struct LLBuildCommandNoteDiagnostic: DiagnosticData {
41+
static let id = DiagnosticID(
42+
type: LLBuildCommandNoteDiagnostic.self,
43+
name: "org.swift.diags.llbuild-command-note",
44+
defaultBehavior: .note,
45+
description: { $0 <<< { $0.message } }
46+
)
47+
48+
let message: String
49+
}
50+
51+
/// Diagnostic error when llbuild detects a cycle.
52+
struct LLBuildCycleErrorDiagnostic: DiagnosticData {
53+
static let id = DiagnosticID(
54+
type: LLBuildCycleErrorDiagnostic.self,
55+
name: "org.swift.diags.llbuild-cycle",
56+
defaultBehavior: .error,
57+
description: {
58+
$0 <<< "build cycle detected: "
59+
$0 <<< { $0.rules.map({ $0.key }).joined(separator: ", ") }
60+
}
61+
)
62+
63+
let rules: [BuildKey]
64+
}
65+
66+
/// Diagnostic error from llbuild
67+
struct LLBuildErrorDiagnostic: DiagnosticData {
68+
static let id = DiagnosticID(
69+
type: LLBuildErrorDiagnostic.self,
70+
name: "org.swift.diags.llbuild-error",
71+
defaultBehavior: .error,
72+
description: {
73+
$0 <<< { $0.message }
74+
}
75+
)
76+
77+
let message: String
78+
}
79+
80+
/// Diagnostic warning from llbuild
81+
struct LLBuildWarningDiagnostic: DiagnosticData {
82+
static let id = DiagnosticID(
83+
type: LLBuildWarningDiagnostic.self,
84+
name: "org.swift.diags.llbuild-warning",
85+
defaultBehavior: .warning,
86+
description: {
87+
$0 <<< { $0.message }
88+
}
89+
)
90+
91+
let message: String
92+
}
93+
94+
/// Diagnostic note from llbuild
95+
struct LLBuildNoteDiagnostic: DiagnosticData {
96+
static let id = DiagnosticID(
97+
type: LLBuildNoteDiagnostic.self,
98+
name: "org.swift.diags.llbuild-note",
99+
defaultBehavior: .note,
100+
description: {
101+
$0 <<< { $0.message }
102+
}
103+
)
104+
105+
let message: String
106+
}
107+
108+
/// Missing inptus from LLBuild
109+
struct LLBuildMissingInputs: DiagnosticData {
110+
static let id = DiagnosticID(
111+
type: LLBuildMissingInputs.self,
112+
name: "org.swift.diags.llbuild-missing-inputs",
113+
defaultBehavior: .error,
114+
description: {
115+
$0 <<< "couldn't build "
116+
$0 <<< { $0.output.key }
117+
$0 <<< " because of missing inputs: "
118+
$0 <<< { $0.inputs.map({ $0.key }).joined(separator: ", ") }
119+
}
120+
)
121+
122+
let output: BuildKey
123+
let inputs: [BuildKey]
124+
}
125+
126+
/// Multiple producers from LLBuild
127+
struct LLBuildMultipleProducers: DiagnosticData {
128+
static let id = DiagnosticID(
129+
type: LLBuildMultipleProducers.self,
130+
name: "org.swift.diags.llbuild-multiple-producers",
131+
defaultBehavior: .error,
132+
description: {
133+
$0 <<< "couldn't build "
134+
$0 <<< { $0.output.key }
135+
$0 <<< " because of multiple producers: "
136+
$0 <<< { $0.commands.map({ $0.description }).joined(separator: ", ") }
137+
}
138+
)
139+
140+
let output: BuildKey
141+
let commands: [SPMLLBuild.Command]
142+
}
143+
144+
/// Command error from LLBuild
145+
struct LLBuildCommandError: DiagnosticData {
146+
static let id = DiagnosticID(
147+
type: LLBuildCommandError.self,
148+
name: "org.swift.diags.llbuild-command-error",
149+
defaultBehavior: .error,
150+
description: {
151+
$0 <<< "command "
152+
$0 <<< { $0.command.description }
153+
$0 <<< " failed: "
154+
$0 <<< { $0.message }
155+
}
156+
)
157+
158+
let command: SPMLLBuild.Command
159+
let message: String
160+
}
161+
162+
extension SPMLLBuild.Diagnostic: DiagnosticDataConvertible {
163+
public var diagnosticData: DiagnosticData {
164+
switch kind {
165+
case .error: return LLBuildErrorDiagnostic(message: message)
166+
case .warning: return LLBuildWarningDiagnostic(message: message)
167+
case .note: return LLBuildNoteDiagnostic(message: message)
168+
}
169+
}
170+
}
171+
172+
private let newLineByte: UInt8 = 10
173+
public final class BuildDelegate: BuildSystemDelegate {
174+
private let diagnostics: DiagnosticsEngine
175+
public var outputStream: OutputByteStream
176+
public var onCommmandFailure: (() -> Void)?
177+
178+
public init(diagnostics: DiagnosticsEngine, outputStream: OutputByteStream = stdoutStream) {
179+
self.diagnostics = diagnostics
180+
self.outputStream = outputStream
181+
}
182+
183+
public var fs: SPMLLBuild.FileSystem? {
184+
return nil
185+
}
186+
187+
public func lookupTool(_ name: String) -> Tool? {
188+
return nil
189+
}
190+
191+
public func hadCommandFailure() {
192+
onCommmandFailure?()
193+
}
194+
195+
public func handleDiagnostic(_ diagnostic: SPMLLBuild.Diagnostic) {
196+
diagnostics.emit(diagnostic)
197+
}
198+
199+
public func commandStatusChanged(_ command: SPMLLBuild.Command, kind: CommandStatusKind) {
200+
}
201+
202+
public func commandPreparing(_ command: SPMLLBuild.Command) {
203+
}
204+
205+
public func commandStarted(_ command: SPMLLBuild.Command) {
206+
guard command.shouldShowStatus else { return }
207+
outputStream <<< (command.description + "\n")
208+
outputStream.flush()
209+
}
210+
211+
public func shouldCommandStart(_ command: SPMLLBuild.Command) -> Bool {
212+
return true
213+
}
214+
215+
public func commandFinished(_ command: SPMLLBuild.Command, result: CommandResult) {
216+
}
217+
218+
public func commandHadError(_ command: SPMLLBuild.Command, message: String) {
219+
diagnostics.emit(data: LLBuildCommandErrorDiagnostic(message: message))
220+
}
221+
222+
public func commandHadNote(_ command: SPMLLBuild.Command, message: String) {
223+
diagnostics.emit(data: LLBuildCommandNoteDiagnostic(message: message))
224+
}
225+
226+
public func commandHadWarning(_ command: SPMLLBuild.Command, message: String) {
227+
diagnostics.emit(data: LLBuildCommandWarningDiagnostic(message: message))
228+
}
229+
230+
public func commandCannotBuildOutputDueToMissingInputs(
231+
_ command: SPMLLBuild.Command,
232+
output: BuildKey,
233+
inputs: [BuildKey]
234+
) {
235+
diagnostics.emit(data: LLBuildMissingInputs(output: output, inputs: inputs))
236+
}
237+
238+
public func cannotBuildNodeDueToMultipleProducers(output: BuildKey, commands: [SPMLLBuild.Command]) {
239+
diagnostics.emit(data: LLBuildMultipleProducers(output: output, commands: commands))
240+
}
241+
242+
public func commandProcessStarted(_ command: SPMLLBuild.Command, process: ProcessHandle) {
243+
}
244+
245+
public func commandProcessHadError(_ command: SPMLLBuild.Command, process: ProcessHandle, message: String) {
246+
diagnostics.emit(data: LLBuildCommandError(command: command, message: message))
247+
}
248+
249+
public func commandProcessHadOutput(_ command: SPMLLBuild.Command, process: ProcessHandle, data: [UInt8]) {
250+
outputStream <<< (data + [newLineByte])
251+
outputStream.flush()
252+
}
253+
254+
public func commandProcessFinished(
255+
_ command: SPMLLBuild.Command,
256+
process: ProcessHandle,
257+
result: CommandExtendedResult
258+
) {
259+
}
260+
261+
public func cycleDetected(rules: [BuildKey]) {
262+
diagnostics.emit(data: LLBuildCycleErrorDiagnostic(rules: rules))
263+
}
264+
265+
public func shouldResolveCycle(rules: [BuildKey], candidate: BuildKey, action: CycleAction) -> Bool {
266+
return false
267+
}
268+
}

Sources/Build/llbuild.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public struct LLBuildManifestGenerator {
2525
/// The build plan to work on.
2626
public let plan: BuildPlan
2727

28+
/// The manifest client name.
29+
public let client: String
30+
2831
/// Path to the resolved file.
2932
let resolvedFile: AbsolutePath
3033

@@ -34,8 +37,9 @@ public struct LLBuildManifestGenerator {
3437
}
3538

3639
/// Create a new generator with a build plan.
37-
public init(_ plan: BuildPlan, resolvedFile: AbsolutePath) {
40+
public init(_ plan: BuildPlan, client: String, resolvedFile: AbsolutePath) {
3841
self.plan = plan
42+
self.client = client
3943
self.resolvedFile = resolvedFile
4044
}
4145

@@ -118,7 +122,7 @@ public struct LLBuildManifestGenerator {
118122
let stream = BufferedOutputByteStream()
119123
stream <<< """
120124
client:
121-
name: swift-build
125+
name: \(client)
122126
tools: {}
123127
targets:\n
124128
"""

Sources/Commands/Options.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ public class ToolOptions {
5252
/// If should enable llbuild manifest caching.
5353
public var shouldEnableManifestCaching = false
5454

55+
/// If should enable building with llbuild library.
56+
public var shouldEnableLLBuildLibrary = false
57+
5558
/// Skip updating dependencies from their remote during a resolution.
5659
public var skipDependencyUpdate = false
5760

0 commit comments

Comments
 (0)