Reputation: 11112
I'm trying to build a dynamic iOS framework manually from .dylib
files. Binaries are created with cmake and xcodebuild and produce two .dylib
files, one containing armv7
, armv7s
and arm64
and the other x86_64
and i386
architectures. Libraries are compiled with -fembed-bitcode parameter
and everything succeeds.
.dylib files are then merged with next command:
lipo -create lib_arm.dylib lib_i386.dylib -output MyFramework
Framework is then created by copying the output from lipo command to:
MyFramework.framework/MyFramework
Headers and Info.plist
are manually generated and added to the framework.
This framework is then installed via CocoaPods into the application as a vendored_framework
. It is known that CocoaPods will strip the i386/x86_64 libraries from any fat binaries, for App Store distribution.
Application builds, runs, archives and uploads successfully to App Store.
However, since Bitcode is enabled, App Store will process the .ipa, and recompile with bitcode, this is where it fails and I receive an email from App Store, that it failed processing. Following instructions, I can reproduce the error locally with Exporting for Ad-Hoc Distribution and recompiling for bitcode. The error I receive is this:
ipatool failed with an exception: #<Errno::ENOENT: No such file or directory - /lib_arm.dylib>\n
So apparently during the recompilation, there is still a reference or somewhere to lib_arm.dylib
, even though it was merged into a fat dylib Mach-O universal binary (file
output of the merged dylib binary below):
>> file MyFramework
MyFramework: Mach-O universal binary with 5 architectures: [x86_64: Mach-O 64-bit dynamically linked shared library x86_64] [i386] [arm_v7] [arm_v7s] [arm64]
MyFramework (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
MyFramework (for architecture i386): Mach-O dynamically linked shared library i386
MyFramework (for architecture armv7): Mach-O dynamically linked shared library arm_v7
MyFramework (for architecture armv7s): Mach-O dynamically linked shared library arm_v7s
MyFramework (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
This is pretty much where my compiler/linker knowledge gets out of scope. So my question is:
Where am I going wrong with this? Maybe bitcode should be compiled differently? Or maybe I am using lipo
in wrong way?
Thank you!
Upvotes: 1
Views: 2000
Reputation: 11112
After inspecting load commands of the created fat binary with otool -l
command, I realized that using lipo
itself does not change the LC_ID_DYLIB
in the binary and it will reuse one from the first provided library. Using install_name_tool
to change the id to correct one of the framework (including @rpath
for iOS dynamic frameworks) fixes the error.
install_name_tool -id @rpath/MyFramework.framework/MyFramework MyFramework
Make sure the entire path to binary is included, together with .framework
directory.
Upvotes: 3