Skip to content

Commit 0d84fd3

Browse files
committed
simplifiy bootstrap build
motivation: remove depednecy on workspace that carries over dependencies on source control and registry changes: * move minimal-built-tool code into swift-bootstrap * add dependency resolution code swift-bootstrap so it does not require dependency on workspace * cleanup bootstrap arguments for those that can be hard coded * adjust target dependencies and cmake setup accordingly
1 parent f157ff9 commit 0d84fd3

File tree

9 files changed

+466
-150
lines changed

9 files changed

+466
-150
lines changed

Package.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,9 @@ let package = Package(
350350
"Basics",
351351
"Build",
352352
"PackageFingerprint",
353+
"PackageLoading",
353354
"PackageModel",
355+
"PackageGraph",
354356
"Workspace",
355357
"XCBuildSupport",
356358
],
@@ -389,7 +391,15 @@ let package = Package(
389391
.executableTarget(
390392
/** Builds SwiftPM itself for bootstrapping (minimal version of `swift-build`) */
391393
name: "swift-bootstrap",
392-
dependencies: ["CoreCommands"],
394+
dependencies: [
395+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
396+
"Basics",
397+
"Build",
398+
"PackageGraph",
399+
"PackageLoading",
400+
"PackageModel",
401+
"XCBuildSupport",
402+
],
393403
exclude: ["CMakeLists.txt"]
394404
),
395405
.executableTarget(

Sources/Build/BuildOperation.swift

Lines changed: 63 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,19 @@ import protocol TSCUtility.ProgressAnimationProtocol
2828

2929
@_implementationOnly import SwiftDriver
3030

31+
32+
3133
public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildSystem, BuildErrorAdviceProvider {
34+
public struct PluginConfiguration {
35+
/// Entity responsible for compiling and running plugin scripts.
36+
let scriptRunner: PluginScriptRunner
37+
38+
/// Directory where plugin intermediate files are stored.
39+
let workDirectory: AbsolutePath
40+
41+
/// Whether to sandbox commands from build tool plugins.
42+
let disableSandbox: Bool
43+
}
3244

3345
/// The delegate used by the build system.
3446
public weak var delegate: SPMBuildCore.BuildSystemDelegate?
@@ -39,14 +51,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
3951
/// The closure for loading the package graph.
4052
let packageGraphLoader: () throws -> PackageGraph
4153

42-
/// Entity responsible for compiling and running plugin scripts.
43-
let pluginScriptRunner: PluginScriptRunner
44-
45-
/// Directory where plugin intermediate files are stored.
46-
let pluginWorkDirectory: AbsolutePath
47-
48-
/// Whether to sandbox commands from build tool plugins.
49-
public let disableSandboxForPluginCommands: Bool
54+
let pluginConfiguration: PluginConfiguration?
5055

5156
/// The llbuild build delegate reference.
5257
private var buildSystemDelegate: BuildOperationBuildSystemDelegateHandler?
@@ -99,10 +104,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
99104
buildParameters: BuildParameters,
100105
cacheBuildManifest: Bool,
101106
packageGraphLoader: @escaping () throws -> PackageGraph,
107+
pluginConfiguration: PluginConfiguration? = .none,
102108
additionalFileRules: [FileRuleDescription],
103-
pluginScriptRunner: PluginScriptRunner,
104-
pluginWorkDirectory: AbsolutePath,
105-
disableSandboxForPluginCommands: Bool,
106109
outputStream: OutputByteStream,
107110
logLevel: Basics.Diagnostic.Severity,
108111
fileSystem: TSCBasic.FileSystem,
@@ -116,9 +119,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
116119
self.cacheBuildManifest = cacheBuildManifest
117120
self.packageGraphLoader = packageGraphLoader
118121
self.additionalFileRules = additionalFileRules
119-
self.pluginScriptRunner = pluginScriptRunner
120-
self.pluginWorkDirectory = pluginWorkDirectory
121-
self.disableSandboxForPluginCommands = disableSandboxForPluginCommands
122+
self.pluginConfiguration = pluginConfiguration
122123
self.outputStream = outputStream
123124
self.logLevel = logLevel
124125
self.fileSystem = fileSystem
@@ -323,6 +324,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
323324
// Compiles a single plugin, emitting its output and throwing an error if it
324325
// fails.
325326
func compilePlugin(_ plugin: PluginDescription) throws {
327+
guard let pluginConfiguration = self.pluginConfiguration else {
328+
throw InternalError("unknown plugin script runner")
329+
330+
}
326331
// Compile the plugin, getting back a PluginCompilationResult.
327332
class Delegate: PluginScriptCompilerDelegate {
328333
let preparationStepName: String
@@ -351,7 +356,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
351356
}
352357
let delegate = Delegate(preparationStepName: "Compiling plugin \(plugin.targetName)", buildSystemDelegate: self.buildSystemDelegate)
353358
let result = try tsc_await {
354-
self.pluginScriptRunner.compilePluginScript(
359+
pluginConfiguration.scriptRunner.compilePluginScript(
355360
sourceFiles: plugin.sources.paths,
356361
pluginName: plugin.targetName,
357362
toolsVersion: plugin.toolsVersion,
@@ -393,40 +398,47 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
393398
// Load the package graph.
394399
let graph = try getPackageGraph()
395400

401+
let buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]]
402+
let prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]]
396403
// Invoke any build tool plugins in the graph to generate prebuild commands and build commands.
397-
let buildToolPluginInvocationResults = try graph.invokeBuildToolPlugins(
398-
outputDir: self.pluginWorkDirectory.appending(component: "outputs"),
399-
builtToolsDir: self.buildParameters.buildPath,
400-
buildEnvironment: self.buildParameters.buildEnvironment,
401-
toolSearchDirectories: [self.buildParameters.toolchain.swiftCompilerPath.parentDirectory],
402-
pluginScriptRunner: self.pluginScriptRunner,
403-
observabilityScope: self.observabilityScope,
404-
fileSystem: self.fileSystem
405-
)
406-
407-
// Surface any diagnostics from build tool plugins.
408-
for (target, results) in buildToolPluginInvocationResults {
409-
// There is one result for each plugin that gets applied to a target.
410-
for result in results {
411-
let diagnosticsEmitter = self.observabilityScope.makeDiagnosticsEmitter {
412-
var metadata = ObservabilityMetadata()
413-
metadata.targetName = target.name
414-
metadata.pluginName = result.plugin.name
415-
return metadata
416-
}
417-
for line in result.textOutput.split(separator: "\n") {
418-
diagnosticsEmitter.emit(info: line)
419-
}
420-
for diag in result.diagnostics {
421-
diagnosticsEmitter.emit(diag)
404+
if let pluginConfiguration = self.pluginConfiguration {
405+
buildToolPluginInvocationResults = try graph.invokeBuildToolPlugins(
406+
outputDir: pluginConfiguration.workDirectory.appending(component: "outputs"),
407+
builtToolsDir: self.buildParameters.buildPath,
408+
buildEnvironment: self.buildParameters.buildEnvironment,
409+
toolSearchDirectories: [self.buildParameters.toolchain.swiftCompilerPath.parentDirectory],
410+
pluginScriptRunner: pluginConfiguration.scriptRunner,
411+
observabilityScope: self.observabilityScope,
412+
fileSystem: self.fileSystem
413+
)
414+
415+
// Surface any diagnostics from build tool plugins.
416+
for (target, results) in buildToolPluginInvocationResults {
417+
// There is one result for each plugin that gets applied to a target.
418+
for result in results {
419+
let diagnosticsEmitter = self.observabilityScope.makeDiagnosticsEmitter {
420+
var metadata = ObservabilityMetadata()
421+
metadata.targetName = target.name
422+
metadata.pluginName = result.plugin.name
423+
return metadata
424+
}
425+
for line in result.textOutput.split(separator: "\n") {
426+
diagnosticsEmitter.emit(info: line)
427+
}
428+
for diag in result.diagnostics {
429+
diagnosticsEmitter.emit(diag)
430+
}
422431
}
423432
}
424-
}
425433

426-
// Run any prebuild commands provided by build tool plugins. Any failure stops the build.
427-
let prebuildCommandResults = try graph.reachableTargets.reduce(into: [:], { partial, target in
428-
partial[target] = try buildToolPluginInvocationResults[target].map { try self.runPrebuildCommands(for: $0) }
429-
})
434+
// Run any prebuild commands provided by build tool plugins. Any failure stops the build.
435+
prebuildCommandResults = try graph.reachableTargets.reduce(into: [:], { partial, target in
436+
partial[target] = try buildToolPluginInvocationResults[target].map { try self.runPrebuildCommands(for: $0) }
437+
})
438+
} else {
439+
buildToolPluginInvocationResults = [:]
440+
prebuildCommandResults = [:]
441+
}
430442

431443
// Emit warnings about any unhandled files in authored packages. We do this after applying build tool plugins, once we know what files they handled.
432444
for package in graph.rootPackages where package.manifest.toolsVersion >= .v5_3 {
@@ -472,7 +484,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
472484

473485
let (buildDescription, buildManifest) = try BuildDescription.create(
474486
with: plan,
475-
disableSandboxForPluginCommands: self.disableSandboxForPluginCommands,
487+
disableSandboxForPluginCommands: self.pluginConfiguration?.disableSandbox ?? false,
476488
fileSystem: self.fileSystem,
477489
observabilityScope: self.observabilityScope
478490
)
@@ -541,6 +553,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
541553
/// Runs any prebuild commands associated with the given list of plugin invocation results, in order, and returns the
542554
/// results of running those prebuild commands.
543555
private func runPrebuildCommands(for pluginResults: [BuildToolPluginInvocationResult]) throws -> [PrebuildCommandResult] {
556+
guard let pluginConfiguration = self.pluginConfiguration else {
557+
throw InternalError("unknown plugin script runner")
558+
559+
}
544560
// Run through all the commands from all the plugin usages in the target.
545561
return try pluginResults.map { pluginResult in
546562
// As we go we will collect a list of prebuild output directories whose contents should be input to the build,
@@ -553,7 +569,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
553569
// Run the command configuration as a subshell. This doesn't return until it is done.
554570
// TODO: We need to also use any working directory, but that support isn't yet available on all platforms at a lower level.
555571
var commandLine = [command.configuration.executable.pathString] + command.configuration.arguments
556-
if !self.disableSandboxForPluginCommands {
572+
if !pluginConfiguration.disableSandbox {
557573
commandLine = try Sandbox.apply(command: commandLine, strictness: .writableTemporaryDirectory, writableDirectories: [pluginResult.pluginOutputDirectory])
558574
}
559575
let processResult = try TSCBasic.Process.popen(arguments: commandLine, environment: command.configuration.environment)

Sources/CoreCommands/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
add_library(CoreCommands
1010
BuildSystemSupport.swift
11-
MinimalBuildTool.swift
1211
SwiftTool.swift
1312
SwiftToolObservabilityHandler.swift
1413
Options.swift)

Sources/CoreCommands/MinimalBuildTool.swift

Lines changed: 0 additions & 86 deletions
This file was deleted.

Sources/CoreCommands/SwiftTool.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@ public protocol SwiftCommand: ParsableCommand {
7575

7676
extension SwiftCommand {
7777
public func run() throws {
78-
let swiftTool = try SwiftTool(options: globalOptions, toolWorkspaceConfiguration: self.toolWorkspaceConfiguration, workspaceDelegateProvider: self.workspaceDelegateProvider, workspaceLoaderProvider: self.workspaceLoaderProvider)
78+
let swiftTool = try SwiftTool(
79+
options: globalOptions,
80+
toolWorkspaceConfiguration: self.toolWorkspaceConfiguration,
81+
workspaceDelegateProvider: self.workspaceDelegateProvider,
82+
workspaceLoaderProvider: self.workspaceLoaderProvider
83+
)
7984
swiftTool.buildSystemProvider = try buildSystemProvider(swiftTool)
8085
var toolError: Error? = .none
8186
do {

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ public struct BuildParameters: Encodable {
229229
hostTriple: Triple? = nil,
230230
destinationTriple: Triple? = nil,
231231
archs: [String] = [],
232-
flags: BuildFlags,
233-
xcbuildFlags: [String] = [],
232+
flags: BuildFlags = .init(),
233+
xcbuildFlags: [String] = [], // FIXME: this seems out of place
234234
jobs: UInt32 = UInt32(ProcessInfo.processInfo.activeProcessorCount),
235235
shouldLinkStaticSwiftStdlib: Bool = false,
236236
shouldEnableManifestCaching: Bool = false,

Sources/swift-bootstrap/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,12 @@
99
add_executable(swift-bootstrap
1010
main.swift)
1111
target_link_libraries(swift-bootstrap PRIVATE
12-
CoreCommands)
12+
ArgumentParser
13+
Basics
14+
Build
15+
PackageGraph
16+
PackageLoading
17+
PackageModel
18+
TSCBasic
19+
TSCUtility
20+
XCBuildSupport)

0 commit comments

Comments
 (0)