Using build tool plugin in the project with many targets

Hello,

I created a custom build tool plugin (linter) and I would love to run it for all my targets. My project contains 4 Swift packages and each of them contains a lot of targets. When I use the plugin approx. with half of them, everything works as expected. But when I apply it for one more target, Xcode freezes and the project can't be built anymore.

The same issue has been reported in the SwiftLint repository, which provides its own plugin implementation.

Is there some limit to how many packages can be used with the build tool plugin in one Xcode project?

I get the same issue with Xcode 14.3.1 and Xcode 15.0.0 Beta 4.

1 Like

We're also experiencing this - 1 build plugin for ~50 targets causes a 7-10 second hang before each build.

This happens even if the plugin is completely empty and does nothing, i.e.

import Foundation
import PackagePlugin

@main struct DummyPlugin: BuildToolPlugin {
    func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
        return [ 
            // this plugin does nothing
        ]
    }
}

Has anyone discovered any sort of workaround? We'd LOVE to use a build plugin for some code generation, but a 7-10 second hang per build is pretty much a deal breaker.

Xcode Version 15.0.1 (15A507)

Is this reproducible for you with the SwiftPM CLI when using swift build and swift test?

1 Like

No - it's unfortunately isolated to Xcode :sob:

Guess it's an Xcode, not a SPM issue.

Do you know if there's an issue filed on https://feedbackassistant.apple.com for this? What's the FB number if so?

1 Like

I don't know if one got filed per your rec here but I'll go ahead and file one myself right now and repost the number here in a moment.

Thanks for the quick responses!

1 Like

Sorry for the delay @Max_Desiatov - I wanted to put together a simple to follow demo.

I filed an issue on feedback assistant, it's 13296864. I also created a dummy repo to demonstrate the issue:

Essentially - its 100 targets with 100 single line files each. The 100th target depends on the other 99. All targets use a build plugin that does nothing.

If you build the 100th target, you'll see a hang / beach ball (5.6s on my 2023 M2 Max) on EVERY build. Even ones where nothing was changed. Comment out the build plugin in the Package.swift and builds will be instant.

It seems to be related to having files in each dependency - I noticed if each dependency has a single file, the builds are basically instant - even with the build plugin. Perhaps there is an inefficient file lookup going on in the background?

EDIT:

Another note; the hang only happens when building in Xcode. Using swift build is much more efficient (the first build took a while since it was from scratch).

2 Likes

@Max_Desiatov out of curiosity are there any temporary workarounds that we might be able to use? Would love to use build plugins @ a large scale if it's possible.

And please let me know if there's any way I can help resolve or provide more info!