iOS - Objective C dynamic framework emit bitcode for arch x86_64 (simulator) - ios

Have setup a sample on Github, I'm using Xcode v 9.4.1
https://github.com/iousin/TreeFramework
Basically I'm trying to build my framework to include bitcode in the x86_64 simulator build. I tried various settings and tried building on command line, xcodebuild refuses to include bitcode in my simulator build, however it is very happy to include it in the arm64 (device) build.
All the following commands should be able to run from the same folder the above framework is checked out.
Following are the commands I've tried to build the above framework:
xcodebuild ENABLE_BITCODE[sdk=iphone*]=YES BITCODE_GENERATION_MODE=bitcode DYLIB_COMPATIBILITY_VERSION=1 -sdk iphonesimulator -configuration Release -target TreeFramework clean build
xcodebuild OTHER_CFLAGS="-fembed-bitcode" ENABLE_BITCODE[sdk=iphone*]=YES BITCODE_GENERATION_MODE=bitcode -sdk iphonesimulator -configuration Release -target TreeFramework clean build
xcodebuild OTHER_CFLAGS="-fembed-bitcode" ENABLE_BITCODE="YES" BITCODE_GENERATION_MODE="bitcode" -sdk iphonesimulator -configuration Release -target TreeFramework clean build
Ran the following to verify bitcode is emitted (it doesn't in this case).
otool -arch x86_64 -l build/Release-iphonesimulator/TreeFramework.framework/TreeFramework | grep LLVM
However when I build for a device, bitcode is included.
xcodebuild -sdk iphoneos -configuration Release -target TreeFramework clean build
Verify bitcode is emitted:
otool -arch arm64 -l build/Release-iphoneos/TreeFramework.framework/TreeFramework | grep LLVM
Appreciate any help.

Related

Export Universal framework for distribution

i have created a framework
Now if reveal it in finder,
It have 2 directory having framework
iphoneos
iphone simmulater
Now i create an app, and drag my framework from iphoneos directory, it run fine in iphone device but gives error in simmulater.
similarely if i drag framework from iphone simulater it work fine in simmulater but give error in device.
Please how to export both directory framework in a combine.
i have try to run script of lipo using aggreation target, but it fails
please guide proper steps.
You can add similar script to your build settings Build Phase tab as Run Script
# debug sim
xcrun xcodebuild -project myFramework.xcodeproj -target myFramework -configuration Debug -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
# release sim
xcrun xcodebuild -project myFramework.xcodeproj -target myFramework -configuration Release -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO
# debug ios
xcrun xcodebuild -project myFramework.xcodeproj -target myFramework -configuration Debug -sdk iphoneos ONLY_ACTIVE_ARCH=NO
# release ios
xcrun xcodebuild -project myFramework.xcodeproj -target myFramework -configuration Release -sdk iphoneos ONLY_ACTIVE_ARCH=NO
mkdir -p build/Release-Universal/myFramework.framework
cp -r build/Debug-iphonesimulator/myFramework.framework/* build/Release-Universal/myFramework.framework/
rm build/Release-Universal/myFramework.framework/myFramework
# lipo
lipo -create build/Release-iphoneos/myFramework.framework/myFramework build/Release-iphonesimulator/myFramework.framework/myFramework -output build/Release-Universal/myFramework.framework/myFramework

How do i make fat framework with bitcode option?

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
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
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
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.
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.

Build an iOS library with Bitcode in order to have backwards compatibility with XCode 6. How?

I am building an iOS static library and I want to provide support for bitcode. In order to achieve that I go to Build settings, search for "custom compiler flags" and add -fembed-bitcode. This builds the library with bitcode and everything works fine under XCode 7.
However by following the approach above I loose backwards compatibility with XCode 6. Having that said I have to ship 2 different library versions to my users, one with bitcode flag and one without since not everyone has upgraded to XCode 7.
Is there a way to have bitcode enabled library and have backwards compatibility without having to ship 2 different versions?
UPDATE:
Hello #Vinicius Jarina thank you for your message. I understand that you can create a fat library which I guess is a common practise. What I was doing so far was to build for both architecture:
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdK iphoneos
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator
and then call lipo to package in a fat library like:
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}"
However, how can i do it now? I tried something like this based on this link, but with no luck:
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos
xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator
xcodebuild -configuration "Release" OTHER_CFLAGS='-fembed-bitcode' -target "${FMK_NAME}" -sdk iphonesimulator
xcodebuild -configuration "Release" OTHER_CFLAGS='-fembed-bitcode' -target "${FMK_NAME}" -sdk iphoneos
and then create a fat lib like this:
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}"
how can i build in my scipt to include both and then package them in a fat-library?
UPDATE 2:
I finally managed to make this work and I list here my solution for others that may face the same issue:
xcodebuild -configuration "Release" ENABLE_BITCODE=NO -target "${FMK_NAME}" -sdK iphoneos
xcodebuild -configuration "Release" ENABLE_BITCODE=NO -target "${FMK_NAME}" -sdk iphonesimulator
xcodebuild -configuration "Release" ENABLE_BITCODE=YES -target "${FMK_NAME}" -sdk iphonesimulator
xcodebuild -configuration "Release" ENABLE_BITCODE=YES -target "${FMK_NAME}" -sdk iphoneos
and then create a fat lib like this:
lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/Versions/${FMK_VERSION}/${FMK_NAME}"
You can try to create a fat-library using different libraries.
lipo -create -output libAndreasv.a libAndreasvBitcode.a libAndreasvARMv7.a libAndreasvARM64.a
This used to work for fat libraries (x86,x64,ARMv7,ARM64) should work for bitcode as well.
Perhaps I am missing something but I do not believe you can have duplicate architectures in a fat library, regardless of whether bitcode is enabled/disabled. For instance the following command causes an error for me:
lipo -create libcurl_iOS_bitcode.a libcurl_iOS_nobitcode.a -output libcurl_iOS_both.a
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: libcurl_iOS_bitcode.a and libcurl_iOS_nobitcode.a have the same architectures (armv7) and can't be in the same fat output file

build iOS for iphonesimulator for 64x and 32x

I'm trying to build a framework that will work with iphonesimulator on both 64-32x.
The command i'm executing is:
xcodebuild -target mypack -sdk iphonesimulator8.1 -configuration Release -arch i386
For some reason it's threw me an error when i'm trying to run this framework on a 64x project ipa using iphonesimulator.
can someone tell me what i'm doing wrong?
I added a new arch called x86_64 into my framework project and then what fix for me the problem is the following command:
xcodebuild -target MobileCore -sdk iphonesimulator8.1 -configuration Release -arch i386 -arch x86_64

Error invalid architecture 'arm' when app from command line + iOS

I want to build an iOS app from command line with iOS simulator.
The build settings are:
1. Architectures - armv7
2. Base SDK - Latest IOS(6.1)
3. Build Active Architecture only - yes
4. Valid architectures - armv7 (also tried adding i386)
5. IOS deployment target - IOS 4.3
I am executing the following command:
xcodebuild -target splistapp2 -sdk iphonesimulator6.1 -configuration Release (also tried with -arch "i836")
But this command gives following error:
invalid architecture 'arm' for deployment target '-mios-simulator-version-min=4.2'
What could be the problem?
In case anyone running into the same annoying problem again, I will share my script here: Remember to run this command under the directory that has the xcodeproj file.
xcodebuild \
-project "full-path-to-your-xcodeproj-file" \
-target YOUR_TARGET \
-sdk iphonesimulator6.1 \
-arch i386 \
-configuration Debug \
VALID_ARCHS="armv6 armv7 i386" \
ONLY_ACTIVE_ARCH=NO \
TARGETED_DEVICE_FAMILY="1" \
clean install
I modified the TARGETED_DEVICE_FAMILY because I only build for iPhone. If you want to build for both iPhone and iPad, delete this line or replace with TARGETED_DEVICE_FAMILY="1, 2".
The device uses ARM; while the simulator uses i386. Pick one or the other:
iphonesimulator6.1 and arch i386
iphoneos and arch armv7 (or armv7s)
Implement using arch1386 architecture.
xcodebuild -project splistapp2 -target TEST_TARGET -sdk iphonesimulator -configuration "Debug" -arch i386

Resources