假设我有一个针对多种架构(例如armv7、armv7s、i386、x86_64、arm64)构建的.a fat 库。库是为 iOS 构建的(其中包含 cmd LC_VERSION_MIN_IPHONEOS 和版本 6.0)。例如,当我运行 $ otool -lv 时,我会得到带有此类加载命令的部分:
Load command 1
cmd LC_VERSION_MIN_IPHONEOS
cmdsize 16
version 6.0
sdk n/a
我想将其替换为:
Load command 1
cmd LC_VERSION_MIN_TVOS
cmdsize 16
version 9.0
sdk n/a
有人知道我该怎么做或者可以指出一些有用的资源吗? 我还可以在 tvOS 上链接修改后的库吗?
如果您有权访问源代码,最好的解决方案显然是为 tvOS 重新编译它。
如果您无权访问源代码,快速而肮脏的解决方案是在十六进制编辑器中打开库,搜索这些字节(每个目标文件一次):
25000000 10000000 00000600 00000000
并将它们替换为:
2f000000 10000000 00000900 00000000
更稳定的解决方案是编写一个小型 C 程序来解析和编辑目标文件的标头。在安装了 Xcode 的 Mac 上,您需要的所有信息(以及有用的注释)都可以从
<mach-o/loader.h>
头文件中获得。对于其他人,该文件也可以从 XNU 源代码获得。
迭代所有加载命令的基本思想如下所示,给定一个包含 Mach-O 的 char 缓冲区
file
:
struct mach_header_64 *hdr = (struct mach_header_64*)file;
for(struct load_command *cmd = (struct load_command*)(hdr + 1),
*end = (struct load_command*)((uintptr_t)cmd + hdr->sizeofcmds);
cmd < end;
cmd = (struct load_command*)((uintptr_t)cmd + cmd->cmdsize)
)
{
// ...
}
现在,为了您的目的,您需要迭代,直到找到带有
cmd->cmd == LC_VERSION_MIN_IPHONEOS
的加载命令,并将其替换为 LC_VERSION_MIN_TVOS
。您还需要将该加载命令转换为 struct version_min_command*
,其定义如下:
struct version_min_command {
uint32_t cmd;
uint32_t cmdsize;
uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
};
因此,为了获得
9.0
的版本号,您需要为 version
分配 (9 << 16)
的值。
然后将文件保存回来,就完成了。