14

I need to release a framework with bitcode enabled which turns out as a hassle. I set 'Enable Bitcode' in the project's settings to 'YES' and it builds cleanly for both a real device and a simulator.

I wanted to test the library so I integrated it to a new app I created for this purpose but now it only build for simulators. When I try to build for a real device I get:

ld: '/path/to/Framework.framework/Company(File.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. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Like I said, I had built it with Bitcode enabled so I'm not sure why this happens.

Any ideas? thanks

Yotam
  • 9,789
  • 13
  • 47
  • 68

3 Answers3

27

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:

enter image description here

enter image description here

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.

AlexDenisov
  • 4,022
  • 25
  • 31
  • 10
    The presence of a `__LLVM` segment is no prove that Bitcode is also present. There are other segments with that name and these don't contain bitcode. Better grep for `__bitcode`. – Mecki Nov 10 '15 at 11:54
  • Is this required also for universal frameworks? I **do** have bitcode enabled in the main target and also the "universal" target, but when using this framework later in another app, that fails out when archiving complaining because that framework does not have bitcode or so it says. – Jonny Feb 03 '16 at 02:13
  • I added `-fembed-bitcode`, like you suggested, to only the main target and that seems to have fixed it also for frameworks. – Jonny Feb 03 '16 at 02:23
  • I had the bitcode issue when using custom dynamic libraries. Grep showed that __LLVM is present. Only after I added `OTHER_CFLAGS="-fembed-bitcode"` to my universal framework build script and updated the embedded binaries, the final app Archive build succeeded. Still, otool did not show any changes in `segname __LLVM`, and `bitcode` was not even present at all. The only sign that the libraries have bitcode is that their size increased from under 1MB to 9MB. – JustAMartin Jul 12 '17 at 11:34
4

For enabling bitcode using xcodebuild command you have to add

BITCODE_GENERATION_MODE=bitcode.

find the below command

xcodebuild BITCODE_GENERATION_MODE=bitcode -target TARGETNAME ONLY_ACTIVE_ARCH=NO -configuration Release -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
SnehaK
  • 141
  • 1
  • 5
-3

Another way with RunScript code: (build setting -- Build Phases RunScript) enter image description here

# define output folder environment variable
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# Step 1. Build Device and Simulator versions
xcodebuild -target TARGETNAME ONLY_ACTIVE_ARCH=NO -configuration Release -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"
xcodebuild -target TARGETNAME -configuration Release -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}"

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 2. Create universal binary file using lipo
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a"

# Last touch. copy the header files. Just for convenience
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/include" "${UNIVERSAL_OUTPUTFOLDER}/"
DanielBarbarian
  • 5,093
  • 12
  • 35
  • 44
shujucn
  • 145
  • 1
  • 5
  • 1
    I am using similar script but it does not protect against the bitcode issue. I had to add `OTHER_CFLAGS="-fembed-bitcode"` or `archive` command to stop my final app Archive from complaining about missing bitcode in the linked frameworks. – JustAMartin Jul 12 '17 at 11:38
  • downvoting as it seems to me the answer does not address the topic (bitcode) in any way – superjos May 30 '19 at 14:14