SPM dependency between multiple packages

516 Views Asked by At

I'm trying to create SPM hierarchy where some packages have dependecies on other, like this: Package A is Core package where I also added dependencies to some external libraries and where I keep most of my native code:

let package = Package(
    name: "Core",
    platforms: [
      .iOS(.v14)
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
        .library(
            name: "Core",
            targets: ["Core"]),
    ],
    dependencies: [
      .package(url: "https://github.com/mxcl/PromiseKit", .exact("6.13.1")),
      .package(url: "https://github.com/PromiseKit/Foundation.git", from: "3.0.0"),
    ],
    targets: [
        .target(
            name: "Core",
            dependencies: [
                           .product(name: "PMKFoundation", package: "Foundation"),
                           "PromiseKit",
                          ]),
        .testTarget(
            name: "CoreTests",
            dependencies: ["Core"]),
    ]
)

Then I have package B, which has dependency on local package A, this package has only few classes but it should have access to external dependencies used by Core package:

let package = Package(
    name: "Package_B",
    platforms: [
      .iOS(.v14)
    ],
    products: [
        .library(
            name: "Package_B",
            targets: ["Package_B"]),
    ],
    dependencies: [
      .package(path: "../Core"),
    ],
    targets: [
        .target(
            name: "Package_B",
            dependencies: [
              "Core",
              "PromiseKit",
            ]),
        .testTarget(
            name: "Package_BTests",
            dependencies: ["Package_B"]),
    ]
)

And Package C which has dependency on package B - it should has access to code from package B, to code from Core package and to external dependencies from Core package:

let package = Package(
    name: "Package_C",
    products: [
        .library(
            name: "Package_C",
            targets: ["Package_C"]),
    ],
    dependencies: [
      .package(path: "../Package_B"),
      .package(url: "https://github.com/ZipArchive/ZipArchive.git", from: "2.2.0"),
    ],
    targets: [
        .target(
            name: "Package_C",
            dependencies: ["Core","Package_B", "PromiseKit", "ZipArchive"]),
        .testTarget(
            name: "Package_CTests",
            dependencies: ["Package_C"]),
    ]
)

Problem which I have is that for start Package_B is showing error in xcode:

x-xcode-log://7C2F67D1-F6A1-4BE1-8E94-DC7E769241AD product 'PromiseKit' required by package 'Package_B' target 'Package_B' not found.

I can add this line to Package_B dependency but it will not solve the issue:

.package(url: "https://github.com/mxcl/PromiseKit", .exact("6.13.1")),

I can then try to compile the code but I got antoher errors like:

No such module 'PromiseKit'
No such module 'Core'

When I'm trying to Import those modules

Has anyone has some idea how to create a tree of dependecies between local packages which can be later used in multiple projects?

1

There are 1 best solutions below

1
kokluch On

Package B must declare in its own dependencies and Package C must declare Core in its dependencies as well.

let package = Package(
name: "Package_B",
platforms: [
  .iOS(.v14)
],
products: [
    .library(
        name: "Package_B",
        targets: ["Package_B"]),
],
dependencies: [
  .package(path: "../Core"),
  .package(url: "https://github.com/mxcl/PromiseKit", .exact("6.13.1")),
  .package(url: "https://github.com/PromiseKit/Foundation.git", from: "3.0.0"),
],
],
targets: [
    .target(
        name: "Package_B",
        dependencies: [
          "Core",
          "PromiseKit",
        ]),
    .testTarget(
        name: "Package_BTests",
        dependencies: ["Package_B"]),
]

)

let package = Package(
name: "Package_C",
products: [
    .library(
        name: "Package_C",
        targets: ["Package_C"]),
],
dependencies: [
  .package(path: "../Core"),
  .package(path: "../Package_B"),
  .package(url: "https://github.com/ZipArchive/ZipArchive.git", from: "2.2.0"),
],
targets: [
    .target(
        name: "Package_C",
        dependencies: ["Core","Package_B", "PromiseKit", "ZipArchive"]),
    .testTarget(
        name: "Package_CTests",
        dependencies: ["Package_C"]),
]

)