将 iOS .dylib 合并到带有 lipo 的框架中会中断位码重新编译
Merging iOS .dylib into framework with lipo breaks bitcode recompilation
我正在尝试从 .dylib
文件手动构建动态 iOS 框架。二进制文件是用 cmake 和 xcodebuild 创建的,并产生两个 .dylib
文件,一个包含 armv7
、armv7s
和 arm64
,另一个包含 x86_64
和 i386
架构。库是用 -fembed-bitcode parameter
编译的,一切都成功了。
.dylib 文件然后与下一个命令合并:
lipo -create lib_arm.dylib lib_i386.dylib -output MyFramework
然后通过将 lipo 命令的输出复制到:
来创建框架
MyFramework.framework/MyFramework
Headers和Info.plist
是手动生成并添加到框架中的。
此框架随后通过 CocoaPods 作为 vendored_framework
安装到应用程序中。众所周知,CocoaPods 将从任何胖二进制文件中删除 i386/x86_64 库,用于 App Store 分发。
应用程序构建、运行、存档并成功上传到 App Store。
但是,由于启用了 Bitcode,App Store 将处理 .ipa,并使用 bitcode 重新编译,这是它失败的地方,我从 App Store 收到一封电子邮件,说它处理失败。按照说明,我可以通过导出 Ad-Hoc 分发和重新编译位码在本地重现错误。我收到的错误是这样的:
ipatool failed with an exception: #<Errno::ENOENT: No such file or directory - /lib_arm.dylib>\n
所以显然在重新编译期间,仍然有对 lib_arm.dylib
的引用或某处,即使它被合并到一个 fat dylib Mach-O 通用二进制文件中(file
的输出合并了下面的 dylib 二进制文件):
>> 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
这几乎是我的 compiler/linker 知识超出范围的地方。
所以我的问题是:
我哪里出错了?也许应该以不同的方式编译位码?或者我使用 lipo
的方式有误?
谢谢!
在使用 otool -l
命令检查创建的 fat 二进制文件的加载命令后,我意识到使用 lipo
本身不会更改二进制文件中的 LC_ID_DYLIB
并且它将重用来自第一个提供的库。使用 install_name_tool
更改 id 以更正框架之一(包括 @rpath
用于 iOS 动态框架)修复错误。
install_name_tool -id @rpath/MyFramework.framework/MyFramework MyFramework
确保包含二进制文件的完整路径以及 .framework
目录。
我正在尝试从 .dylib
文件手动构建动态 iOS 框架。二进制文件是用 cmake 和 xcodebuild 创建的,并产生两个 .dylib
文件,一个包含 armv7
、armv7s
和 arm64
,另一个包含 x86_64
和 i386
架构。库是用 -fembed-bitcode parameter
编译的,一切都成功了。
.dylib 文件然后与下一个命令合并:
lipo -create lib_arm.dylib lib_i386.dylib -output MyFramework
然后通过将 lipo 命令的输出复制到:
来创建框架MyFramework.framework/MyFramework
Headers和Info.plist
是手动生成并添加到框架中的。
此框架随后通过 CocoaPods 作为 vendored_framework
安装到应用程序中。众所周知,CocoaPods 将从任何胖二进制文件中删除 i386/x86_64 库,用于 App Store 分发。
应用程序构建、运行、存档并成功上传到 App Store。
但是,由于启用了 Bitcode,App Store 将处理 .ipa,并使用 bitcode 重新编译,这是它失败的地方,我从 App Store 收到一封电子邮件,说它处理失败。按照说明,我可以通过导出 Ad-Hoc 分发和重新编译位码在本地重现错误。我收到的错误是这样的:
ipatool failed with an exception: #<Errno::ENOENT: No such file or directory - /lib_arm.dylib>\n
所以显然在重新编译期间,仍然有对 lib_arm.dylib
的引用或某处,即使它被合并到一个 fat dylib Mach-O 通用二进制文件中(file
的输出合并了下面的 dylib 二进制文件):
>> 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
这几乎是我的 compiler/linker 知识超出范围的地方。 所以我的问题是:
我哪里出错了?也许应该以不同的方式编译位码?或者我使用 lipo
的方式有误?
谢谢!
在使用 otool -l
命令检查创建的 fat 二进制文件的加载命令后,我意识到使用 lipo
本身不会更改二进制文件中的 LC_ID_DYLIB
并且它将重用来自第一个提供的库。使用 install_name_tool
更改 id 以更正框架之一(包括 @rpath
用于 iOS 动态框架)修复错误。
install_name_tool -id @rpath/MyFramework.framework/MyFramework MyFramework
确保包含二进制文件的完整路径以及 .framework
目录。