Hive
SPM build tool plugins (e.g. SwiftLint) not emitted as PBXBuildToolPlugin/buildToolPlugins
GitHub issue · Open
What happened?
- Add a build-tool plugin package to the project packages (example in Tuist/Package.swift).
- Add the plugin as a target dependency, e.g.: .package(product: “SwiftLintBuildToolPlugin”, type: .plugin) and include it in a target dependency (.package(product: “…”, type: .plugin))
- Run
tuist generate. - Open the generated Xcode project and build a target that should use the plugin.
- Inspect generated project file
*.xcodeproj/project.pbxproj.
How do we reproduce it?
- Add a build-tool plugin package to the project packages (example in Tuist/Package.swift).
- Add the plugin as a target dependency, e.g.: .package(product: “SwiftLintBuildToolPlugin”, type: .plugin) and include it in a target dependency (.package(product: “…”, type: .plugin))
- Run
tuist generate. - Open the generated Xcode project and build a target that should use the plugin.
- Inspect generated project file
*.xcodeproj/project.pbxproj.
Error log
1) Target block shows a PBXTargetDependency referencing the plugin product:
<ANON_TARGET> /* PBXNativeTarget / = { isa = PBXNativeTarget; buildPhases = ( / Sources /, / Resources /, / Frameworks /, ); buildRules = ( ); dependencies = ( / … /, 0B69D60995D9AD7F00480AFF / PBXTargetDependency */, // plugin dependency entry ); name = “<ANON_TARGET>”; };
0B69D60995D9AD7F00480AFF /* PBXTargetDependency / = { isa = PBXTargetDependency; productRef = 5F9742E781E0E4A2DC0120DD / SwiftLintBuildToolPlugin */; };
2) Package product dependency exists:
5F9742E781E0E4A2DC0120DD /* SwiftLintBuildToolPlugin */ = { isa = XCSwiftPackageProductDependency; productName = “plugin:SwiftLintBuildToolPlugin”; … };
Expected but missing:
- PBXBuildToolPlugin objects section mapping plugin product -> PBXBuildToolPlugin
- buildToolPlugins = ( /* SwiftLintBuildToolPlugin */ ) entries inside the PBXNativeTarget block
Consequence: Xcode does not execute plugin (no plugin run printed in build logs; generated artifacts absent).
macOS version
25.2.0
Tuist version
4.131.1
Xcode version
26.2
Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.
Start a Flight and preserve its objective, outcome, and session here.
Hi @losharik! I’m Dosu and I’m helping the tuist team.
Tuist does not currently support emitting SPM build tool plugins (like SwiftLint) as PBXBuildToolPlugin/buildToolPlugins in the generated Xcode project, which means Xcode won’t execute these plugins during the build. This is a known limitation—there’s an open issue tracking it (#6096), and a prototype PR (#7990) is in progress but not yet merged or complete. The current TargetGenerator only wires up standard dependencies and does not generate the PBX structures required for SPM build tool plugins, so what you’re seeing is expected behavior right now.
If you need plugin functionality immediately, you’ll need to use a manual workaround (like a custom script phase), or keep an eye on the referenced issue and PR for future support. For more details, see the Tuist documentation and the community discussion.
To reply, just mention @dosu.
Docs are dead. Just use Dosu.
@losharik I’d also add to what Dosu said that you can install SwiftLint using Mise, and then invoke SwiftLint from a script build phase in your projects. At the end of the day, SwiftPM build tool plugins are a a convenient distribution and integration tool with slightly less convenient ways of achieveing the same thing. If ou are interested in taking the implementation yourself, we’d be happy to review the code, but we can’t prioritize this at the moment.