Hive Hive
Sign in

SPM Plugin support for Package.swift

GitHub issue · Open

Metadata
Source
tuist/tuist #6096
Updated
Jun 11, 2026
Domains
Generated projects
Details

What problem or need do you have?

When moving from external Package dependencies to Package.swift there is currently no SPM Plugin support.

Potential solution

No response

macOS version

14.3.1

Tuist version

4.6.0

Xcode version

15.3

Comments
P
pepicrft May 14, 2024

For anyone interested in implementing this one. The implementation should be similar to the Swift Macros one. A plugin is a CLI that’s then invoked using the -load-plugin-executable Swift compiler flag. So the following is needed:

  • A target dependency between the target that uses the build plugin, and the target that represents the build plugin (command line tool)
  • A -load-plugin-executable flag in the Swift compiler flag build setting to point to the executable in the derived data directory.
A
AnthonyMDev Sep 30, 2024

+1 to this. Would really like to see this implemented.

We want to use the Benchmarks library, but this functions as an SPM executable target and uses an SPM plugin.

Y
YIshihara11201 Jun 21, 2025

Hi! I’d like to work on this issue.

F
fortmarek Jun 21, 2025

Hi! I’d like to work on this issue.

This would be amazing @YIshihara11201 💜 Let us know if you need any help/extra pointers 😌

Y
YIshihara11201 Jun 21, 2025

Hi @fortmarek !

I took some time to go through the codebase to better understand this issue.

A target dependency between the target that uses the build plugin, and the target that represents the build plugin (command line tool) A -load-plugin-executable flag in the Swift compiler flag build setting to point to the executable in the derived data directory.

For the second part, I roughly identified where it is handled:

◼︎ Locating the executable
- GraphTraverser.allSwiftPluginExecutables
◼︎ Setting the -load-plugin-executable flag for the swiftc command
- ConfigGenerator.swiftMacrosDerivedSettings
◼︎ Placing the executable in a path where it can be loaded via -load-plugin-executable
- BuildPhaseGenerator.generateBuildPhase

As for the first part, I feel I need to better understand the problem this issue refers to. Specifically, what does the phrase “moving from external Package dependencies to Package.swift” actually mean in this context? It would be very helpful if you could clarify what specific steps or changes this phrase refers to.

P
pepicrft Jun 23, 2025

@YIshihara11201 there are two ways to integrate packages: - The official one where Xcode takes care of everything and the one where Tuist converts everything into Xcode targets.

This issue is about supporting the latter, so a built plugin is an executable. You would need to create a target in a project that is an executable, and then those built plugins need to be compiled before the target that needs them. So you need to declare a target dependency, and then you need to adjust the build setting in the target that depends on the built plugin to tell the Swift compiler to use the executable.

Does that help?

Y
YIshihara11201 Jun 23, 2025

@pepicrft
Thank you for the response.

I’ve reviewed your advice alongside the codebase, and I’m currently organizing what needs to be done before diving into the implementation.

It might take me a couple of days, as I need to wrap my head around how the SPM plugin system itself works, and a few other things.

Before I start coding in earnest, would you mind reviewing my current understanding and planned approach? I’d really appreciate your feedback.

Y
YIshihara11201 Jun 24, 2025

@pepicrft Let me check some word definitions in this message.

Q1

The official one where Xcode takes care of everything

Is this referring to the process to add .package(url:) to Project's property of packages in Project.swift as following ?

let project = Project(
name: "Framework",
packages: [
.package(url: "https://github.com/ordo-one/package-benchmark", .upToNextMajor(from: "1.4.0")),
],
// ...

For this case, after tuist install tuist generate: plugin is treated as a native package dependency.

Q2

the one where Tuist converts everything into Xcode targets.

Does this mean we must convert SPM plugin dependency defined in Package.swift into Xcode Projects, create targets, and set up dependencies between those targets ?

F
fortmarek Jun 24, 2025

Is this referring to the process to add .package(url:) to Project’s property of packages in Project.swift as following ?

Right, that use case is already supported.

Does this mean we must convert SPM plugin dependency defined in Package.swift into Xcode Projects, create targets, and set up dependencies between those targets ?

That’s exactly right. An important piece is the PackageInfoMapper that does the majority of the mapping from SwiftPM definition to the Tuist definition. This mapping currently does not support SwiftPM plugins. If you search for macro in that file, you’ll see the important bits for converting a macro into the Tuist definition.

Y
YIshihara11201 Jun 29, 2025

Hi!

I’m doing some experiments and would like to clarify one point.

I selected SwiftLintPlugin as a sample and noticed that the plugin depends on SwiftLintBinary.artifactbundle.zip instead of an xcframework.

Does this mean we would need to introduce a new architecture to handle this pattern properly? Or is there an existing approach that I might have overlooked?

F
fortmarek Jun 30, 2025

Does this mean we would need to introduce a new architecture to handle this pattern properly? Or is there an existing approach that I might have overlooked?

You will need to unzip the bundle when generating the project – and then grab the .xcframework that should be inside the archive. It might be good to start with that in a separate PR or choose a different plugin that doesn’t depend on a zipped binary target.

Y
YIshihara11201 Jul 24, 2025

I would like to confirm the expected behavior.

With SPM’s native behavior, when a plugin is added as a dependency, it is automatically listed under Run Build Tool Plug-ins in Xcode.

When supporting SPM plugins in Tuist, is it expected that the same behavior should occur?

F
fortmarek Jul 25, 2025

The build tool plug-in support for the XcodeProj-based integration will look more like macros where we use macOS executables and build phases:

This screenshot is taken from multiplatform_app_with_swift_macros fixture that might be good for you to inspect before doing any work on this one. Let me know if you need any help btw 🙂

Y
YIshihara11201 Aug 10, 2025

@fortmarek

This screenshot is taken from multiplatform_app_with_swift_macros fixture that might be good for you to inspect before doing any work on this one.

I’ve studied the macro workflow and am now applying that approach to SPM plugin integration. In this PR (#7990), I added a test fixture to verify the behaviour and left several comments. I’d appreciate your review to confirm whether I’m moving in the right direction. 🙏