将 iOS .dylib 合并到带有 lipo 的框架中会中断位码重新编译

Merging iOS .dylib into framework with lipo breaks bitcode recompilation

我正在尝试从 .dylib 文件手动构建动态 iOS 框架。二进制文件是用 cmake 和 xcodebuild 创建的,并产生两个 .dylib 文件,一个包含 armv7armv7sarm64,另一个包含 x86_64i386架构。库是用 -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 目录。