Add dependencies to binary targets in Swift Package Manager
Asked Answered
O

1

7

I want to create a Swift Package with binary targets which has sub dependencies. As the binary targets not support sub dependencies out of the box, I have created a wrapper target that depends on both the binary framework and other dependencies as described here

Package has a target called Logger. CocoaLumberjack is a dependency of Logger.

Logger I have generated as XCFramwork and hosted in a server as publicly accessible. Below I have added a screenshot of the Xcode project which I used to generate XCFramwork.

Please refer to the Package manifest file.

import PackageDescription

let package = Package(
    name: "spmpoc",
    products: [
        .library(
            name: "Logger",
            targets: ["LoggerTarget"]),
    ],
    dependencies: [
        .package(
            name: "CocoaLumberjack",
            url: "https://github.com/CocoaLumberjack/CocoaLumberjack.git",
            from: "3.6.1"),
    ],
    targets: [
        .target(
              name: "LoggerTarget",
              dependencies: [.target(name: "LoggerWrapper",
                                     condition: .when(platforms: [.iOS]))]
            ),
        .target(
              name: "LoggerWrapper",
              dependencies: [
                .target(name: "Logger", condition: .when(platforms: [.iOS])),
                .product(name: "CocoaLumberjack", package: "CocoaLumberjack")
              ]
            ),
        .binaryTarget(name: "Logger", url: "https://mypath.com/Logger.xcframework.zip", checksum: "mychecksum")
    ]
)

I am able to add Swift package via Swift Package Manager, but When I try to import Logger module build error occured as ..../Logger.framework/Modules/Logger.swiftmodule/arm64-apple-ios.swiftinterface:4:8: No such module 'CocoaLumberjack'

Could someone please help me to figure out what could be the issue here?

Error enter image description here

XCFramwork code snapshot for reference enter image description here

Update:

I have change import to @_implementationOnly import in Logger.swift. Now in the generated .swiftinterface files does not contains the "import CocoaLumberjack" hence, compile error went away. However, app crashing because it is still looking for CocoaLumberjack.framework but its not available. '.../Library/Developer/Xcode/DerivedData/TestSPMApp-gfbagjtzjrrkjuathrrienvklwxs/Build/Products/Debug-iphonesimulator/CocoaLumberjack.framework/CocoaLumberjack' (no such file) CocoaLumberJack added to Logger framework as a pod dependency. It seems, inside the Pods-Logger.xcconfig file it is referring to CocoaLumberjack.framework. I believe this causes the issue now.

enter image description here

Ortensia answered 11/4, 2022 at 8:40 Comment(4)
try this this answerAlsup
@Alsup Thanks for the input. I had went through the answer and I re-look in to my XCFramwork generation project as well. It seems frameworkes linked correctly there. I had updated my question with XCframework part as well.Ortensia
Try also checking if it is not problem with arm64 simulator , as hereAlsup
In debug mode it has set to Build Active Architecture Only. I tried to build with real device as well, same issue there. I am really not sure if this is due to some misconfiguration in Package.swiftOrtensia
S
2

I think the real issue here is that the dependencies don't need to be a part of your modules's public interface. You would need to replace all instances of import for the dependencies in your code to @_implementationOnly import

E.g.

@_implementationOnly import CocoaLumberjack

You can read more about @_implementationOnly here

Surmullet answered 20/4, 2022 at 8:35 Comment(12)
Though compilation error went away, now app crashing because it is still looking for CocoaLumberjack.framework but its not available. Any idea? '.../Library/Developer/Xcode/DerivedData/TestSPMApp-gfbagjtzjrrkjuathrrienvklwxs/Build/Products/Debug-iphonesimulator/CocoaLumberjack.framework/CocoaLumberjack' (no such file),Ortensia
CocoaLumberJack added to Logger framework as a pod dependency. It seems, inside the Pods-Logger.xcconfig file it is refering to CocoaLumberjack.framework. I believe this causes the issue now. FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers"Ortensia
I think so too, because it works perfectly if I have the dependency added through SPM in the main framework targetSurmullet
I also tried removing Pods-Logger.framework from the Link Binary Libraries of main project. And then generated the Xcframework. Issue still persists. Not sure from where these linker headers coming from :(Ortensia
I am having exact same issue. Do you have any idea how to resolve this problem?Rocket
@Ortensia Are you able to archive the framework after deintegrating cocoapods? I am getting 'no such module XXX' in every place where I am importing the dependency.Rocket
I got it to work - see my answear https://mcmap.net/q/832066/-supporting-3rd-party-dependencies-for-binarytarget-via-spmRocket
@Rocket I still could not resolve the issue. In your approach "added SQLite.swift via SPM" that means you added SQLite via SPM in your main target and then generate the XCframework?Ortensia
@Ortensia yes, using spm instead of cocoapods for your main target works perfectly.Surmullet
@Ortensia exactly, you need to use SPM instead of cocoapods to archive your frameworkRocket
Yeah, I had try with SPM all working fine. But I'm wondering with Cocoapods is it really not possible? I could not found any official statement or such, saying it is not possible. Do you guys have any idea on that?Ortensia
I have accepted this answer even though this is not exact solution. I am still looking for a solution to use cocoapods in the main project and then generate XCframworkOrtensia

© 2022 - 2024 — McMap. All rights reserved.