.swiftinterface "No such module" in XCFramework

Hello everyone!

I've been trying to build an XCFramework from my program that wraps C code into Swift and I need it to support both x86_64 and arm64 archs for MacOS. I have succeeded in creating a .framework that combines the two binaries from both architectures into a single universal fat file using lipo -create -output and once I implement this .framework into any Xcode project, it works right out of the box and I'm able to import it and use it without major issue.

The trouble begins when I try to generate an XCFramework using this exact same universal .framework. I'm running xcodebuild -create-xcframework -framework /myFramework.framework -output myXCFramework.xcframework as you do normally and the XCFramework is generated successfully, but. when I try including it in an Xcode Project, I get a 'No such module' on the .swiftinterface file, specifically in the imported module that wraps my C code and maps it into Swift.

I appreciate any help or pointers!

The error is indicating that the textual Swift interface (a .swiftinterface file) of the xcframework contains import CFaspIO and the compiler cannot find any module with that name. The build log should show you where this .swiftinterface file is located on disk and you can open it directly to view its contents.

I'm guessing CFaspIO is the internal clang module for the underlying C implementation of this framework - is that right? If so, then CFaspIO is an internal implementation detail of the FaspIO module and you need to ensure that references to CFaspIO don't appear in the interface of the framework. The way to do that currently is to make sure that every import of CFaspIO in your Swift sources has @_implementationOnly before it.

A couple things to note:

  • You won't be able to reference any types from CFaspIO in the public interfaces of the framework since to external clients, that module doesn't exist.
  • @_implementationOnly is an underscored attribute, which means it's not official part of the language and could be subject to change or removal in a future version of the compiler.

EDIT: You may also find this older thread helpful if you're trying to accomplish something similar.

1 Like

Hello @tshortli, thank you for your answer! CFaspIO is just a Swift module that wraps C code, correct. We don't want to show anything CFaspIO-related to external clients. So is there a way to explicitly locate the module CFaspIO so that the compiler knows where it can be found? What's confusing to me is the fact that this reference to the CFaspIO module is present in the universal .framework but once I build the XCFramework with it, the module (or at least where to find it) is lost in the process.

The purpose of using @_implementationOnly import is to ensure that the clients of your framework don't need to find the module definition of CFaspIO.

1 Like

Using @_implementationOnly import instead of a normal import solved the issue. Thank you so much!

1 Like