Ios 使用位码更改LC\U ID\U动态库重新编译

Ios 使用位码更改LC\U ID\U动态库重新编译,ios,frameworks,dylib,mach-o,otool,Ios,Frameworks,Dylib,Mach O,Otool,我正在从源代码为iOS构建一个启用位代码的动态框架(使用cmake和xcodebuild)。我使用lipo和install\u name\u tool制作fat二进制文件并更新LC\u ID\u DYLIB,以便正确加载二进制文件。当我归档应用程序时,框架与应用程序一起正确签名和打包。这是文件的输出: MyFramework: Mach-O universal binary with 3 architectures: [arm_v7: Mach-O dynamically linked shar

我正在从源代码为iOS构建一个启用位代码的动态框架(使用
cmake
xcodebuild
)。我使用
lipo
install\u name\u tool
制作fat二进制文件并更新
LC\u ID\u DYLIB
,以便正确加载二进制文件。当我归档应用程序时,框架与应用程序一起正确签名和打包。这是
文件的输出:

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
查看
LC\u ID\u DYLIB的
otool-l
输出显示:

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
这一切似乎都是正确的。如果我将此存档上载到App Store,它将被正确上载和处理。从App Store运行后,由于加载动态框架,它在启动后立即崩溃。众所周知,应用程序是从AppStore上的位代码重新编译的,所以我模拟了这种情况,将其作为临时导出,并按照中的建议启用“从位代码重建”选项。检查.ipa(启动后也会崩溃)和相关框架,这是
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
显然,这个库的
LC\u ID\u DYLIB
是不正确的,这是在生成胖二进制文件之前,框架最初构建位置的绝对路径。这在从位代码重建的步骤中被替换,但我不知道为什么或者甚至不知道该路径存储在现有的马赫-O文件中的什么位置。我使用了
otool
objdump
工具,试图在Mach-O二进制文件中找到引用,但运气不好

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

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
这只会发生在讨论中的框架上,而不会发生在其他框架上,
@rpath
保持原样

我的问题仍然是:

此绝对路径引用存储在哪里?以及如何删除它,以便从位代码重建不再影响它?


谢谢大家!

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


在我的例子中,我使用cmake构建框架,它将这些信息添加到链接器标志中。配置
INSTALL\u NAME\u DIR
BUILD\u与\u INSTALL\u RPATH
并使用@RPATH有效地解决了这个问题,不再需要
INSTALL\u NAME\u工具了。

我遇到了完全相同的问题。接受的答案让我很接近,但是设置
INSTALL\u NAME\u DIR
参数本身并不能解决这个问题,因为它不允许您将传递给链接器的完整值设置为INSTALL\u NAME(正如您所期望的,仅是目录)

相反,我设置了
XCODE\u属性\u LD\u DYLIB\u INSTALL\u NAME
,它一次就覆盖了完整的值。显然,这只适用于CMake中的XCode生成器,但这符合我的要求。总之,我的这个框架的CMake文件现在包含:

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)