如何检查一个静态库是否包含位码?

45

我有一个由其他公司编译的静态库。我想知道它是否包含位码(bitcode),哪个命令可以在终端检测到它?

6个回答

68

正如其他答案中已经写过的一样,

otool -l yourlib.a | grep __LLVM

走这条路是正确的。

一名苹果工程师说,使用这种方式是正确的。

otool -l yourlib.a | grep bitcode

搜索“bitcode”段不是检测文件是否包含嵌入式bitcode的可靠方法。如果要这样做,请搜索“__LLVM”段。您应该知道,使用 -fembed-bitcode-marker 选项进行正常构建将生成最小大小的嵌入式bitcode部分而没有任何真实内容。这是为了测试构建中与bitcode相关的方面而不减慢构建过程。实际的bitcode内容是在进行存档构建时包括的。

另请参见xCocoa的评论。

看起来,如果包括了iPhone模拟器的架构(x86_64或i386)的代码,则otool不会报告bitcode。

您可以使用以下命令列出库的架构:

lipo -info yourlib.a

然后你可以分别检查每个架构的位代码,例如:

然后您可以分别检查每个体系结构的位代码,例如:

otool -arch armv7 -l yourlib.a  | grep bitcode
otool -arch arm64 -l yourlib.a  | grep bitcode

以下内容是否正确:如果静态库未使用ENABLE_BITCODE=NO构建,则无法从启用了ENABLE_BITCODE=YES的目标中使用它?反之亦然,是否正确? - Yevhen Dubinin
2
@EugeneDubinin Bitcode只是一些额外的信息,因此拥有它除了稍微增加一点大小之外并没有什么害处。然而,在二进制文件中缺少bitcode意味着您无法将其链接到需要启用bitcode的目标上。 - Mazyod
2
请注意,如果您使用 -fembed-bitcode-marker 编译而不是 -fembed-bitcode(请检查编译器输出),则这些命令可能会出现误报,因为位码“标记”存在,但实际的位码不存在。此答案提供了更多相关信息。 - William Denniss
3
在@WilliamDenniss的答案上进行跟进,您可以通过在otool结果中用grep查找bitcode,然后查看该字段4行后的大小来检查误报(您可以使用-A 4参数查看grep匹配后的下4行)。如果大小为1,则意味着未设置-fembed-bitcode且库不包含bitcode。 - Deemoe

3

建议对LLVM符号进行测试:

otool -l yourlib.a | grep LLVM

你应该会得到一些带有“__LLVM”的行。


1
我尝试了一下,但没有发现任何东西,你的lib.a包含位码,我很确定。 - xCocoa
你已经为存档构建了吗? - SeikoTheWiz
请问您能指出您主张的来源吗?为什么我要用 LLVM 进行 grep? - Paul
关于搜索“__LLVM”,请参阅此答案 - Quintin Willison

2

声明:我是LibEBC的作者。

你可以使用ebcutil来查看Mach-O二进制文件或库中是否存在位码,并且甚至可以使用它来提取嵌入的位码。

https://github.com/JDevlieghere/LibEBC


我尝试使用这个库,但在最新的macOS上,它似乎根本无法编译。 - jarora
请随意在GitHub上开启一个问题。 - Jonas

2

如果您想检查静态库中特定文件 (yourFile.o) 是否启用了位码(bitcode),您可以提取 'staticLibrary.a' 并使用相同的 otool 命令。但是,在某些情况下,macOS 不允许使用默认的提取工具提取 staticLibrary.a,大多数第三方工具也无法正常工作。

您可以按照以下步骤检查特定的 .o 文件:

  1. Get the info of the architecture

    lipo -info yourStaticLibrary.a
    

例如输出:armv7 arm64

  1. Extract yourStaticLibrary.a for any or both of the above architecture

    lipo yourStaticLibrary.a -thin armv7 -output yourStaticLibraryarmv7.a
    

指定你想要提取到的输出路径。

  1. You get the 'yourStaticLibraryarmv7.a' which then can be easily extracted with the default mac unarchiver

  2. On extracting, you then get a folder 'yourStaticLibraryarmv7' containing all the .o files

  3. otool -l yourFile.o | grep bitcode or with the specific architecture

    otool -arch armv7 -l yourFile.o  | grep bitcode
    
如果文件启用了位码,命令行中将出现“sectname __bitcode”。

默认的Mac解压软件让我很烦恼,所以你可以尝试使用这个命令 ar -t yourStaticLibraryarmv7.a 来查看.o文件列表,以及 ar -xv yourStaticLibraryarmv7.a yourFile.o 来提取你的文件。 - yano
@yano,对我不起作用。执行ar -t ***.a时我得到了ar:***.a: Inappropriate file type or format的错误提示。我按照答案中所述的方法删除了armv7切片。 - marchinram
  1. lipo -info lib.a
  2. 检查架构,选择您的架构
  3. lipo lib.a -thin arm64 -output lib_arm64.a
  4. ar -tv lib_arm64.a // 列出文件
  5. ar -xv lib_arm64.a yourfile.o // 提取文件
  6. otool -arch armm64 -l yourfile.o | grep bitcode
如果文件启用了位码,则在命令行中会显示 'sectname __bitcode'
- Amit

0
  1. lipo -info lib.a // 您的静态库
  2. 检查体系结构,选择您的体系结构
  3. lipo lib.a -thin arm64 -output lib_arm64.a // 提取您的体系结构
  4. ar -tv lib_arm64.a // 列出文件
  5. ar -xv lib_arm64.a yourfile.o // 文件提取
  6. otool -arch armm64 -l yourfile.o | grep bitcode

如果文件启用了位码,则会显示 'sectname __bitcode'


-1

2
我的开发环境是Xcode7和EI Capitan 10.11.1,我使用了命令,但是找不到“__bitcode”部分。 - xCocoa

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