使用Bitcode重新编译更改LC_ID_DYLIB

时间:2016-12-13 10:47:36

标签: ios frameworks dylib mach-o otool

我从启用了bitcode的iOS源代码构建动态框架(使用cmakexcodebuild)。我使用lipoinstall_name_tool创建一个胖二进制文件并更新LC_ID_DYLIB,以便正确加载二进制文件。归档应用程序时,框架已正确签名并与应用程序打包在一起。这是file

的输出
MyFramework: Mach-O universal binary with 3 architectures: [arm_v7: Mach-O dynamically linked shared library arm_v7] [arm_v7s] [arm64]
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

查看otool -l的{​​{1}}输出显示了这一点:

LC_ID_DYLIB

一切似乎都是正确的。如果我将此存档上传到App Store,则会正确上传和处理。从App Store运行后,由于加载动态框架,它在启动后立即崩溃。众所周知,应用程序会从App Store上的Bitcode重新编译,因此我通过导出为Ad-Hoc并从Bitcode" Rebuild Bitcode"根据{{​​3}}中的建议启用了该选项。检查.ipa(在启动后也崩溃了)和相关框架,这是Load command 4 cmd LC_ID_DYLIB cmdsize 64 name @rpath/MyFramework.framework/MyFramework (offset 24) time stamp 1 Thu Jan 1 01:00:01 1970 current version 1.0.0 compatibility version 1.0.0 的输出:

otool -l

显然,这个库的Load command 3 cmd LC_ID_DYLIB cmdsize 128 name /Users/legoless/Downloads/ios/build/build-iphoneos/lib/Release/MyFramework_ios.framework/MyFramework_ios (offset 24) time stamp 1 Thu Jan 1 01:00:01 1970 current version 1.0.0 compatibility version 1.0.0 是不正确的,这是构建框架最初构建的位置的绝对路径,然后再创建胖二进制文件。这在从Bitcode重建步骤中被替换,但我不知道为什么甚至将此路径存储在现有的 Mach-O 文件中。我使用了LC_ID_DYLIBotool工具来尝试在Mach-O二进制文件中找到引用,没有运气。

实际上,另一个框架依赖于此框架,这是目标框架的加载命令:

objdump

再次使用Bitcode重建之后,引用也会在此处更改:

Load command 14
          cmd LC_LOAD_DYLIB
      cmdsize 64
         name @rpath/MyFramework.framework/MyFramework (offset 24)
   time stamp 2 Thu Jan  1 01:00:02 1970
      current version 1.0.0
compatibility version 1.0.0

这仅适用于相关框架,但不适用于其他框架,其中Load command 13 cmd LC_LOAD_DYLIB cmdsize 128 name /Users/legoless/Downloads/ios/build/build-iphoneos/lib/Release/MyFramework_ios.framework/MyFramework_ios (offset 24) time stamp 2 Thu Jan 1 01:00:02 1970 current version 1.0.0 compatibility version 1.0.0 保持不变。

我的问题仍然存在:

存储此绝对路径引用的位置?以及如何删除它,所以从Bitcode重建不再影响它了?

谢谢!

2 个答案:

答案 0 :(得分:1)

对此问题进行详细调查,结果显示在Mach-O文件中包含bitcode的 .xar 存档存储了相当多的信息,包括链接器标志。此信息存储在归档的目录中,用于在bitcode重新编译时重新编译/重新链接库。

就我而言,我正在使用 cmake 构建框架,该框架将此信息添加到链接器标记中。配置INSTALL_NAME_DIRBUILD_WITH_INSTALL_RPATH并使用@rpath有效地解决了问题,并且不再需要install_name_tool

答案 1 :(得分:0)

我遇到了完全相同的问题。接受的答案让我接近,但设置INSTALL_NAME_DIR参数本身并没有修复它,因为它不允许你设置传递给链接器的完整值作为install_name(只有目录,正如你所料)。

相反,我设置XCODE_ATTRIBUTE_LD_DYLIB_INSTALL_NAME,一次性覆盖完整的值。显然这只适用于CMake中的XCode生成器,但这对我想要的很好。总而言之,我的此框架的C​​Make文件现在包含:

set_target_properties(${LIBRARY_NAME} PROPERTIES XCODE_ATTRIBUTE_LD_DYLIB_INSTALL_NAME "@rpath/${LIBRARY_NAME}.framework/${LIBRARY_NAME}")
set_target_properties(${LIBRARY_NAME} PROPERTIES BUILD_WITH_INSTALL_RPATH 1)