iOS library to BitCode
Asked Answered
B

6

57

I recently downloaded Xcode 7 beta, and Xcode complains about some of my C libraries not being compiled into BitCode. How would I go about telling Clang to produce BitCode that is compatible with iOS? I've seen similar answers on stackoverflow, but I don't know if they apply to producing BitCode libraries for iOS.

Edit:

I am using the correct setting, -fembed-bitcode, but when I try to archive, I get the error: ld: warning: ignoring file XXXX/XXXX, file was built for archive which is not the architecture being linked (arm64). When I use -fembed-bitcode-marker, I can archive, but I get the error: full bitcode bundle could not be generated because XX/XX was built only with bitcode marker. The library must be generated from Xcode archive build with bitcode enabled.

Any ideas on what is going wrong? The library is compiling successfully, but it doesn't let me archive. I created a simple add function and made it into a library, and I get the same symptoms, so it is not the library I'm compiling.

Edit 2: You must build both the arm64 and armv7 versions using bitcode and lipo them together. Using bitcode doesn't take away the need for a fat library when archiving. source : Link

Boloney answered 5/7, 2015 at 18:4 Comment(2)
so you compile these C libraries yourself?Connotative
Yeah, specifically asking about gmp. But I'm asking in general, how do we get clang to produce BitCode that works with iOS. I know there's an option to get clang to stop at the intermediate representation (IR), but I don't know if this will work with the whole BitCode Apple is mentioning now.Boloney
F
77

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).
Fiorin answered 10/7, 2015 at 17:20 Comment(4)
Thanks for the xcode-select build trick, that is very useful, and I didn't know about it. So if I use -fembed-bitcode, will the produced libraries work under the simulator? I currently have to use the -fembed-bitcode-marker libraries when deploying to the device, but have to use my previously compiled fat libraries when running on the simulator, else I get linker errors. Also, if I use -fembed-bitcode-marker, is Xcode creating the bitcode versions of the library when deploying to device, as I don't get warnings anymore?Boloney
Okay, I've built using that command. However, I am having the same symptoms as before - the fat libraries run on the simulator, but the -fembed bitcode ones don't. Also, I can't archive. Xcode says "ld: warning: ignoring file X, file was built for archive which is not the architecture being linked (arm64)." When I use the -fembed-bitcode-marker library, it lets me archive, however I again get the bitcode warnings as you said (since it is not actually bitcode). Why can't I archive with -fembed-bitcode only then, it even says it was built for archive.Boloney
I am having the same trouble and I have tried the same :/Gavra
Where i have to insert that line will you please tell mePatio
D
56

Go the Build Settings. Search for "custom compiler flags".
Add -fembed-bitcode to Other C Flags. This will ensure that the lib is built with bitcode compatibility at compile time. I made this for iOS 64 bit and 32 bit, and lipo'd them into one. Works like a charm.

Since you guys had queries, here's a screenshot of the settings: The settings are same for the project target and the SDK target.

enter image description here


The bitcode lib will not work with Xcode 6.

Declinature answered 15/9, 2015 at 9:52 Comment(7)
Can you please share the script for making 64bit, 32bit and for simulator and then lips them into one?Spagyric
lipo -create -output “destination” “source1” “source2” "source 3". Here source 1 is your path to the 32 bit simulator lib, "source 2" is the path to 64 bit simulator lib and "source 3" is the path to "iOS Device lib". This is done from the terminal. You can check the final library details with this command lipo -info "path to the final lib"Declinature
Thanks, I want the build command for creating 32bit and 64bit lib filesSpagyric
@GautamJain, I am using XCode7.0.1 and i added Other C Flags with -fembed-bitcode, Enable Bitcode=YES under the target build settings and then ran lipo command on the device and simulator builds. Also, i am using shell script to make the device and simulator builds with ENABLE_BITCODE=YES and OTHER_CFLAGS="-fembed-bitcode" options. However, i don't seem to have luck with the fat library. The bitcode is stripped from the fat library and i am unable to archive my application when setting Enable Bitcode=YES under the application target build settings. I am confused why lipo removes bitcode flags?Iaverne
"bitcode is stripped from the fat library" I am seeing this too. I am trying to convince myself that this is expected behavior...Ascogonium
@Ascogonium - It is working for me. If I run this command otool -l /Users/gautam/Desktop/SDK/V1.8.5/MoEngage/libMoEngageSDK.a | grep LLVM. I get the result segname __LLVM. If I do it with a lib I built without bitcode, I get nothing. Hence it means my lib has bitcode. Attaching a screenshot of my settings in the answer.Declinature
should it also be on C++, or only C ??Chloropicrin
D
30

If you're still having trouble after adding the -fembed-bitcode to the Other C flags, search for "Enable Bitcode" under "Build Options" and set it to No. This will allow you to archive properly.

Determinative answered 27/4, 2016 at 3:53 Comment(2)
You sir, are a life-saver! Thank you!Buffon
It should be set to no? not yes? #34666747Camden
G
21

What you need is -fembed-bitcode. When ENABLE_BITCODE is enabled, Xcode builds with -fembed-bitcode-marker for regular builds and with -fembed-bitcode for archive builds. One option simply "marks" where the bitcode would be in the binary after an archive build and enforces the new bitcode rules, while the other actually does the full-on bitcode generation, which is likely slower and thus not enabled on every kind of build.

Syo Ikeda's guide to handling BITCODE might also help you:

You can find the full slide deck here.

Gunzburg answered 2/11, 2015 at 18:51 Comment(0)
N
12

If you are building a Static Library and would like to enable the bitcode, just the (1) ENABLE_BITCODE = YES may not be enough.

(2) Also with the setting -fembed-bitcode the error below was still being thrown for multiple files when built in Teamcity

bitcode bundle could not be generated because ‘/path/fileInYourStaticLib.a(fileInYourStaticLib.o)’ was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture arm64

Few tips/things to consider that helped me to ultimately solve the issue, in addition to the above steps (1) and (2)

  1. Make Sure you set the variable 'Other C Flags' to "-fembed-bitcode" on the 'PROJECT', and all the 'TARGETS'.

  2. If there are multiple projects that you are trying to create a static library for, make sure all the projects have "-fembed-bitcode" enabled.

  3. On Build Settings, click on the + sign at the top to add a user-defined build setting with the nameBITCODE_GENERATION_MODE, and set Debug tomarker, Release tobitcode

  4. If the above steps doesn't work, you can also try this option. On Build Settings -> Other C flags, set Debug to-fembed-bitcode-marker, and Release to-fembed-bitcode

This blog was of great help https://medium.com/@heitorburger/static-libraries-frameworks-and-bitcode-6d8f784478a9

Also every time you make the above changes, try deleting the DerivedData, Clean the XCode Project, and possibly quit and restart XCode

Ninfaningal answered 27/4, 2017 at 8:45 Comment(1)
cool, ya its not as straight forward as setting a flag unfortunately :)Ninfaningal
M
0

Just to add some details for future noobs like me.

I ran into this problem with libVivoxNative.a when building from unity to iOS. I had to disable bitcode in 4 different spots:

screenshot

Originally I guess I had just set it for the target Unity-iPhone, not the project or the tests/UnityFramework. Changing the setting for all 4 did the trick.

Mauser answered 5/11, 2021 at 18:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.