13

Environment: XCode 7.0.1 Module: Objective-C Bundle Type: Framework

Hi, I am trying to create a framework to support armv7, armv7s, arm64, i386 and x86_64. I am using aggregate to make the fat library. Inside the aggregate script, i am running two xcodebuild commands 1. for armv7, armv7s and arm64 and 2. for i386 and x86_64 architectures. Also, I have set Enable Bitcode=YES and Other C Flags=-fembed-bitcode under target build settings. As a precautionary mesasure, i am adding ENABLE_BITCODE=YES and OTHER_CFLAGS="-fembed-bitcode" options to the xcodebuild command

My xcode build commands are as follows -

#Build The framework Target for iPhoneOS
xcodebuild -project "${PROJECT_FILE_PATH}" -target "${AN_TARGET}" 
ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -sdk iphoneos 
BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}" 
CONFIGURATION_BUILD_DIR="${IPHONE_DEVICE_BUILD_DIR}" SYMROOT="${SYMROOT}" 
ARCHS="armv7 armv7s arm64" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" $ACTION

#Build The framework Target for iPhoneSimulator
xcodebuild -project "${PROJECT_FILE_PATH}" -target "${AN_TARGET}" 
ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -sdk iphonesimulator 
BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}" 
CONFIGURATION_BUILD_DIR="${IPHONE_SIMULATOR_BUILD_DIR}" SYMROOT="${SYMROOT}" 
ARCHS="i386 x86_64" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" $ACTION

after running the above two commands, i am combining these two builds to make a fat framework binary using the below command

# create a fat Framework
lipo -create 
"${IPHONE_DEVICE_BUILD_DIR}/${PROJECT_NAME}.framework/${PROJECT_NAME}" 
"${IPHONE_SIMULATOR_BUILD_DIR}/${PROJECT_NAME}.framework/${PROJECT_NAME}" -
output "${FRAMEWORK_FOLDER}/${AN_END_USER_FRAMEWORK_NAME}"

The issue iam facing is after the lipo is created, i am unable to use it in the bitcode enabled application. After running the otool -l framework_binary | grep -LLVM, i do not see the bitcode enabled flags or __LLVM.

Lipo removes bitcode from the fat binary. Is there a way i can retain bitcode while running the lipo command?

Correction: Based on the reply from Nestor, i ran the otool command as otool -l -arch armv7 framework_binary | grep LLVM and much to my surprise, i could see the segname __LLVM clang. However when i integrate the same fat framework binary into my project, it builds fine on simulator however throws the following error while running on device - ld: 'MyBinary' 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

Deepak Badiger
  • 448
  • 7
  • 18

4 Answers4

9

Happily it's just a problem with otool's reporting, not lipo; you have to add the -arch parameter:

otool -arch arm64 -l myLipoOutput.a

Source: http://www.openradar.me/radar?id=6301306440384512

Nestor
  • 2,753
  • 2
  • 29
  • 34
  • tried that. Unfortunately, It seems the fat binary does not contain bitcode flags. as when i run it on simulator, it built fine but when i build it for device with Enable Bitcode=YES under application target build settings, i get the error ld: 'myBinary' 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. – Deepak Badiger Oct 15 '15 at 09:17
  • Sorry to hear that. You're sure it's lipo that's removing it? – Nestor Oct 15 '15 at 09:38
  • I think, the problem is bit different here. When i ran the command otool with -arch armv7 and for armv7s, arm64 i get the segname __LLVM, but when i build my application for device with bitcode fat binary, i get the following error ld: 'MyBinary' 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 – Deepak Badiger Oct 15 '15 at 10:36
8

This is something weird, there are not many documentation for do this, at the end I use this command:

xcodebuild -project ${PROJECT_NAME}.xcodeproj -target ${FRAMEWORK_NAME} ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode FRAMEWORK_SEARCH_PATHS="${FRAMEWORK_SEARCH_PARTH} ${SRCROOT}/**" -sdk ${SIMULATOR_SDK} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-${SIMULATOR_SDK} 2>&1

xcodebuild -project ${PROJECT_NAME}.xcodeproj -target ${FRAMEWORK_NAME} -sdk ${DEVICE_SDK} ONLY_ACTIVE_ARCH=NO BITCODE_GENERATION_MODE=bitcode FRAMEWORK_SEARCH_PATHS="${FRAMEWORK_SEARCH_PARTH} ${SRCROOT}/**" -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-${DEVICE_SDK} 2>&1

Add the BITCODE_GENERATION_MODE=bitcode flag to the xcodebuild command

David Cortes
  • 535
  • 4
  • 14
  • More info on this: http://stackoverflow.com/questions/34959767/whats-the-difference-between-fembed-bitcode-and-bitcode-generation-mode – Patrick Pijnappel Apr 30 '16 at 16:40
  • 2
    How does this solve the `lipo` issue? `lipo` strips any bitcode on merge. –  Mar 30 '17 at 09:51
  • 1
    At the end I fix this issue using the current commands: xcodebuild -project ${PROJECT_NAME}.xcodeproj ONLY_ACTIVE_ARCH=NO ENABLE_BITCODE=YES BITCODE_GENERATION_MODE=bitcode -sdk ${SIMULATOR_SDK} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-${SIMULATOR_SDK} 2>&1 xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk ${DEVICE_SDK} ONLY_ACTIVE_ARCH=NO ENABLE_BITCODE=YES BITCODE_GENERATION_MODE=bitcode -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-${DEVICE_SDK} 2>&1 – David Cortes Jun 11 '17 at 00:03
  • If your doing a framework, even if you have a scheme that supports bitcode I'm finding the BITCODE_GENERATION_MODE=bitcode must be added. I looked for 2 days to find this answer. – Scott Jenkins Aug 14 '17 at 17:08
1

Try to use archive for the arm slices instead of build

xcodebuild -scheme "${SCHEME}" -workspace "${WORKSPACE}" -configuration "${CONFIGURATION}" -sdk iphoneos ARCHS="arm64 armv7 armv7s" CONFIGURATION_BUILD_DIR="${CONFIGURATION_BUILD_DIR}/arm" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO ONLY_ACTIVE_ARCH=NO archive

After that run lipo to merge the simulator and the arm ones.

And after that run otool -arch arm64 -l myLipoOutput.a and it should work.

Cosmin
  • 2,840
  • 5
  • 32
  • 50
0

It looks like a bug in Xcode 7.0.1 . I've had the same issue and downgrading Xcode to version 7 fixed it.

Update: Actually it may be a bug in Xcode 7 that was fixed in 7.0.1 - this SO answer solved the issue for me.

Community
  • 1
  • 1
silyevsk
  • 4,021
  • 3
  • 31
  • 30