34

From Xcode 7 it became one of the common problem that third party frameworks should support Bitcode. We can also disable the BITCODE by setting ENABLE_BITCODE to NO in Build settings. But i do not want to turn it off, instead i want to convert all my frameworks to BITCODE compatible.

So how to check if a framework is BITCODE compatible apart from compiling the framework in Xcode. Sometimes Xcode give error for BITCODE compatibility for one framework leaving the others even though they don't have BITCODE support.

Is there any tool/command line check?

Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
ipraba
  • 16,485
  • 4
  • 59
  • 58

6 Answers6

58

From this Apple Developers Forum discussion, user dshirley and bwilson suggest using command line tools otool and grep to check if bitcode sections exist.

$ otool -l libName.o | grep __LLVM

or

$ otool -l MyFramework.framework/Versions/A/MyFramework | grep __LLVM

Running the above command, if the library contains bitcode you will see segname __LLVM output.

iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
Michael M. Myers
  • 2,495
  • 26
  • 22
  • 2
    Thanks for the answer Michael. So this tool works on a .o or .a file. How to check for a .framework file? – ipraba Oct 01 '15 at 05:33
  • 3
    The .framework is just a nice way of packaging resources, public headers, and a library all together. The library is in there, you will want to run the command on that. So for example, depending on the directory structure: `$ otool -l MyFramework.framework/Versions/A/MyFramework | grep __LLVM`, where `MyFramework` is the library (without the file extension). For more information on framework directory structures, check out https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html – Michael M. Myers Oct 01 '15 at 14:31
  • Thanks for the info Michael – ipraba Oct 01 '15 at 14:58
  • Use this to check all .a files in your tree (note that the last semicolon MUST be part of the command. Also don't forget to make test_bitcode.sh executable): find . -name '*a' -type f -exec ./test_bitcode.sh {} \; The content of test_bitcode.sh is: echo "***** TESTING $1" ; otool -l $1 | grep __LLVM | head -n1 – PerfectGamesOnline.com Oct 20 '15 at 08:55
  • I cannot get this method to work and made a new post about it (http://stackoverflow.com/questions/35014582/method-to-determine-whether-a-binary-contains-bitcode-no-longer-seems-to-work) If anyone can help please let me know. – Locksleyu Jan 26 '16 at 13:09
  • 1
    The problem with this answer is that if you build with "-fembed-bitcode-marker" you will also see segname __LLVM in your output, but you do not actually have bitcode -- just space in the library for it. See this answer -- http://stackoverflow.com/questions/34959767/whats-the-difference-between-fembed-bitcode-and-bitcode-generation-mode – Joe Steele May 11 '17 at 16:46
  • Why my framework does not contain `Versions` directory? Isn't it a must for a framewoek? – Desmond DAI Sep 22 '17 at 03:15
  • 3
    This only works for me when checking a specific architecture. e.g. `otool -arch arm64 -l MyFramework.framework/Versions/A/MyFramework | grep LLVM` – Adam Johns Sep 11 '18 at 16:52
  • By running this command, I got this one "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/objdump: 'teliver.o': No such file or directory" – Vinoth Vino Apr 23 '19 at 11:02
17

The accepted answer suggests you shall do grep __LLVM but I'd rather do this

otool -l libName.o | grep __bitcode

as there are different __LLVM segments and not all of these indicate the presence of Bitcode. Here's an example:

Section
  sectname __bitcode
   segname __LLVM
      addr 0x00000000000007d0
      size 0x0000000000000f10
    offset 3360
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __cmdline
   segname __LLVM
      addr 0x00000000000016e0
      size 0x0000000000000069
    offset 7216
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0

The presence of the __cmdline Section does not indicate that Bitcode is present, yet it would also be found when just searching for __LLVM.

Mecki
  • 125,244
  • 33
  • 244
  • 253
  • 2
    This doesn't work. I have a Swift framework and searching for "__LLVM" with bit code enabled works but this does not. – David S. Feb 17 '16 at 18:26
  • 5
    In https://forums.developer.apple.com/message/7038 user bwilson (Apple Staff) mentions searching for __bitcode is not reliable and recommends __LLVM – Michael M. Myers Jul 12 '16 at 14:54
8

I have observed that __bitcode section is only present for static Libs and not for dynamic libs. So, one solution is the below command.

otool -l libDeviceManager.a | grep __LLVM 

Also, sometimes with fat binaries otool may not give __LLVM segments even though they are present. You can use the following command for those cases

otool -arch armv7 -l libDeviceManager.framework/libDeviceManager | grep __LLVM
SnehaK
  • 141
  • 1
  • 5
1

you can try these commands:

otool -arch armv7 -l libDeviceManager.a | grep bit code

and

otool -arch arm64 -l libDeviceManager.a | grep bitcode
ddb
  • 2,423
  • 7
  • 28
  • 38
naresh d
  • 183
  • 1
  • 3
  • 8
1

Set the flag in the Targets:

enter image description here

Bitcode enabled

otool -arch arm64 -l myFramework | grep __LLVM
  segname __LLVM
   segname __LLVM

I ( wrongly ) expected to read the same output against a local iOS app build. That was not the case. The same command produced nothing, despite have ENABLE_BITCODE YES. Only when you selected Archive did the bitcode process start.

This answer helped me:

What's the difference between `-fembed-bitcode` and BITCODE_GENERATION_MODE?

rustyMagnet
  • 3,479
  • 1
  • 31
  • 41
0

One more approach

otool -v -s __LLVM __bundle <binary_path>
//e.g.
otool -v -s __LLVM __bundle "/Users/alex/MyModule.framework/MyModule" 

or to find __bundle section in __LLVM segment

otool -l <binary_path> | grep __bundle 

[Bitcode]

yoAlex5
  • 29,217
  • 8
  • 193
  • 205