Skip to content

Commit 1fd2ffd

Browse files
committed
Refactor the plugin loading a bit to minimize compile-time differences
This narrows what's guarded by USE_STATIC_PLUGIN_INITIALIZATION as tightly as possible, to avoid unintentional build breakages during refactoring, for clients where this flag is turned off. It also fixes an issue which resulted from this during Core initialization where the wrong type of plugin manager was being passed into the plugin initialization function.
1 parent d45edbe commit 1fd2ffd

File tree

11 files changed

+77
-66
lines changed

11 files changed

+77
-66
lines changed

Sources/SWBAndroidPlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public import SWBCore
1515
import SWBMacro
1616
import Foundation
1717

18-
@PluginExtensionSystemActor public func initializePlugin(_ manager: MutablePluginManager) {
18+
public let initializePlugin: PluginInitializationFunction = { manager in
1919
let plugin = AndroidPlugin()
2020
manager.register(AndroidPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)
2121
manager.register(AndroidEnvironmentExtension(plugin: plugin), type: EnvironmentExtensionPoint.self)

Sources/SWBApplePlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import SWBProtocol
1717
import Foundation
1818
import SWBTaskConstruction
1919

20-
@PluginExtensionSystemActor public func initializePlugin(_ manager: MutablePluginManager) {
20+
public let initializePlugin: PluginInitializationFunction = { manager in
2121
manager.register(AppleDeveloperDirectoryExtension(), type: DeveloperDirectoryExtensionPoint.self)
2222
manager.register(ApplePlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)
2323
manager.register(ActoolInputFileGroupingStrategyExtension(), type: InputFileGroupingStrategyExtensionPoint.self)

Sources/SWBBuildService/BuildServiceEntryPoint.swift

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -127,27 +127,39 @@ extension BuildService {
127127

128128
pluginManager.register(BuiltinTaskActionsExtension(), type: TaskActionExtensionPoint.self)
129129

130+
let staticPluginInitializers: [PluginInitializationFunction]
131+
132+
// This MUST be a compile-time check because the module dependencies on the plugins are conditional.
133+
// Minimize the amount of code that is conditionally compiled to avoid breaking the build during refactoring.
130134
#if USE_STATIC_PLUGIN_INITIALIZATION
131-
// Statically initialize the plugins.
132-
SWBAndroidPlatform.initializePlugin(pluginManager)
133-
SWBApplePlatform.initializePlugin(pluginManager)
134-
SWBGenericUnixPlatform.initializePlugin(pluginManager)
135-
SWBQNXPlatform.initializePlugin(pluginManager)
136-
SWBUniversalPlatform.initializePlugin(pluginManager)
137-
SWBWebAssemblyPlatform.initializePlugin(pluginManager)
138-
SWBWindowsPlatform.initializePlugin(pluginManager)
135+
staticPluginInitializers = [
136+
SWBAndroidPlatform.initializePlugin,
137+
SWBApplePlatform.initializePlugin,
138+
SWBGenericUnixPlatform.initializePlugin,
139+
SWBQNXPlatform.initializePlugin,
140+
SWBUniversalPlatform.initializePlugin,
141+
SWBWebAssemblyPlatform.initializePlugin,
142+
SWBWindowsPlatform.initializePlugin,
143+
]
139144
#else
140-
// Otherwise, load the normal plugins.
141-
if let pluginsDirectory {
142-
let pluginsPath = try pluginsDirectory.filePath
143-
pluginManager.load(at: pluginsPath)
144-
for subpath in (try? localFS.listdir(pluginsPath).sorted().map({ pluginsPath.join($0) })) ?? [] {
145-
if localFS.isDirectory(subpath) {
146-
pluginManager.load(at: subpath)
145+
staticPluginInitializers = []
146+
#endif
147+
148+
if useStaticPluginInitialization {
149+
// Statically initialize the plugins.
150+
staticPluginInitializers.forEach { $0(pluginManager) }
151+
} else {
152+
// Otherwise, load the normal plugins.
153+
if let pluginsDirectory {
154+
let pluginsPath = try pluginsDirectory.filePath
155+
pluginManager.load(at: pluginsPath)
156+
for subpath in (try? localFS.listdir(pluginsPath).sorted().map({ pluginsPath.join($0) })) ?? [] {
157+
if localFS.isDirectory(subpath) {
158+
pluginManager.load(at: subpath)
159+
}
147160
}
148161
}
149162
}
150-
#endif
151163

152164
return pluginManager
153165
}()

Sources/SWBCore/Core.swift

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,6 @@ public final class Core: Sendable {
5151
return nil
5252
}
5353

54-
#if USE_STATIC_PLUGIN_INITIALIZATION
55-
// In a package context, plugins are statically linked into the build system.
56-
// Load specs from service plugins if requested since we don't have a Service in certain tests
57-
// Here we don't have access to `core.pluginPaths` like we do in the call below,
58-
// but it doesn't matter because it will return an empty array when USE_STATIC_PLUGIN_INITIALIZATION is defined.
59-
await extraPluginRegistration(pluginManager, [])
60-
#endif
61-
6254
let resolvedDeveloperPath: DeveloperPath
6355
do {
6456
if let resolved = developerPath {
@@ -81,6 +73,10 @@ public final class Core: Sendable {
8173
return nil
8274
}
8375

76+
// In a package context, plugins are statically linked into the build system.
77+
// Load specs from service plugins if requested since we don't have a Service in certain tests.
78+
await extraPluginRegistration(pluginManager, Self.pluginPaths(inferiorProductsPath: inferiorProductsPath, developerPath: resolvedDeveloperPath))
79+
8480
let core: Core
8581
do {
8682
core = try await Core(delegate: delegate, hostOperatingSystem: hostOperatingSystem, pluginManager: pluginManager.finalize(), developerPath: resolvedDeveloperPath, resourceSearchPaths: resourceSearchPaths, inferiorProductsPath: inferiorProductsPath, additionalContentPaths: additionalContentPaths, environment: environment, buildServiceModTime: buildServiceModTime, connectionMode: connectionMode)
@@ -103,12 +99,6 @@ public final class Core: Sendable {
10399
}
104100
}
105101

106-
#if !USE_STATIC_PLUGIN_INITIALIZATION
107-
// In a package context, plugins are statically linked into the build system.
108-
// Load specs from service plugins if requested since we don't have a Service in certain tests
109-
await extraPluginRegistration(core.pluginManager, core.pluginPaths)
110-
#endif
111-
112102
await core.initializeSpecRegistry()
113103

114104
await core.initializePlatformRegistry()
@@ -313,19 +303,19 @@ public final class Core: Sendable {
313303
}()
314304

315305
/// The list of plugin search paths.
316-
@_spi(Testing) public lazy var pluginPaths: [Path] = {
317-
#if USE_STATIC_PLUGIN_INITIALIZATION
318-
// In a package context, plugins are statically linked into the build system.
319-
return []
320-
#else
306+
private static func pluginPaths(inferiorProductsPath: Path?, developerPath: DeveloperPath) -> [Path] {
307+
if useStaticPluginInitialization {
308+
// In a package context, plugins are statically linked into the build system.
309+
return []
310+
}
321311

322312
var result = [Path]()
323313

324314
// If we are inferior, then search the built products directory first.
325315
//
326316
// FIXME: This is error prone, as it won't validate that any of these are installed in the expected location.
327317
// FIXME: If we remove, move or rename something in the built Xcode, then this will still find the old item in the installed Xcode.
328-
if let inferiorProductsPath = self.inferiorProductsPath {
318+
if let inferiorProductsPath {
329319
result.append(inferiorProductsPath)
330320
}
331321

@@ -359,8 +349,7 @@ public final class Core: Sendable {
359349
}
360350

361351
return result.map { $0.normalize() }
362-
#endif
363-
}()
352+
}
364353

365354
/// The list of SDK search paths.
366355
@_spi(Testing) public lazy var sdkPaths: [(Path, Platform?)] = {

Sources/SWBGenericUnixPlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public import SWBUtil
1414
import SWBCore
1515
import Foundation
1616

17-
@PluginExtensionSystemActor public func initializePlugin(_ manager: MutablePluginManager) {
17+
public let initializePlugin: PluginInitializationFunction = { manager in
1818
let plugin = GenericUnixPlugin()
1919
manager.register(GenericUnixDeveloperDirectoryExtension(), type: DeveloperDirectoryExtensionPoint.self)
2020
manager.register(GenericUnixPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)

Sources/SWBQNXPlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import SWBCore
1515
import SWBMacro
1616
import Foundation
1717

18-
@PluginExtensionSystemActor public func initializePlugin(_ manager: MutablePluginManager) {
18+
public let initializePlugin: PluginInitializationFunction = { manager in
1919
let plugin = QNXPlugin()
2020
manager.register(QNXPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)
2121
manager.register(QNXEnvironmentExtension(plugin: plugin), type: EnvironmentExtensionPoint.self)

Sources/SWBTestSupport/CoreTestSupport.swift

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,30 +140,30 @@ extension Core {
140140
pluginManager.load(at: path)
141141
}
142142

143+
let staticPluginInitializers: [String: PluginInitializationFunction]
144+
145+
// This MUST be a compile-time check because the module dependencies on the plugins are conditional.
146+
// Minimize the amount of code that is conditionally compiled to avoid breaking the build during refactoring.
143147
#if USE_STATIC_PLUGIN_INITIALIZATION
144-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBAndroidPlatformPlugin") {
145-
SWBAndroidPlatform.initializePlugin(pluginManager)
146-
}
147-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBApplePlatformPlugin") {
148-
SWBApplePlatform.initializePlugin(pluginManager)
149-
}
150-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBGenericUnixPlatformPlugin") {
151-
SWBGenericUnixPlatform.initializePlugin(pluginManager)
152-
}
153-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBQNXPlatformPlugin") {
154-
SWBQNXPlatform.initializePlugin(pluginManager)
155-
}
156-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBUniversalPlatformPlugin") {
157-
SWBUniversalPlatform.initializePlugin(pluginManager)
158-
}
159-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBWebAssemblyPlatformPlugin") {
160-
SWBWebAssemblyPlatform.initializePlugin(pluginManager)
161-
}
162-
if !skipLoadingPluginsNamed.contains("com.apple.dt.SWBWindowsPlatformPlugin") {
163-
SWBWindowsPlatform.initializePlugin(pluginManager)
164-
}
148+
staticPluginInitializers = [
149+
"Android": SWBAndroidPlatform.initializePlugin,
150+
"Apple": SWBApplePlatform.initializePlugin,
151+
"GenericUnix": SWBGenericUnixPlatform.initializePlugin,
152+
"QNX": SWBQNXPlatform.initializePlugin,
153+
"Universal": SWBUniversalPlatform.initializePlugin,
154+
"WebAssembly": SWBWebAssemblyPlatform.initializePlugin,
155+
"Windows": SWBWindowsPlatform.initializePlugin,
156+
]
157+
#else
158+
staticPluginInitializers = [:]
165159
#endif
166160

161+
if useStaticPluginInitialization {
162+
for (infix, initializer) in staticPluginInitializers where !skipLoadingPluginsNamed.contains("com.apple.dt.SWB\(infix)PlatformPlugin") {
163+
initializer(pluginManager)
164+
}
165+
}
166+
167167
registerExtraPlugins(pluginManager)
168168
}
169169

Sources/SWBUniversalPlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Foundation
1616
import SWBTaskConstruction
1717
import SWBTaskExecution
1818

19-
@PluginExtensionSystemActor public func initializePlugin(_ manager: MutablePluginManager) {
19+
public let initializePlugin: PluginInitializationFunction = { manager in
2020
manager.register(UniversalPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)
2121
manager.register(UniversalPlatformTaskProducerExtension(), type: TaskProducerExtensionPoint.self)
2222
manager.register(UniversalPlatformTaskActionExtension(), type: TaskActionExtensionPoint.self)

Sources/SWBUtil/PluginManager.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,13 @@ private final class ImmutablePluginManager: Sendable, PluginManager {
221221
}
222222
}
223223
}
224+
225+
public typealias PluginInitializationFunction = @Sendable @PluginExtensionSystemActor (_ manager: MutablePluginManager) -> ()
226+
227+
public var useStaticPluginInitialization: Bool {
228+
#if USE_STATIC_PLUGIN_INITIALIZATION
229+
true
230+
#else
231+
false
232+
#endif
233+
}

Sources/SWBWebAssemblyPlatform/Plugin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import SWBCore
1515
import SWBMacro
1616
import Foundation
1717

18-
@PluginExtensionSystemActor public func initializePlugin(_ manager: MutablePluginManager) {
18+
public let initializePlugin: PluginInitializationFunction = { manager in
1919
manager.register(WebAssemblyPlatformSpecsExtension(), type: SpecificationsExtensionPoint.self)
2020
manager.register(WebAssemblyPlatformExtension(), type: PlatformInfoExtensionPoint.self)
2121
manager.register(WebAssemblySDKRegistryExtension(), type: SDKRegistryExtensionPoint.self)

0 commit comments

Comments
 (0)