[Pitch] SwiftPM: Allow targets to depend on products in the same package

I found this thread trying to solve a problem I have with SwiftPM.

I have a similar challenge to what has been discussed in this thread, but with a twist: I use a plugin to generate a lot of code on my behalf. As the API surface that my generator produces grows in scope, I found myself needing to split the code into multiple libraries, as the full library was becoming too large [1].

The simple solution of splitting the library in individual libraries that depend on others does not work. I have a setup where I have components that depend on each other, I have a “core” library; a “2d” library, a “3d” library, a “controls” library that depend on Core.

On top of these, I have an “XR” library that depends on “3d”, an “editor” library that depends on all the previous ones, and SwiftPM decides that the higher level libraries should get a full copy of any of its dependencies, which sounds good, except when you have code that uses both 2D and 3D, and all of a sudden I two Cores loaded. Gets worse with the even higher levels.

I found out that I could introduce a dependency like this:

 .package(name: "SwiftGodot", path: ".")

And then consume it like this:

        .target(
            name: "SwiftGodot2D",
            dependencies: [
                .product(name: "SwiftGodotCore", package: "SwiftGodot")
            ]
        ),

And this would produce properly isolated dylibs.

But with the real project, one that has the plugins and dependencies, I kept crashing Xcode[3] and kept crashing SwiftPM 6.2.

Oddly, this works with SwiftPM if I use Swift 6.1.2, but fails with 6.2 [4]

I found this thread trying to figure whether my scenario is supported. At this point, I am not sure if this was supported by accident and 6.2 regressed the accidental support, or if this was never supported.

The pain expressed on the previous posts is real (having to split up the code in subprojects), but is exacerbated by having to rely on both plugins and generators that are in “..”, which SwiftPM disallows, so I can not just use the approach where I move these packages into a subdirectory.

It seems like the only solution is to make replicas of the code generator and plugin for every one of the submodules, and that sounds brutal.

[1] Some of the issues: slow to build; auto-complete does not work and is very unreliable; Windows symbol limits imposing a physical stop to how much the API can grow and a library that contained too much for people that used a fraction.

[2] gist:d31b31f9ccc04b404b8f87a5bd11260c · GitHub

[3] Xcode crash: gist:0174e0a49aeefb99d0d9fe862b4ca17b · GitHub

[4] My code in a branch showing the exact use case: GitHub - migueldeicaza/SwiftGodot at split-crash make sure you use the “split-crash” branch after the checkout.

2 Likes