Search code examples
swiftxcodeswift-package-manager

Reuse local Swift package in multiple targets


I need to reuse local Swift packages in multiple targets. They are all part of the same workspace which looks something like this

- Workspace
  - ProjectA
    - TargetA1 depends on PackageA
    - TargetA2 depends on PackageA and PackageB
  - ProjectB
    - TargetB1 depends on PackageA
  - ProjectC, etc...
  - Modules
    - PackageA
    - PackageB

The package build products are added under the individual targets General > Frameworks and Libraries dependencies. Now when I trigger the build, I get

Multiple commands produce '.../Modules/PackageA' etc...

which is somewhat understandable, I hoped Xcode would be smart enough to not build the package over and over again, and even if, I don't understand why that would result in an error in the first place.

Is there a reasonable solution to this?

I don't want to start creating static library targets again or create a separate repository just to be able to import it via a package dependency.


Solution

  • Ok, I found a somewhat satisfactory answer to this.

    First, prevent SPM from choosing the library type itself and declare 2 separate build products in the package you want to share:

    ...
    products: [
        .library(name: "PackageA", type: .dynamic, targets: ["PackageA"]),
        .library(name: "PackageAStatic", type: .static, targets: ["PackageA"])
    ],
    ...
    

    One explicitly .dynamic and the other explicitly .static. Now depending on the target you want to use this package in, link the correct one (either dynamic or static). This seems to resolve this issue for me.