skip to Main Content

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


  1. Chosen as BEST ANSWER

    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

    1. Create the wrapping xcframeworks (CLib1 and CLib2) without the headers and module.modulemap. xcodebuild -create-xcframework -library /path/to/lib1

    2. Setup binary targets in the Swift package MySwiftPackage that pull in these frameworks

    3. Add a include directory in the main targets of MySwiftPackage. Add the headers of CLib1 and CLib2 to this folder.

    4. Create a single custom module.modulemap which setups modules for both CLib1 and CLib2. Save it in the include folder.

    5. Add csettings to the target on MySwiftPackage. Set the headerSearchPath to the include folder

    While 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).


  2. You can put the headers and the module.modulemap in another subdirectory than headers, like lib1 and lib2.

    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:

    xcodebuild -create-xcframework -library ... -headers ...
    

    And it should pick up the headers.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search