Accessing Resources of other package targets or dependencies using Swift Package Manager

Good day I am developing XRKit framework, which contains the pipeline logic for rendering using Metal, in manifest it has two targets - framework itself in Swift and XRKitDefenitions in C++ and MSL (since Apple forbids us multilingualism in one package). Both targets have Resources folders open in their manifest.

When I try to access the test files hello01.txt (Resources for XRKit) and hello2.txt (Resources for XRKitDefenitions) via Bundle.module, I only see hello01.txt and it doesn't read hello2.txt because it's in a different target.

How do I properly organize my code with SPM to access the Resources of XRKitDefenitions target?

PS When trying to organize XRKitDefenitions as a remote package on GitHub and defining it as a dependency, situation does not change. I understand now that Bundle.module only refers to its Resources. Is there a way to refer to resources that provided other targets or dependencies in the same package?

Accepted Reply

Solution to my question is as follows:

  • "Child" package with C++ code now contains only ‘.c’ and ‘.h’ files linked to each other;
  • «Рarent» package with Swift code contains ‘*.metal’ file with the shaders (now in root directory, but this is easy to fix);
  • Necessary headers in the .metal file are now accessed like this: 
#include "../XRKitDefenitions/include/VertexAttributes.h"
#include "../XRKitDefenitions/include/TextureIndices.h"
  • Complete ‘Package.swift’ code now looks like this:
let package = Package(
    name: "XRKit",
    platforms: [.macOS(.v10_15), .iOS(.v13)],
    products: [
        .library(name: "XRKit", targets: ["XRKit"]),
        .library(name: "XRKitDefenitions", targets: ["XRKitDefenitions"])
    ],
    targets: [
        .target(
            name: "XRKitDefenitions",
            path: "Sources/XRKitDefenitions",
            cxxSettings: [
                .headerSearchPath("../include/")
            ]
        ),
        .target(
            name: "XRKit",
            dependencies: ["XRKitDefenitions"],
            path: "Sources/XRKit",
            resources: [
                .copy("Shaders.metal"),
            ]
        )
    ]
)
  • Create MTLLibrary like this:
self.mtlDevice.makeDefaultLibrary(bundle: .module);

It was interesting to figure out on my own how it could work for my case :)

Replies

Solution to my question is as follows:

  • "Child" package with C++ code now contains only ‘.c’ and ‘.h’ files linked to each other;
  • «Рarent» package with Swift code contains ‘*.metal’ file with the shaders (now in root directory, but this is easy to fix);
  • Necessary headers in the .metal file are now accessed like this: 
#include "../XRKitDefenitions/include/VertexAttributes.h"
#include "../XRKitDefenitions/include/TextureIndices.h"
  • Complete ‘Package.swift’ code now looks like this:
let package = Package(
    name: "XRKit",
    platforms: [.macOS(.v10_15), .iOS(.v13)],
    products: [
        .library(name: "XRKit", targets: ["XRKit"]),
        .library(name: "XRKitDefenitions", targets: ["XRKitDefenitions"])
    ],
    targets: [
        .target(
            name: "XRKitDefenitions",
            path: "Sources/XRKitDefenitions",
            cxxSettings: [
                .headerSearchPath("../include/")
            ]
        ),
        .target(
            name: "XRKit",
            dependencies: ["XRKitDefenitions"],
            path: "Sources/XRKit",
            resources: [
                .copy("Shaders.metal"),
            ]
        )
    ]
)
  • Create MTLLibrary like this:
self.mtlDevice.makeDefaultLibrary(bundle: .module);

It was interesting to figure out on my own how it could work for my case :)