Skip to content

Commit 7f86b2c

Browse files
authored
WIP: Support for building plugin dependencies for the host (#6060)
Hacky support for building plugin dependencies for the host. This is achieved by creating a second build operation with altered build parameters and individually building dependencies using that build operation, somewhat similar to how command plugins operate.
1 parent 9fbd3fb commit 7f86b2c

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

Sources/Build/BuildOperation.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
394394
let prebuildCommandResults: [ResolvedTarget: [PrebuildCommandResult]]
395395
// Invoke any build tool plugins in the graph to generate prebuild commands and build commands.
396396
if let pluginConfiguration = self.pluginConfiguration {
397+
let buildOperationForPluginDependencies = try BuildOperation(buildParameters: self.buildParameters.withDestination(self.buildParameters.hostTriple), cacheBuildManifest: false, packageGraphLoader: { return graph }, additionalFileRules: self.additionalFileRules, pkgConfigDirectories: self.pkgConfigDirectories, outputStream: self.outputStream, logLevel: self.logLevel, fileSystem: self.fileSystem, observabilityScope: self.observabilityScope)
397398
buildToolPluginInvocationResults = try graph.invokeBuildToolPlugins(
398399
outputDir: pluginConfiguration.workDirectory.appending(component: "outputs"),
399400
builtToolsDir: self.buildParameters.buildPath,
@@ -403,7 +404,14 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
403404
pluginScriptRunner: pluginConfiguration.scriptRunner,
404405
observabilityScope: self.observabilityScope,
405406
fileSystem: self.fileSystem
406-
)
407+
) { name, path in
408+
try buildOperationForPluginDependencies.build(subset: .product(name))
409+
if let builtTool = try buildOperationForPluginDependencies.buildPlan.buildProducts.first(where: { $0.product.name == name}) {
410+
return builtTool.binaryPath
411+
} else {
412+
return nil
413+
}
414+
}
407415

408416

409417
// Surface any diagnostics from build tool plugins.

Sources/SPMBuildCore/BuildParameters.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,50 @@ public struct BuildParameters: Encodable {
293293
self.verboseOutput = verboseOutput
294294
}
295295

296+
public func withDestination(_ destinationTriple: Triple) throws -> BuildParameters {
297+
let forceTestDiscovery: Bool
298+
let testEntryPointPath: AbsolutePath?
299+
switch self.testProductStyle {
300+
case .entryPointExecutable(let explicitlyEnabledDiscovery, let explicitlySpecifiedPath):
301+
forceTestDiscovery = explicitlyEnabledDiscovery
302+
testEntryPointPath = explicitlySpecifiedPath
303+
case .loadableBundle:
304+
forceTestDiscovery = false
305+
testEntryPointPath = nil
306+
}
307+
308+
return .init(
309+
dataPath: self.dataPath.parentDirectory.appending(components: ["plugins", "tools"]),
310+
configuration: self.configuration,
311+
toolchain: try UserToolchain(destination: Destination.hostDestination()),
312+
hostTriple: self.hostTriple,
313+
destinationTriple: destinationTriple,
314+
flags: BuildFlags(),
315+
pkgConfigDirectories: self.pkgConfigDirectories,
316+
architectures: nil,
317+
workers: self.workers,
318+
shouldLinkStaticSwiftStdlib: self.shouldLinkStaticSwiftStdlib,
319+
shouldEnableManifestCaching: self.shouldEnableManifestCaching,
320+
canRenameEntrypointFunctionName: self.canRenameEntrypointFunctionName,
321+
shouldCreateDylibForDynamicProducts: self.shouldCreateDylibForDynamicProducts,
322+
sanitizers: self.sanitizers,
323+
enableCodeCoverage: self.enableCodeCoverage,
324+
indexStoreMode: self.indexStoreMode,
325+
enableParseableModuleInterfaces: self.enableParseableModuleInterfaces,
326+
emitSwiftModuleSeparately: self.emitSwiftModuleSeparately,
327+
useIntegratedSwiftDriver: self.useIntegratedSwiftDriver,
328+
useExplicitModuleBuild: self.useExplicitModuleBuild,
329+
isXcodeBuildSystemEnabled: self.isXcodeBuildSystemEnabled,
330+
enableTestability: self.enableTestability,
331+
forceTestDiscovery: forceTestDiscovery,
332+
testEntryPointPath: testEntryPointPath,
333+
explicitTargetDependencyImportCheckingMode: self.explicitTargetDependencyImportCheckingMode,
334+
linkerDeadStrip: self.linkerDeadStrip,
335+
colorizedOutput: self.colorizedOutput,
336+
verboseOutput: self.verboseOutput
337+
)
338+
}
339+
296340
/// The path to the build directory (inside the data directory).
297341
public var buildPath: AbsolutePath {
298342
if isXcodeBuildSystemEnabled {

Sources/SPMBuildCore/PluginInvocation.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ extension PackageGraph {
335335
pkgConfigDirectories: [AbsolutePath],
336336
pluginScriptRunner: PluginScriptRunner,
337337
observabilityScope: ObservabilityScope,
338-
fileSystem: FileSystem
338+
fileSystem: FileSystem,
339+
builtToolHandler: (_ name: String, _ path: RelativePath) throws -> AbsolutePath? = { _, _ in return nil }
339340
) throws -> [ResolvedTarget: [BuildToolPluginInvocationResult]] {
340341
var pluginResultsByTarget: [ResolvedTarget: [BuildToolPluginInvocationResult]] = [:]
341342
for target in self.reachableTargets.sorted(by: { $0.name < $1.name }) {
@@ -375,7 +376,11 @@ extension PackageGraph {
375376
var builtToolNames: [String] = []
376377
let accessibleTools = try pluginTarget.processAccessibleTools(packageGraph: self, fileSystem: fileSystem, environment: buildEnvironment, for: try pluginScriptRunner.hostTriple) { name, path in
377378
builtToolNames.append(name)
378-
return builtToolsDir.appending(path)
379+
if let result = try builtToolHandler(name, path) {
380+
return result
381+
} else {
382+
return builtToolsDir.appending(path)
383+
}
379384
}
380385

381386
// Determine additional input dependencies for any plugin commands, based on any executables the plugin target depends on.

0 commit comments

Comments
 (0)