Skip to content

Commit 3fed667

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 3fed667

File tree

10 files changed

+479
-154
lines changed

10 files changed

+479
-154
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: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import protocol TSCUtility.ProgressAnimationProtocol
2929
@_implementationOnly import SwiftDriver
3030

3131
public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildSystem, BuildErrorAdviceProvider {
32-
3332
/// The delegate used by the build system.
3433
public weak var delegate: SPMBuildCore.BuildSystemDelegate?
3534

@@ -39,14 +38,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
3938
/// The closure for loading the package graph.
4039
let packageGraphLoader: () throws -> PackageGraph
4140

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
41+
/// the plugin configuration for build plugins
42+
let pluginConfiguration: PluginConfiguration?
5043

5144
/// The llbuild build delegate reference.
5245
private var buildSystemDelegate: BuildOperationBuildSystemDelegateHandler?
@@ -99,10 +92,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
9992
buildParameters: BuildParameters,
10093
cacheBuildManifest: Bool,
10194
packageGraphLoader: @escaping () throws -> PackageGraph,
95+
pluginConfiguration: PluginConfiguration? = .none,
10296
additionalFileRules: [FileRuleDescription],
103-
pluginScriptRunner: PluginScriptRunner,
104-
pluginWorkDirectory: AbsolutePath,
105-
disableSandboxForPluginCommands: Bool,
10697
outputStream: OutputByteStream,
10798
logLevel: Basics.Diagnostic.Severity,
10899
fileSystem: TSCBasic.FileSystem,
@@ -116,9 +107,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
116107
self.cacheBuildManifest = cacheBuildManifest
117108
self.packageGraphLoader = packageGraphLoader
118109
self.additionalFileRules = additionalFileRules
119-
self.pluginScriptRunner = pluginScriptRunner
120-
self.pluginWorkDirectory = pluginWorkDirectory
121-
self.disableSandboxForPluginCommands = disableSandboxForPluginCommands
110+
self.pluginConfiguration = pluginConfiguration
122111
self.outputStream = outputStream
123112
self.logLevel = logLevel
124113
self.fileSystem = fileSystem
@@ -323,6 +312,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
323312
// Compiles a single plugin, emitting its output and throwing an error if it
324313
// fails.
325314
func compilePlugin(_ plugin: PluginDescription) throws {
315+
guard let pluginConfiguration = self.pluginConfiguration else {
316+
throw InternalError("unknown plugin script runner")
317+
318+
}
326319
// Compile the plugin, getting back a PluginCompilationResult.
327320
class Delegate: PluginScriptCompilerDelegate {
328321
let preparationStepName: String
@@ -351,7 +344,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
351344
}
352345
let delegate = Delegate(preparationStepName: "Compiling plugin \(plugin.targetName)", buildSystemDelegate: self.buildSystemDelegate)
353346
let result = try tsc_await {
354-
self.pluginScriptRunner.compilePluginScript(
347+
pluginConfiguration.scriptRunner.compilePluginScript(
355348
sourceFiles: plugin.sources.paths,
356349
pluginName: plugin.targetName,
357350
toolsVersion: plugin.toolsVersion,
@@ -393,40 +386,47 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
393386
// Load the package graph.
394387
let graph = try getPackageGraph()
395388

389+
let buildToolPluginInvocationResults: [ResolvedTarget: [BuildToolPluginInvocationResult]]
390+
let prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]]
396391
// 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)
392+
if let pluginConfiguration = self.pluginConfiguration {
393+
buildToolPluginInvocationResults = try graph.invokeBuildToolPlugins(
394+
outputDir: pluginConfiguration.workDirectory.appending(component: "outputs"),
395+
builtToolsDir: self.buildParameters.buildPath,
396+
buildEnvironment: self.buildParameters.buildEnvironment,
397+
toolSearchDirectories: [self.buildParameters.toolchain.swiftCompilerPath.parentDirectory],
398+
pluginScriptRunner: pluginConfiguration.scriptRunner,
399+
observabilityScope: self.observabilityScope,
400+
fileSystem: self.fileSystem
401+
)
402+
403+
// Surface any diagnostics from build tool plugins.
404+
for (target, results) in buildToolPluginInvocationResults {
405+
// There is one result for each plugin that gets applied to a target.
406+
for result in results {
407+
let diagnosticsEmitter = self.observabilityScope.makeDiagnosticsEmitter {
408+
var metadata = ObservabilityMetadata()
409+
metadata.targetName = target.name
410+
metadata.pluginName = result.plugin.name
411+
return metadata
412+
}
413+
for line in result.textOutput.split(separator: "\n") {
414+
diagnosticsEmitter.emit(info: line)
415+
}
416+
for diag in result.diagnostics {
417+
diagnosticsEmitter.emit(diag)
418+
}
422419
}
423420
}
424-
}
425421

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-
})
422+
// Run any prebuild commands provided by build tool plugins. Any failure stops the build.
423+
prebuildCommandResults = try graph.reachableTargets.reduce(into: [:], { partial, target in
424+
partial[target] = try buildToolPluginInvocationResults[target].map { try self.runPrebuildCommands(for: $0) }
425+
})
426+
} else {
427+
buildToolPluginInvocationResults = [:]
428+
prebuildCommandResults = [:]
429+
}
430430

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

473473
let (buildDescription, buildManifest) = try BuildDescription.create(
474474
with: plan,
475-
disableSandboxForPluginCommands: self.disableSandboxForPluginCommands,
475+
disableSandboxForPluginCommands: self.pluginConfiguration?.disableSandbox ?? false,
476476
fileSystem: self.fileSystem,
477477
observabilityScope: self.observabilityScope
478478
)
@@ -541,6 +541,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
541541
/// Runs any prebuild commands associated with the given list of plugin invocation results, in order, and returns the
542542
/// results of running those prebuild commands.
543543
private func runPrebuildCommands(for pluginResults: [BuildToolPluginInvocationResult]) throws -> [PrebuildCommandResult] {
544+
guard let pluginConfiguration = self.pluginConfiguration else {
545+
throw InternalError("unknown plugin script runner")
546+
547+
}
544548
// Run through all the commands from all the plugin usages in the target.
545549
return try pluginResults.map { pluginResult in
546550
// As we go we will collect a list of prebuild output directories whose contents should be input to the build,
@@ -553,7 +557,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
553557
// Run the command configuration as a subshell. This doesn't return until it is done.
554558
// TODO: We need to also use any working directory, but that support isn't yet available on all platforms at a lower level.
555559
var commandLine = [command.configuration.executable.pathString] + command.configuration.arguments
556-
if !self.disableSandboxForPluginCommands {
560+
if !pluginConfiguration.disableSandbox {
557561
commandLine = try Sandbox.apply(command: commandLine, strictness: .writableTemporaryDirectory, writableDirectories: [pluginResult.pluginOutputDirectory])
558562
}
559563
let processResult = try TSCBasic.Process.popen(arguments: commandLine, environment: command.configuration.environment)
@@ -613,6 +617,25 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
613617
}
614618
}
615619

620+
extension BuildOperation {
621+
public struct PluginConfiguration {
622+
/// Entity responsible for compiling and running plugin scripts.
623+
let scriptRunner: PluginScriptRunner
624+
625+
/// Directory where plugin intermediate files are stored.
626+
let workDirectory: AbsolutePath
627+
628+
/// Whether to sandbox commands from build tool plugins.
629+
let disableSandbox: Bool
630+
631+
public init(scriptRunner: PluginScriptRunner, workDirectory: AbsolutePath, disableSandbox: Bool) {
632+
self.scriptRunner = scriptRunner
633+
self.workDirectory = workDirectory
634+
self.disableSandbox = disableSandbox
635+
}
636+
}
637+
}
638+
616639
extension BuildDescription {
617640
static func create(with plan: BuildPlan, disableSandboxForPluginCommands: Bool, fileSystem: TSCBasic.FileSystem, observabilityScope: ObservabilityScope) throws -> (BuildDescription, LLBuildManifest.BuildManifest) {
618641
// Generate the llbuild manifest.

Sources/CoreCommands/BuildSystemSupport.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ extension SwiftTool {
3030
buildParameters: customBuildParameters ?? self.buildParameters(),
3131
cacheBuildManifest: cacheBuildManifest && self.canUseCachedBuildManifest(),
3232
packageGraphLoader: customPackageGraphLoader ?? graphLoader,
33+
pluginConfiguration: .init(
34+
scriptRunner: self.getPluginScriptRunner(),
35+
workDirectory: try self.getActiveWorkspace().location.pluginWorkingDirectory,
36+
disableSandbox: self.options.security.shouldDisableSandbox
37+
),
3338
additionalFileRules: FileRuleDescription.swiftpmFileTypes,
34-
pluginScriptRunner: self.getPluginScriptRunner(),
35-
pluginWorkDirectory: try self.getActiveWorkspace().location.pluginWorkingDirectory,
36-
disableSandboxForPluginCommands: self.options.security.shouldDisableSandbox,
3739
outputStream: customOutputStream ?? self.outputStream,
3840
logLevel: customLogLevel ?? self.logLevel,
3941
fileSystem: self.fileSystem,

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)