I’m trying to build a Swift package containing multiple binary xcframeworks (each of which wrap a different static C library). The .xcframework contains multiple versions of the same library (one per arch type – x86_64, aarch64). I first build the static library for each arch, and then, create the .xcframework with
xcodebuild create-xcframwork -library /path/to/lib_for_arch1 -headers /path/to/headers -library /path/to/lib_for_arch2 -headers /path/to/headers -output MyXcFramework.xcframework
The headers folder above contains the header and a module.modulemap file.
When adding two such binary frameworks to a single Swift package, I get a build error
Showing All Messages
duplicate output file ‘/Path/To/Xcode/DerivedData/MySwiftPackage-djghajsghjsgsjdgh/Build/Products/Debug/include/module.modulemap' on task: ProcessXCFramework /Path/to/BinaryFramework1.xcframework /Path/to/Xcode/DerivedData/MySwiftPackage-djghajsghjsgsjdgh/Build/Products/Debug/include/module.modulemap macos
Showing All Messages
Multiple commands produce '/Path/To/Xcode/DerivedData/MySwiftPackage-djghajsghjsgsjdgh/Build/Products/Debug/include/module.modulemap':
1) Command: ProcessXCFramework /Path/To/Xcode/DerivedData/MySwiftPackage-djghajsghjsgsjdgh/SourcePackages/artifacts/MySwiftPackage/Framework1.xcframework /Path/To/Xcode/DerivedData/MySwiftPackage-djghajsghjsgsjdgh//Build/Products/Debug/include/module.modulemap macos
2) Command: ProcessXCFramework /Path/to/BinaryFramework1.xcframework /Path/To/Xcode/DerivedData/MySwiftPackage-djghajsghjsgsjdgh/Build/Products/Debug/include/module.modulemap macos
As best as I can tell, while processing each binary xcframework, it’s copying the contents of each xcframework’s Headers
folder into the include
folder of the package. When it’s copying the second module.modulemap, it errors out because one already exists (from the first binary xcframework).
I’ve tried wrapping each binary xcframework inside a Swift package of it’s own, and making my primary Swift package depend on these wrapper packages instead. But, I still get the same error.
Any ideas on what the best way forward would be? Thanks
P.S. Using Xcode 12.5.1 and Swift 5.4.2
Edit: Using a Xcode project (that embed two binary xcframeworks similar to the above setup) instead of Swift package, results in the same error as well.
2
Answers
I've gotten it to work by doing the following. Assuming, we are creating two binary frameworks (CLib1.xcframework and CLib2.xcframework - each wrapping a C library). We are going to use these frameworks in a Swift package
MySwiftPackage
Create the wrapping xcframeworks (CLib1 and CLib2) without the headers and module.modulemap.
xcodebuild -create-xcframework -library /path/to/lib1
Setup binary targets in the Swift package MySwiftPackage that pull in these frameworks
Add a include directory in the main targets of MySwiftPackage. Add the headers of CLib1 and CLib2 to this folder.
Create a single custom module.modulemap which setups modules for both CLib1 and CLib2. Save it in the include folder.
Add
csettings
to the target on MySwiftPackage. Set theheaderSearchPath
to the include folderWhile this builds, I'm hoping there is an easier/better way to do this (as removing the module.modulemap from the xcframework's means we always have to custom create one - and it no longer is just a simple import of a binary framework).
You can put the headers and the
module.modulemap
in another subdirectory thanheaders
, likelib1
andlib2
.As the example shows, it is important to chose a directory that is not used by another library. So the library-name is a good choice.
Then you can run the following:
And it should pick up the headers.