93

Xcode 7 introduces Bitcode, which is some sort of LLVM intermediate binary that means Apple's servers can recompile my app for different architectures without my involvement.

At Lookback, I distribute a static archive framework with our library. It seems that when you build with anything but a "Build & Archive", bitcode is not actually emitted into my library, and anyone who links with my library in their app and tries to do a Build & Archive with Bitcode enabled will get one of two warnings:

  • ld: 'Lookback(Lookback.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. (if lib is built with Xcode 6)
  • ld: warning: full bitcode bundle could not be generated because 'Lookback(Lookback.o)' was built only with bitcode marker. The library must be generated from Xcode archive build with bitcode enabled (Xcode setting ENABLE_BITCODE) (if lib is built with Xcode 7 with a normal xcodebuild)

I have a build script that builds a device+simulator universal binary, so I can't use Build & Archive, but rather, I run xcodebuild from commandline from my script. How can I make xcodebuild generate a proper bitcode-enabled library?

2
  • HI @nevyn Im trying to get your SDK to compile in an app which uses bitcode. Is there a way?
    – Stoff81
    Mar 29, 2017 at 15:31
  • @Stoff81 Sorry, I'm working on it. I need to get all my dependencies working with Bitcode first, and it's quite a bit of work.
    – nevyn
    Oct 18, 2017 at 23:21

4 Answers 4

142

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

13
  • 9
    FWIW, you can get rid of the warning about -fembed-bitcode-marker being ignored by adding -Qunused-arguments as well.
    – mstorsjo
    Sep 29, 2015 at 10:33
  • which exportFormat do use for a xcodebuild of a framework? Only "ipa", "pkg" and "app" seems to be defined (developer.apple.com/library/mac/documentation/Darwin/Reference/…). Dec 2, 2015 at 10:27
  • @nevyn Still could not build my main app which has the custom framework file which in turn contains a build script with the above mentioned flag. Jan 22, 2016 at 23:25
  • otool -l (my .o or .a file). Do you mean otool -l (my .o or .a file) | grep __bitcode ?
    – Mike M
    Feb 22, 2016 at 13:03
  • 1
    @MikeM no actually otool -l myfile.o | grep __LLVM, because there will be a __bitcode segment even if there's only bitcode marker in there instead of real bitcode.
    – nevyn
    Feb 22, 2016 at 22:34
44

With Xcode 8, I couldn't get OTHER_CFLAGS="-fembed-bitcode" to work. I kept running into something along the lines of was built without full bitcode. All frameworks and dylibs for bitcode must be generated from Xcode Archive or Install build when I tried to create an Archive build of an app containing my static framework.

What I was really looking for was this:

BITCODE_GENERATION_MODE=bitcode

I'm actually using a Run Script inside of an aggregate target, the full xcodebuild line looks like this (just for reference):

xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

4
  • 3
    +1, the BITCODE_GENERATION_MODE=bitcode method seems to be preferred, as suggested in this answer too. Nov 9, 2017 at 1:06
  • This also fixed my issue whereas the default answer doesn't anymore.
    – Kamchatka
    Jan 8, 2018 at 16:18
  • Life saver! Thank you! Nov 18, 2019 at 6:03
  • +1. Accepted answer didn't work for me, but including BITCODE_GENERATION_MODE=bitcode did the trick. Thank you! Dec 9, 2021 at 1:35
17

Once you add bitcode support for the static lib, it won't be compatible with Xcode 6. The app won't archive.

I would like to clearly mention the setting for bitcode as @nevyn's answer confused me a little.

Go to Build settings, search for "custom compiler flags". Add -fembed-bitcode. This will build your lib with bitcode.

0
7

Select project On Build Settings -> Other C flags, set Debug to -fembed-bitcode-marker and Release to -fembed-bitcode

On Build Settings, click on the + sign at the top to add a user-defined build setting with the name BITCODE_GENERATION_MODE, and set Debug to marker, Release to bitcode

Edit schema as Release Then click the desired library. A file and get the build path. Get the library form Release folder.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.