Coder Social home page Coder Social logo

xcframework-with-dep-example's Introduction

Distribute XCFramework with mixed implementation only and exported dependencies

We have an SDK that we would to share as XCFramework. This SDK has some proprietary transitive dependencies

SDK
—>ImpOnlyA
—>ImpOnlyB
—>PublicSDK

ImpOnly* are imported as @_implementationOnly while PublicSDK must be exposed by SDK and is imported as @_exported

Each SDK has its own Xcode project file with Enable Libraries For Distribution at true.

We build our XCFramework from the SDK root using Carthage script carthage build --platform iOS --no-skip-current --use-xcframeworks

Once built we add it to a consumer app. The xcframework is added as usual inside the app project and we are able to build, launch and archive, basically “It works on my machine”. The issue comes when we distribute the xcframework, right after trying to build it an error message is displayed AppDelegate.swift:9:8: Missing required modules: 'ImpOnlyA', 'ImpOnlyB', 'PublicSDK'

I’ve also discovered that if I delete the DerivedData I can reproduce the same error, and that if I use again the script to build the SDK the error disappear. So it seems that the consumer is looking for something in the derived data that comes form the SDK xcframework creation. Dependencies are added to the SDK with SPM, but I tried also to add them as Xcode project and add linking manually, but the problem is till the same.

Following a lot of discussions on Swift forums, SO and Apple developers forum I’ve found this conclusion

  • Xcode doesn’t generate .swiftinterface for Swift packages, even linked dynamically as frameworks
  • Without library evolution, an XCFramework can’t reference symbols from a framework built from a source Swift package Mostly I think that this discussion from neonacho sump pretty well the issue “The general issue here is that the Swift compiler needs to be able to see all the modules being used at build-time, either via .swiftmodule/.swiftinterface or module maps. A single XCFramework can only contain one such module, though.”

Then he suggests some workarounds:

  • You could use @_implementationOnly import for the modules from the third-party SDK if you aren't using anything from that SDK as part of your module's public interface.
  • You provide the third-party SDK separately, e.g. as its own XCFramework. The important part here is that you need to make sure that it doesn't get linked statically into your other XCFramework, otherwise you will run into duplicated symbols. For packages that means making any library products dynamic. This might require some significant effort since there could be more transitive dependencies.
  • You provide the additional module definitions out-of-band and make sure they get found at build-time by the compiler using search paths.

The first one is not violable for us, since we want to expose “PublicSDK” The second neither because we would like to avoid our clients to access the dependencies The third could be interesting because it seems that along with the xcframework we just need to add module files but I’ve tried a lot without solving the issues, so far I’ve done:

  • Create an xcframework for each dependencies to leverage Xcode create the .swiftmodule
  • Tried to reference them in the consumer app using Swift Search Path -> Import path
  • Tried reference them from “header search path”
  • Tried reference them from “”framework search path” Basically I don’t know which Xcode flag should I use and where to point it.

The MVP project is available here https://www.dropbox.com/s/bxoqoaxpu2o9t6u/MVP.zip?dl=0

References:

https://kean.blog/post/xcframeworks-caveats

https://forums.swift.org/t/issue-with-third-party-dependencies-inside-a-xcframework-through-spm/41977/3

https://forums.swift.org/t/spm-dependency-problem-missing-required-module/44633/2

https://forums.swift.org/t/distribute-xcframework-of-a-swift-packages-with-local-transient-dependencies/55698/4

https://mustafa-ysf.medium.com/creating-xcframework-from-swift-package-e8af6f44501f

https://vanthanhtran245.github.io/properly-build-a-dynamic-framework-containing-a-static-one/

xcframework-with-dep-example's People

Contributors

drama999 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.