如何确定在Mac OS X上静态库(.a)的目标架构?

161

我想确认给定的iPhone静态库是为ARM还是Intel构建的。

这只是出于好奇而已。是否有某种Mac OS X或BSD特定的工具来完成此操作?这个帖子给出了一个在Linux中的示例。

6个回答

286
另一个选择是lipo;它的输出比otool更简洁易读。
一个例子:
% lipo -info /usr/lib/libiodbc.a 
Architectures in the fat file: /usr/lib/libiodbc.a are: x86_64 i386 ppc
% lipo -info libnonfatarchive.a
input file libnonfatarchive.a is not a fat file
Non-fat file: libnonfatarchive.a is architecture: i386
%

刚刚用一个旧的PJSIP .a文件验证了一下,是armv7的。谢谢。 - Alex Zavatone
我如何检查目标体系结构(.a文件)的最低iOS版本? - DevSemenuk

73

file 命令可能会告诉你。 otool 也应该能够。但我建议先试试 file 命令。

logan:/Users/logan% file d2
d2: Mach-O executable ppc

使用存档的示例:

logan:/Users/logan% file /usr/lib/libMallocDebug.a
/usr/lib/libMallocDebug.a: Mach-O universal binary with 2 architectures
/usr/lib/libMallocDebug.a (for architecture i386):      current ar archive random library
/usr/lib/libMallocDebug.a (for architecture ppc):       current ar archive

37
根据我的经验,“file” 经常会失败。 - Stefan Schmidt
4
下面有关于脂肪吸除的回答,一直都有效。 - Maciej Swic
我注意到如果 .a 没有经过 ranlib 处理,file 命令有时会报告较少的信息。 - Paul Du Bois
4
现在在2015年,您应该使用lipo。请参见下面的答案。 - derFunk
2
很不幸,这在多个操作系统版本上都没有起作用。 - rmcclellan

64

如前所述,file 命令并不总是有效。使用 otool -hv -arch all 可以得到最接近于可靠的答案 - 它会给出库中每个目标文件的体系结构信息。

示例:

% otool -hv /sw/lib/libfftw3.a
Archive : /sw/lib/libfftw3.a
/sw/lib/libfftw3.a(align.o):
Mach 头
      魔数    CPU 类型  子类型     标志    文件类型 ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      OBJECT     3        336 SUBSECTIONS_VIA_SYMBOLS
/sw/lib/libfftw3.a(alloc.o):
Mach 头
      魔数    CPU 类型  子类型     标志    文件类型 ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      OBJECT     3        416 SUBSECTIONS_VIA_SYMBOLS
...

仅补充一下,我更喜欢使用otool而不是file或lipo。我尝试了file、lipo和otool来处理一个iOS的fat库,只有otool能够显示其中包含了i386(iPhone模拟器)、armv6、armv7和armv7s(iPhone操作系统)的文件。 - Roberto
1
注意:如果您想检查您的库是否是fat格式,请使用“otool -arch all”命令;否则,它将仅报告每个.o文件的一个架构。要快速了解您的.a中的架构,请使用“otool -f”命令。 - Paul Du Bois

7
如果有人想知道如何判断一个库(或其中的目标文件)是否适用于Mac Catalyst,请使用otool -l命令来转储加载命令。查找任何对象的LC_BUILD_VERSION部分。Mac Catalyst的标识为platform 6而不是platform 1

6
这个 Bash 脚本将帮助你以编程方式获取架构列表并存储到一个变量中。 list_archs.sh:
#! /bin/bash
lipo -info $1 | sed -En -e 's/^(Non-|Architectures in the )fat file: .+( is architecture| are): (.*)$/\3/p'

使用示例:

./list_archs.sh /usr/lib/libc.dylib
x86_64 i386

4

作为替代方案,我发现objdump可以很好地工作。例如,在我的环境中,我使用vxWorks构建库存档,并需要将其链接到其他项目中。要测试存档是否是正确的架构,我可以执行以下操作(bash语法):

if [ "$(objdumpsparc -a ${ARCHIVE_FILE} 2>&1 | ggrep -cvP 'elf32-sparc-vxworks')" -ne "0" ]; then
  echo "Cannot build with ${ARCHIVE_FILE}, it contains one or more non-sparc components"
fi;

这个例子并不完全正确,因为有一些行并不会显示elf32-sparc-vxworks,但是很容易就能适应它。

这样做的一个好处是,在大多数*nix操作系统上都安装了objdump或类似命名的变体,而其他响应中建议的工具则没有。

编辑 我突然想到OP在询问OSX。非常抱歉。


要使用 objdump,您可以通过MacPorts安装GNU Binutils。只需执行 port search binutils 就可以查看所有可用的架构。本地开发工具都有前缀以避免冲突(例如,gobjdump 代替 objdump)。您可能希望为方便起见创建别名。 - Stefan Schmidt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接