How to Xcodebuild a Static Library with Bitcode Enabled

How do I xcodebuild a static library with Bitcode enabled?

Bitcode is a compile-time feature (not a link-time feature) which means that every .o file should contain an extra section called __bitcode when built with bitcode. You can confirm whether your binary is bitcode-compatible by running otool -l (my .o or .a file) | grep __LLVM.

When you build normally, Xcode adds the build flag -fembed-bitcode-marker to any clang invocation. This seems to be some sort of 'this is where bitcode would go, if bitcode was enabled' thing, and doesn't actually enable bitcode.

When you "Build & Archive", this flag is replaced by -fembed-bitcode, which really does build a Bitcode-enabled binary.

There seems to be two ways to make xcodebuild use -fembed-bitcode:

  • Use the 'archive' action, as in xcodebuild -target LookbackSDK archive instead of xcodebuild -target LookbackSDK build. This has the side-effect of putting binaries in your Xcode Organizer instead of the build/ folder, though you can work around that by using -exportArchive -archivePath ./build (thanks @JensAyton)
  • Force usage of the flag by adding Other C Flags with OTHER_CFLAGS="-fembed-bitcode". Your xcodebuild invocation would look something like xcodebuild OTHER_CFLAGS="-fembed-bitcode" -target LookbackSDK build.

The latter is what I chose so that I don't have to change my build system, but it will generate warnings for every file, since now both -fembed-bitcode-marker and -fembed-bitcode are sent to clang. Luckilly the latter wins, generating a Bitcode-enabled library!

Resources

  • Apple DevForums: Bitcode and Assembly?
  • SO: iOS library to BitCode

iOS library to BitCode

When building static libraries you must add the following for bitcode generation:

-fembed-bitcode 

for a dynamic library you need to additionally link with

-fembed-bitcode

Note: This command is only available with Xcode7+

In regards to the accepted answer of using -fembed-bitcode-marker

You should be aware that a normal build with the
-fembed-bitcode-marker option will produce minimal size embedded bitcode sections without any real content. This is done as a way of
testing the bitcode-related aspects of your build without slowing down
the build process. The actual bitcode content is included when you do
an Archive build.

bwilson Apple Staff.
https://forums.developer.apple.com/thread/3971#12225


To be more specific:

  • -fembed-bitcode-marker simply marks where the bitcode would be in the binary after an archive build.
  • -fembed-bitcode actually does the full bitcode generation and embedding, so this is what you need to use for building static libraries.
  • Xcode itself builds with -fembed-bitcode-marker for regular builds (like deploy to simulator)
  • Xcode only builds with -fembed-bitcode for archive builds / production builds (as this is only needed for Apple).

Compiling iOS library with bitcode enabled

AFAIK, when you build app with Xcode it includes Bitcode only when you make archive, the reason - decrease compile time when just want to debug or test the app/library.

To ensure that Xcode emits bitcode at each build you can add -fembed-bitcode flag to Other C flags and Other linker flags:

Sample Image

Sample Image

Also, the easiest way to check if the binary contains bitcode is to use otool and grep:

otool -l binary_name | grep __LLVM

you will see one or more segname __LLVM entries if it does have bitcode or empty output if does not.

xcodebuild 7.3 can't enable bitcode

I ran into a similar issue yesterday. After some investigation, the problem, that appears when running xcodebuild from a "Run Script" build phase in any Xcode target, seems related with the explicit specification of the toolchain to be used, done with the ENV variable TOOLCHAINS.

Therefore, until Apple releases a fixed version of Xcode 7.3, you can try to add the following command at the beginning of your script:

# workaround for bitcode generation problem with Xcode 7.3
unset TOOLCHAINS

This should be harmless, as this env variable is not set by default when you run xcodebuild from the command line, and this workaround works just fine in my case.

ENABLE_BITCODE in static library

Traditionally I'm answering my own question)
Hopefully this will be useful for someone in future.

The problem was actually not in my own third-party framework. I had old version of FacebookSDK linked to my host project, and in fact the linker required to recompile it (or request a new version from vendor) instead of my own library.

That's definitely strange and confusing why linker was reporting an error in one of my library modules.
There is no connection between my library and FacebookSDK.

Bitcode not being included in my Framework

Okey finally I found the solution. In my case I had some library imported in my project which didn't have bitcode added.

You have to check that every library you use has bitcode and, if not, update to a version that has it (or download the code and compile it yourself with bitcode enabled as I've done).

You can check if a lib has bitcode enabled with the link in my question, but I'll paste it here again.

Hope this help somebody.



Related Topics



Leave a reply



Submit