Static library links on device but fails on iOS Simulator

I’m working on an iOS workspace with:

  • a static library project: M800SDK
  • a test app project: TestAppObj

I was able to build M800SDK for iOS Simulator on Apple Silicon as a simulator static library, and I also verified the architectures in the produced .a file.

However, when I link the app target against that simulator build and try to build TestAppObj for iOS Simulator, I get the following linker errors:

Undefined symbols for architecture arm64: _OBJC_CLASS_$_TokenMngr
clang++: error: linker command failed with exit code 1

Additional context:

  • The library links and works correctly when building the app for a physical iPhone. And the public header TokenMngr.h is found correctly by the app target.
  • The app target is compiled as Objective-C++ where needed.
  • The library is linked in the app target under “Link Binary With Libraries”.

Could you help me understand: Is it possible to run on iOS Simulator ? the recommended way to package and consume this library for iOS Simulator on Apple Silicon?

Also I am aware i can also build the library for :

Any iOS Simulator Device (arm64, x86_64)

And specify that on Build Phases in Link : Link Binary With Libraries adding the .a Before i do that i ensure the .a is arm64, x86_64 using the command :

lipo -info libM800SDK.a

end it returns :

Architectures in the fat file: libM800SDK.a are: x86_64 arm64

However, even after confirming those architectures and linking the library to the app target, the app still does not link correctly for iOS Simulator.

In some cases, Xcode reports errors suggesting that the build is targeting iOS Simulator, but that one of the linked binaries was built for iPhoneOS instead.

This is where I am confused: I understand that lipo -info only shows the CPU architectures present in the library, but not whether a given arm64 slice was built for iPhoneOS or for iOS Simulator

Answered by DTS Engineer in 880190022

It sounds like your static library isn't built as an XCFramework that then contains your static library. In essence, your library needs to be built twice, once for iOS devices and a second time for iOS simulators, with both copies and the header files then packed inside of the XCFramework so Xcode then handles all of the details from there. The documentation covers all of the details you need.

— Ed Ford,  DTS Engineer

Accepted Answer

It sounds like your static library isn't built as an XCFramework that then contains your static library. In essence, your library needs to be built twice, once for iOS devices and a second time for iOS simulators, with both copies and the header files then packed inside of the XCFramework so Xcode then handles all of the details from there. The documentation covers all of the details you need.

— Ed Ford,  DTS Engineer

So, if I understand correctly, I should package my library as an XCFramework instead of sharing the library project itself, and then add that XCFramework to the app project that needs to use it.

Also, if I follow the XCFramework approach, what exactly should I deliver to the client so they can integrate and use the library without needing access to my original library project?

Static library links on device but fails on iOS Simulator
 
 
Q