Skip to content

Commit 6245408

Browse files
authored
refactor LLBuildManifest graphviz file visualization flow (#5576)
motivation: code cleanup changes: * move the code that prints the LLBuildManifest graphviz visualization to stdout from the build system to the build tool, which is where printg should be done * remove printManifestGraphviz from BuildParameters as it was only necessary to drive outputing the visulaization from the build system * move the LLBuild manifest dserializer to the Commands module, with the rest of the user facing output serilizers * create Utilities directory in the Commands module and move the various utilities there to better organize the code * rename dependencies_serializer to DependenciesSerializer
1 parent 4cf8e7e commit 6245408

17 files changed

+44
-39
lines changed

Sources/Build/BuildOperation.swift

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,14 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
143143
}
144144
}
145145
// We need to perform actual planning if we reach here.
146-
return try self.plan()
146+
return try self.plan().description
147147
}
148148
}
149149

150+
public func getBuildManifest() throws -> LLBuildManifest.BuildManifest {
151+
return try self.plan().manifest
152+
}
153+
150154
/// Cancel the active build operation.
151155
public func cancel(deadline: DispatchTime) throws {
152156
buildSystem?.cancel()
@@ -283,7 +287,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
283287
}
284288

285289
/// Create the build plan and return the build description.
286-
private func plan() throws -> BuildDescription {
290+
private func plan() throws -> (description: BuildDescription, manifest: LLBuildManifest.BuildManifest) {
287291
// Load the package graph.
288292
let graph = try getPackageGraph()
289293

@@ -372,18 +376,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
372376
observabilityScope: self.observabilityScope
373377
)
374378

375-
// FIXME: ideally this would be done outside of the planning phase,
376-
// but it would require deeper changes in how we serialize BuildDescription
377-
// Output a dot graph
378-
if buildParameters.printManifestGraphviz {
379-
// FIXME: this seems like the wrong place to print
380-
var serializer = DOTManifestSerializer(manifest: buildManifest)
381-
serializer.writeDOT(to: self.outputStream)
382-
self.outputStream.flush()
383-
}
384-
385379
// Finally create the llbuild manifest from the plan.
386-
return buildDescription
380+
return (buildDescription, buildManifest)
387381
}
388382

389383
/// Build the package structure target.
@@ -519,7 +513,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
519513
}
520514

521515
extension BuildDescription {
522-
static func create(with plan: BuildPlan, disableSandboxForPluginCommands: Bool, fileSystem: TSCBasic.FileSystem, observabilityScope: ObservabilityScope) throws -> (BuildDescription, BuildManifest) {
516+
static func create(with plan: BuildPlan, disableSandboxForPluginCommands: Bool, fileSystem: TSCBasic.FileSystem, observabilityScope: ObservabilityScope) throws -> (BuildDescription, LLBuildManifest.BuildManifest) {
523517
// Generate the llbuild manifest.
524518
let llbuild = LLBuildManifestBuilder(plan, disableSandboxForPluginCommands: disableSandboxForPluginCommands, fileSystem: fileSystem, observabilityScope: observabilityScope)
525519
let buildManifest = try llbuild.generateManifest(at: plan.buildParameters.llbuildManifest)

Sources/Commands/CMakeLists.txt

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,8 @@
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

99
add_library(Commands
10-
APIDigester.swift
11-
Describe.swift
12-
GenerateLinuxMain.swift
13-
MultiRootSupport.swift
10+
1411
Options.swift
15-
show-dependencies.swift
1612
Snippets/CardEvent.swift
1713
Snippets/Cards/SnippetCard.swift
1814
Snippets/Cards/SnippetGroupCard.swift
@@ -27,9 +23,15 @@ add_library(Commands
2723
SwiftRunTool.swift
2824
SwiftTestTool.swift
2925
SwiftTool.swift
30-
SymbolGraphExtract.swift
31-
TestingSupport.swift
32-
WatchmanHelper.swift)
26+
Utilities/APIDigester.swift
27+
Utilities/DependenciesSerializer.swift
28+
Utilities/Describe.swift
29+
Utilities/DOTManifestSerializer.swift
30+
Utilities/GenerateLinuxMain.swift
31+
Utilities/MultiRootSupport.swift
32+
Utilities/SymbolGraphExtract.swift
33+
Utilities/TestingSupport.swift
34+
Utilities/WatchmanHelper.swift)
3335
target_link_libraries(Commands PUBLIC
3436
ArgumentParser
3537
Basics

Sources/Commands/Options.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,6 @@ struct BuildOptions: ParsableArguments {
339339
@Flag(name: .customLong("experimental-explicit-module-build"))
340340
var useExplicitModuleBuild: Bool = false
341341

342-
/// Whether to output a graphviz file visualization of the combined job graph for all targets
343-
@Flag(
344-
name: .customLong("print-manifest-job-graph"),
345-
help: "Write the command graph for the build manifest as a graphviz file")
346-
var printManifestGraphviz: Bool = false
347-
348342
/// The build system to use.
349343
@Option(name: .customLong("build-system"))
350344
var _buildSystem: BuildSystemKind = .native

Sources/Commands/SwiftBuildTool.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ struct BuildToolOptions: ParsableArguments {
6969
@Flag(name: .customLong("show-bin-path"), help: "Print the binary output path")
7070
var shouldPrintBinPath: Bool = false
7171

72+
/// Whether to output a graphviz file visualization of the combined job graph for all targets
73+
@Flag(name: .customLong("print-manifest-job-graph"),
74+
help: "Write the command graph for the build manifest as a graphviz file")
75+
var printManifestGraphviz: Bool = false
76+
7277
/// Specific target to build.
7378
@Option(help: "Build the specified target")
7479
var target: String?
@@ -96,7 +101,17 @@ public struct SwiftBuildTool: SwiftCommand {
96101

97102
public func run(_ swiftTool: SwiftTool) throws {
98103
if options.shouldPrintBinPath {
99-
try print(swiftTool.buildParameters().buildPath.description)
104+
return try print(swiftTool.buildParameters().buildPath.description)
105+
}
106+
107+
if options.printManifestGraphviz {
108+
let buildOperation = try swiftTool.createBuildOperation()
109+
let buildManifest = try buildOperation.getBuildManifest()
110+
var serializer = DOTManifestSerializer(manifest: buildManifest)
111+
// print to stdout
112+
let outputStream = stdoutStream
113+
serializer.writeDOT(to: outputStream)
114+
outputStream.flush()
100115
return
101116
}
102117

Sources/Commands/SwiftTool.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,6 @@ public class SwiftTool {
843843
useIntegratedSwiftDriver: options.build.useIntegratedSwiftDriver,
844844
useExplicitModuleBuild: options.build.useExplicitModuleBuild,
845845
isXcodeBuildSystemEnabled: options.build.buildSystem == .xcode,
846-
printManifestGraphviz: options.build.printManifestGraphviz,
847846
forceTestDiscovery: options.build.enableTestDiscovery, // backwards compatibility, remove with --enable-test-discovery
848847
linkerDeadStrip: options.linker.linkerDeadStrip,
849848
verboseOutput: self.logLevel <= .info

Sources/LLBuildManifest/DOTManifestSerializer.swift renamed to Sources/Commands/Utilities/DOTManifestSerializer.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import LLBuildManifest
1314
import TSCBasic
1415

1516
/// Serializes an LLBuildManifest graph to a .dot file
1617
public struct DOTManifestSerializer {
1718
var kindCounter = [String: Int]()
1819
var hasEmittedStyling = Set<String>()
19-
let manifest: BuildManifest
20+
let manifest: LLBuildManifest.BuildManifest
2021

2122
/// Creates a serializer that will serialize the given manifest.
22-
public init(manifest: BuildManifest) {
23+
public init(manifest: LLBuildManifest.BuildManifest) {
2324
self.manifest = manifest
2425
}
2526

Sources/LLBuildManifest/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
add_library(LLBuildManifest STATIC
1010
BuildManifest.swift
1111
Command.swift
12-
ManifestWriter.swift
13-
DOTManifestSerializer.swift
12+
ManifestWriter.swift
1413
Node.swift
1514
Target.swift
1615
Tools.swift)

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,6 @@ public struct BuildParameters: Encodable {
128128
/// Whether to use the explicit module build flow (with the integrated driver)
129129
public var useExplicitModuleBuild: Bool
130130

131-
/// Whether to output a graphviz file visualization of the combined job graph for all targets
132-
public var printManifestGraphviz: Bool
133-
134131
/// Whether to create dylibs for dynamic library products.
135132
public var shouldCreateDylibForDynamicProducts: Bool
136133

@@ -200,7 +197,6 @@ public struct BuildParameters: Encodable {
200197
useIntegratedSwiftDriver: Bool = false,
201198
useExplicitModuleBuild: Bool = false,
202199
isXcodeBuildSystemEnabled: Bool = false,
203-
printManifestGraphviz: Bool = false,
204200
enableTestability: Bool? = nil,
205201
forceTestDiscovery: Bool = false,
206202
linkerDeadStrip: Bool = true,
@@ -230,7 +226,6 @@ public struct BuildParameters: Encodable {
230226
self.useIntegratedSwiftDriver = useIntegratedSwiftDriver
231227
self.useExplicitModuleBuild = useExplicitModuleBuild
232228
self.isXcodeBuildSystemEnabled = isXcodeBuildSystemEnabled
233-
self.printManifestGraphviz = printManifestGraphviz
234229
// decide on testability based on debug/release config
235230
// the goals of this being based on the build configuration is
236231
// that `swift build` followed by a `swift test` will need to do minimal rebuilding

Tests/CommandsTests/BuildToolTests.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,4 +334,10 @@ final class BuildToolTests: CommandsTestCase {
334334
}
335335
}
336336

337+
func testPrintLLBuildManifestJobGraph() throws {
338+
try fixture(name: "DependencyResolution/Internal/Simple") { fixturePath in
339+
let output = try execute(["--print-manifest-job-graph"], packagePath: fixturePath).stdout
340+
XCTAssertMatch(output, .prefix("digraph Jobs {"))
341+
}
342+
}
337343
}

0 commit comments

Comments
 (0)