Skip to content

Commit 4111569

Browse files
authored
simplify bootstrap build (#5939)
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 bd6487b commit 4111569

21 files changed

+542
-195
lines changed

Package.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,9 @@ let package = Package(
345345
"Basics",
346346
"Build",
347347
"PackageFingerprint",
348+
"PackageLoading",
348349
"PackageModel",
350+
"PackageGraph",
349351
"Workspace",
350352
"XCBuildSupport",
351353
],
@@ -414,7 +416,15 @@ let package = Package(
414416
.executableTarget(
415417
/** Builds SwiftPM itself for bootstrapping (minimal version of `swift-build`) */
416418
name: "swift-bootstrap",
417-
dependencies: ["CoreCommands"],
419+
dependencies: [
420+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
421+
"Basics",
422+
"Build",
423+
"PackageGraph",
424+
"PackageLoading",
425+
"PackageModel",
426+
"XCBuildSupport",
427+
],
418428
exclude: ["CMakeLists.txt"]
419429
),
420430
.executableTarget(

Sources/Basics/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ add_library(Basics
2929
SQLite.swift
3030
Sandbox.swift
3131
String+Extensions.swift
32-
Triple+Extensions.swift
3332
SwiftVersion.swift
3433
SQLiteBackedCache.swift
3534
Version+Extensions.swift

Sources/Build/BuildOperation.swift

Lines changed: 72 additions & 49 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
)
@@ -526,7 +526,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
526526
buildFile: buildParameters.llbuildManifest.pathString,
527527
databaseFile: databasePath,
528528
delegate: buildSystemDelegate,
529-
schedulerLanes: buildParameters.jobs
529+
schedulerLanes: buildParameters.workers
530530
)
531531

532532
// TODO: this seems fragile, perhaps we replace commandFailureHandler by adding relevant calls in the delegates chain
@@ -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/Build/BuildPlan.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -883,7 +883,7 @@ public final class SwiftTargetBuildDescription {
883883
args += optimizationArguments
884884
args += testingArguments
885885
args += ["-g"]
886-
args += ["-j\(buildParameters.jobs)"]
886+
args += ["-j\(buildParameters.workers)"]
887887
args += activeCompilationConditions
888888
args += additionalFlags
889889
args += try moduleCacheArgs
@@ -1037,7 +1037,7 @@ public final class SwiftTargetBuildDescription {
10371037
result += optimizationArguments
10381038
result += testingArguments
10391039
result += ["-g"]
1040-
result += ["-j\(buildParameters.jobs)"]
1040+
result += ["-j\(buildParameters.workers)"]
10411041
result += activeCompilationConditions
10421042
result += additionalFlags
10431043
result += try moduleCacheArgs
@@ -1084,7 +1084,7 @@ public final class SwiftTargetBuildDescription {
10841084
result += optimizationArguments
10851085
result += testingArguments
10861086
result += ["-g"]
1087-
result += ["-j\(buildParameters.jobs)"]
1087+
result += ["-j\(buildParameters.workers)"]
10881088
result += activeCompilationConditions
10891089
result += additionalFlags
10901090
result += try moduleCacheArgs

Sources/Commands/PackageTools/APIDiff.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ struct APIDiff: SwiftCommand {
114114

115115
let results = ThreadSafeArrayStore<SwiftAPIDigester.ComparisonResult>()
116116
let group = DispatchGroup()
117-
let semaphore = DispatchSemaphore(value: Int(try buildSystem.buildPlan.buildParameters.jobs))
117+
let semaphore = DispatchSemaphore(value: Int(try buildSystem.buildPlan.buildParameters.workers))
118118
var skippedModules: Set<String> = []
119119

120120
for module in modulesToDiff {

Sources/Commands/Utilities/APIDigester.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct APIDigesterBaselineDumper {
140140
// Dump the SDK JSON.
141141
try swiftTool.fileSystem.createDirectory(baselineDir, recursive: true)
142142
let group = DispatchGroup()
143-
let semaphore = DispatchSemaphore(value: Int(buildParameters.jobs))
143+
let semaphore = DispatchSemaphore(value: Int(buildParameters.workers))
144144
let errors = ThreadSafeArrayStore<Swift.Error>()
145145
for module in modulesToDiff {
146146
semaphore.wait()

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)

0 commit comments

Comments
 (0)