SPM: Custom Framework with multiple targets

I have a framework with two targets (A and B) with the following file structure:

FooFramework
|__ A
     |__ Foo.swift
     |__ Bar.swift
     |__ Foobar.swift
|__ B
     |__ Barfoo.swift

B basically has a subset of A's files (where B is set as a target), e.g. B only uses Foo.swift and Bar.swift, but not Foobar.swift.

Now I have an app that needs both framework A and B (for different targets).

At this point I'm unsure how to setup the Package.swift file for the setup to work. Whenever I open the Package.swift in Xcode and try to build framework B, the compiler is complaining about missing types in Barfoo.swift, because they are included in Bar.swift.

This is how I've setup the Package.swift file:

// swift-tools-version:5.3

import PackageDescription

let package = Package(
    name: "Framework",
    platforms: [
        .iOS(.v11),
        .macOS(.v10_15)
    ],
    products: [
        .library(
            name: "A",
            targets: ["A"]),
        .library(
            name: "B",
            targets: ["B"]),
    ],
    dependencies: [
        .package(name: "Dependency", url: "https://github.com/...", .exact("1.0.0"))
    ],
    targets: [
        .target(
            name: "A",
            dependencies: [
                "Dependency",
            ],
            path: "A",
            exclude: [
                "Info.plist",
            ],
            resources: [
                .process("fonts"),
            ]
        ),
        .target(
            name: "B",
            dependencies: ["A"],
            path: "B",
            exclude: [
                "Info.plist",
            ],
            resources: [
                .process("../A/fonts"),
            ]),
        .testTarget(
            name: "ATests",
            dependencies: ["A"],
            path: "ATests",
            exclude: [
                "Info.plist"
            ]
        )
    ]
)

Any ideas how I would correctly set this up?

I've cross posted this question on StackOverflow: ios - Framework with multiple targets and shared sources - Stack Overflow

No solution as of yet.

There isn’t much to say beyond what is already in the other thread you linked from Stack Overflow:

If it were me, I would simply factor the shared files out into a module C that both A and B can depend on.

Sharing files between targets isn’t something SwiftPM intentionally supports at the moment, but if none of the workarounds from the other thread work for you, you might be able to use symlinks to trick SwiftPM into thinking there are two separate files.

2 Likes

I wouldn't mind having a common's module, if it weren't for the @_exported import syntax you mentioned in the other thread.

I think I'll try out the symlinking approach, just to see, if it works.

In the end I'll probably just not offer B as SPM package, until there is a native support for it.

Terms of Service

Privacy Policy

Cookie Policy