hennes
hennes

Reputation: 9352

Vendoring xcframework with fat static libraries for multiple architectures from Cocoapods in a React Native turbo module

I'm developing a React Native turbo module that needs to vendor an XCFramework.

The XCFramework (obtained from here) contains static libraries for three different architectures.

MatrixSDKFFI.xcframework
├── Info.plist
├── ios-arm64
│   ├── Headers
│   │   ├── matrix_sdkFFI.h
│   │   ├── matrix_sdk_baseFFI.h
│   │   ├── matrix_sdk_cryptoFFI.h
│   │   ├── matrix_sdk_ffiFFI.h
│   │   ├── matrix_sdk_uiFFI.h
│   │   └── module.modulemap
│   └── libmatrix_sdk_ffi.a
├── ios-arm64_x86_64-simulator
│   ├── Headers
│   │   ├── matrix_sdkFFI.h
│   │   ├── matrix_sdk_baseFFI.h
│   │   ├── matrix_sdk_cryptoFFI.h
│   │   ├── matrix_sdk_ffiFFI.h
│   │   ├── matrix_sdk_uiFFI.h
│   │   └── module.modulemap
│   └── libmatrix_sdk_ffi_iossimulator.a
└── macos-arm64_x86_64
    ├── Headers
    │   ├── matrix_sdkFFI.h
    │   ├── matrix_sdk_baseFFI.h
    │   ├── matrix_sdk_cryptoFFI.h
    │   ├── matrix_sdk_ffiFFI.h
    │   ├── matrix_sdk_uiFFI.h
    │   └── module.modulemap
    └── libmatrix_sdk_ffi_macos.a

Inside the turbo module's podspec, I'm vendoring the XCFramework using

s.vendored_frameworks = "MatrixSDKFFI.xcframework"

Upon trying to pod install in an example app that consumes the turbo module, I'm hitting the following error

...
Generating Pods project
[!] Unable to install vendored xcframework `MatrixSDKFFI` for Pod `react-native-matrix-sdk` because it contains static libraries
with differing binary names: libmatrix_sdk_ffi, libmatrix_sdk_ffi_iossimulator, and libmatrix_sdk_ffi_macos.

To work around this, I renamed the .a files and used xcodebuild to assemble a new XCFramework.

xcodebuild -create-xcframework \
  -library MatrixSDKFFI.xcframework/ios-arm64/libmatrix_sdk_ffi.a \
  -headers MatrixSDKFFI.xcframework/ios-arm64/Headers \
  -library MatrixSDKFFI.xcframework/ios-arm64_x86_64-simulator/libmatrix_sdk_ffi.a \
  -headers MatrixSDKFFI.xcframework/ios-arm64_x86_64-simulator/Headers \
  -library MatrixSDKFFI.xcframework/macos-arm64_x86_64/libmatrix_sdk_ffi.a \
  -headers MatrixSDKFFI.xcframework/macos-arm64_x86_64/Headers \
  -output MatrixSDKFFI-new.xcframework

This lets me pod install in the example app. However, build the app fails.

❌  /Users/jm/Library/Developer/Xcode/DerivedData/MatrixSdkExample-ehaqmpwzfrmmtdcmzfodmqxnxfvn/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/react-native-matrix-sdk/Headers/module.modulemap:3:8: redefinition of module 'matrix_sdkFFI'

module matrix_sdkFFI {
            ^~~~~



❌  /Users/jm/Library/Developer/Xcode/DerivedData/MatrixSdkExample-ehaqmpwzfrmmtdcmzfodmqxnxfvn/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/react-native-matrix-sdk/Headers/module.modulemap:10:8: redefinition of module 'matrix_sdk_cryptoFFI'

module matrix_sdk_cryptoFFI {
       ^



❌  /Users/jm/Library/Developer/Xcode/DerivedData/MatrixSdkExample-ehaqmpwzfrmmtdcmzfodmqxnxfvn/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/react-native-matrix-sdk/Headers/module.modulemap:17:8: redefinition of module 'matrix_sdk_ffiFFI'

module matrix_sdk_ffiFFI {
       ^



❌  /Users/jm/Library/Developer/Xcode/DerivedData/MatrixSdkExample-ehaqmpwzfrmmtdcmzfodmqxnxfvn/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/react-native-matrix-sdk/Headers/module.modulemap:24:8: redefinition of module 'matrix_sdk_baseFFI'

module matrix_sdk_baseFFI {
       ^



❌  /Users/jm/Library/Developer/Xcode/DerivedData/MatrixSdkExample-ehaqmpwzfrmmtdcmzfodmqxnxfvn/Build/Products/Debug-iphonesimulator/XCFrameworkIntermediates/react-native-matrix-sdk/Headers/module.modulemap:31:8: redefinition of module 'matrix_sdk_uiFFI'

module matrix_sdk_uiFFI {
       ^

I suspect what happens here is that two of the static libraries are loaded and then conflict because obviously the have the same module map. I'm not sure why more than one library is loaded to begin with though because they are separated by architecture.

Does anyone know how to properly vendor a framework with static libraries for different architectures in a React Native turbo module?

Update: It looks like it's actually only pulling one slice from the XCFramework as I've found this in the logs.

Selected xcframework slice ios-arm64_x86_64-simulator

However, that library appears to be a fat one

$ lipo -info MatrixSDKFFI.xcframework/ios-arm64_x86_64-simulator/libmatrix_sdk_ffi.a
Architectures in the fat file: MatrixSDKFFI.xcframework/ios-arm64_x86_64-simulator/libmatrix_sdk_ffi.a are: x86_64 arm64

If I exclude the x86_64 architecture in the example app's build settings, the build is successful. This will break the build for people still using Intel Macs though. So it feels like a band aid.

enter image description here

Upvotes: 0

Views: 78

Answers (0)

Related Questions