链接后更改dylib名称

Change dylib name after linkage

在 linkage 之后,dylib 的名称似乎被嵌入到它的二进制代码中(类似于 Linux 下的 SONAME 标签)。是否可以追溯更改此字段?

详细说明

我有一个 dylib,我想将其打包为一个 iOS 框架。构建一个使用 XCode 下的框架的项目工作正常。但是,如果我尝试将它安装到设备上,则会收到以下错误(来自设备日志)

codeSigningInfoByValidatingResources:performingOnlineAuthorization:ignoringCachedSigningInfo:checkingTrustCacheIfApplicable:error:]: 817: Code signing identifier DYLIB_NAME does not match bundle identifier BUNDLE_IDENTIFIER

我发现如果我在 link 时更改 dylib 名称以匹配包标识符,错误就会消失,即调用

clang++ -shared -Wl,-dylib {OBJECT_FILES} -o BUNDLE_IDENTIFIER

简单地重命名dylib并不能解决问题。事实上,如果我在十六进制编辑器中打开 dylib,我可以看到 BUNDLE_IDENTIFIER 嵌入到二进制文件中。但是,我找不到 如果我使用例如相应的标签otool(虽然我不是专家,所以也许我是 只是使用了错误的参数)。 做构建系统限制,我想创建一个不同名称的dylib,稍后将其更改为bundle identifier。

具体问题

  1. 我可以追溯更改名称吗?
  2. dylib 名称和代码签名标识符之间有什么联系?
  3. Apple 如何解析 dylib 中的名称?

您的问题可能与此标识符有关,它存储在代码签名 blob 中(使用 CFNetwork.framework 进行演示):

$ codesign -dvv CFNetwork 2>&1 | egrep ^Identifier
Identifier=com.apple.CFNetwork

您可以使用 codesign -i 标志更改它。来自手册页:

 -i, --identifier identifier
         During signing, explicitly specify the unique identifier string that is embedded in
         code signatures. If this option is omitted, the identifier is derived from either
         the Info.plist (if present), or the filename of the executable being signed, possi-
         bly modified by the --prefix option.  It is a very bad idea to sign different pro-
         grams with the same identifier.

请注意,这与存储在加载命令中的 "library identification name" 是分开的(即 Mach-O header):

$ otool -l CFNetwork | fgrep -B1 -A5 LC_ID_DYLIB
Load command 5
          cmd LC_ID_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/CFNetwork.framework/CFNetwork (offset 24)
   time stamp 1 Thu Jan  1 01:00:01 1970
      current version 0.0.0
compatibility version 1.0.0

您可以使用 install_name_tool -id 更改那个(尽管您必须在签名之前这样做,否则会使签名无效)。再次来自手册页:

   -id name
          Changes the shared library identification name of a  dynamic  shared  library  to
          name.  If the Mach-O binary is not a dynamic shared library and the -id option is
          specified it is ignored.