Carthage: BITCODE support

Created on 9 Jun 2015  Â·  50Comments  Â·  Source: Carthage/Carthage

Reading the release notes, I stumbled upon this:

ENABLE_BITCODE should be consistently turned on for all the targets. If you use a
library or framework provided by a third party, please contact the vendor for an updated version which
contains bitcode.

Given that Carthage is simply built on top of xcodebuild (yay!), it's likely that nothing will need to be changed. When compiling frameworks for dependencies using Xcode 7 (which hopefuly will have ENABLE_BITCODE set to true by default), it will do the right thing.

I figured I'd open an issue to keep track of this though :)

Happy Swifting!

build help wanted

Most helpful comment

I have found the Xcode setting differs between archive and build: BITCODE_GENERATION_MODE.

During normal builds, BITCODE_GENERATION_MODE is set to marker, meaning -fembed-bitcode-marker is passed to clang, meaning the bitcode section is created in the binary but has a size of 1.

During archive builds, BITCODE_GENERATION_MODE is set to bitcode, meaning -fembed-bitcode is passed to clang, meaning the bitcode section is created and properly filled.

All 50 comments

I'm not sure what the ENABLE_BITCODE flag does exactly in Xcode, but -fembed-bitcode can be used to embed bitcode directly into an object file.

When trying to build Quick with Xcode 7 beta 3, I got the following failure message:

ld: warning: Auto-Linking supplied '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/XCTest', '/Applications/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/XCTest' 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.

Perhaps it's related to this?

@dduan That is related to Quick/Quick#342.

From whatt i've gathered so far, bitcode will be included ONLY when archiving. Afaict, carthage isn't archiving, so i imagine there is some work to be done there.

Any update on this? Is there anybody working on this? Otherwise I'd invest some spare time...

I'm not sure what should be done here.

This issue is making any watchOS frameworks unusable when built with Carthage. When you try to submit the app to iTunesConnect, the Bitcode is missing.

To be fair, I opened this issue not knowing what it would entail at the time.
I'm not sure if there's anything that needs to be done in Carthage or of this is strictly a project configuration issue.

As far as I'm concerned all this is completely broken anyway.

I'm running into this issue as well. When submitting an app, I get the following warning for each framework built by Carthage:

Invalid Executable - The executable 'NAME.app/Watch/NAME WatchKit App.app/PlugIns/NAME WatchKit Extension.appex/Frameworks/BrightFutures.framework/BrightFutures' does not contain bitcode

The dependencies do have the bitcode build setting enabled, but Carthage' build process/xcodebuild doesn't seem to pick that up.

I'd like to help in resolving this issue, but any pointers for where to look would be appreciated.

I got around this by adding the Carthage checkout to my workspace and building the frameworks with my project. You can use --no-build when you update with Carthage and then when you archive, the Bitcode will be there.

Bitcode segments are included by xcode only when archiving. So if by "bitcode build setting enabled", you mean the dropdown set to "yes", that's expected.
Try adding -fembed-bitcode to your carthage dependencies projects, and see what happens.

/kra

On Sep 15, 2015, at 4:47 AM, Thomas Visser [email protected] wrote:

I'm running into this issue as well. When submitting an app, I get the following warning for each framework built by Carthage:

Invalid Executable - The executable 'NAME.app/Watch/NAME WatchKit App.app/PlugIns/NAME WatchKit Extension.appex/Frameworks/BrightFutures.framework/BrightFutures' does not contain bitcode

The dependencies do have the bitcode build setting enabled, but Carthage' build process/xcodebuild doesn't seem to pick that up.

I'd like to help in resolving this issue, but any pointers for where to look would be appreciated.

—
Reply to this email directly or view it on GitHub.

Maybe we should be using the archive command from xcodebuild instead of build?

I have found the Xcode setting differs between archive and build: BITCODE_GENERATION_MODE.

During normal builds, BITCODE_GENERATION_MODE is set to marker, meaning -fembed-bitcode-marker is passed to clang, meaning the bitcode section is created in the binary but has a size of 1.

During archive builds, BITCODE_GENERATION_MODE is set to bitcode, meaning -fembed-bitcode is passed to clang, meaning the bitcode section is created and properly filled.

Interesting! I wonder if making Carthage manually set BITCODE_GENERATION_MODE to bitcode would be a simpler fix than making it archive instead of build.

Definitely sounds like the way you'd like to go. Awesome finding!

Switching to archive only requires switching out one word in the source code. Someone just needs to test that it works. :smile:

conradev - thanks for your tip! I just tried adding that to my frameworks in Xcode then manually rebuilding. It worked and my WatchOS2 app is now submitted :-) So I can confirm this seems to fix it.

I have two Frameworks developed by myself that seem to miss the bitcode. I get this error when submitting:
Invalid Bundle - Failed to verify bitcode in LZUtility.framework/LZUtility: error: Bundle only contains bitcode-marker MyCurrency.app/Frameworks/LZUtility.framework/LZUtility (armv7)

I modified the run script adding OTHER_CFLAGS="-fembed-bitcode", but doesn't seem to work either.

Anybody can give me a step by step solution. I would really appreciate, I am completely stuck.

I didn't find any place in Xcode for setting BITCODE_GENERATION_MODE to bitcode. How is that done?

@skyluca You can add it as a User Defined Setting and Xcode will pick it up. There doesn't appear to be a setting by default.

Also to be clear that flag goes in the framework projects - and you'll have to rebuild your frameworks once you've added it.

So for me the steps were
1) Add that flag as described in the framework's project.
2) Rebuild the framework (either by using Xcode to build it then grab it from derived data, or i'm guessing you could also use the carthage build command - but I didnt try that).

@conradev, @dcaunt, @TomThorpe Thank you very much! I set BITCODE_GENERATION_MODE to bitcode. It looks it worked out. This time I am not receiving any error from iTunes, and the Icon of the App appeared on TestFlight App. Nevertheless it's still processing. I have been stuck on this for 48 hours, because I have a very complicated run script for building a Universal Framework both for iOS and WatchOS (and then another script for eliminating the simulators slices during submission). I hope that the nightmare is finished.

There is another relatively significant issue. Before submitting I have to uncheck "Include application symbols" (this way I cannot receive symbolicated crashes... If I do not uncheck I get this error:

"The archive did not contain

Anyone ever got this problem?

By the way I confirm that the submission setting BITCODE_GENERATION_MODE to bitcode worked perfectly!!!!! Thank you!!

Yep I did get that too and also unticked the upload dsyms option. Sorry I should have mentioned that.

I'm not sure how important uploading dsyms will be now anyway given that if you submit using bitcode the app willl have the final compilation done by the app store which should generate the dsyms for us. I'm not 100% sure on that though.

Glad it worked for you! Full credit to @conradev for finding that flag!

Yes full credit to @conradev !! By the way I have another "small" issue when the submission to iTunes is finalized. I get this message:

" The archive passed validation with several warnings. iTunes Store operation succeeded with a warning. The resulting API analysis file is too large. We were unable to validate your API usage prior to delivery. This is just an informational message"

Do you get you too this message??

@skyluca I always get that warning, doesn't have much to do with bitcode.
I also got the dsym upload problem. As far as I understand it, the problem is that carthage (or any framework that was built outside of your project actually) don't have a dsym and the App Store submission process chokes on that.
I spent most of last night playing with that, I couldn't for the life of me get a dsym to be included in there. We used to include all dependencies in the main project (e.g. rebuild the target within our project directly), and I was able to check the dsym box for a couple of releases.
Last night I started building the dependencies separately and linking against the binary (e.g. carthage style), and that's when the trouble started.
As far as I understand it, it's a shortcoming in their crash reporting offering.

I don't think bitcode has anything to do with dsyms, it opens post submission optimizations by retaining the semantics, but the actual debug symbols like "File foo+category.m line 24" is not available with dsy,s

@olarivain Thank you. But probably as @TomThorpe said dsyms are not so essentials with bitcode upload. Apple final compilation should generate dsyms for us. Of course it's a reasonable guess this, we cannot be sure 100%. Let's see.

Yeah, I have to agree it'd be nice if apple gave us more than 2 paragraphs of marketing material about bitcode.
Just figuring out if assembly is off bounds was already pretty tough for the cardIO guys.

I set this manually in the project (testing with RAC for now) and my submission still received

Invalid Executable - The executable 'WatchChessTV.app/Frameworks/ReactiveCocoa.framework/ReactiveCocoa' does not contain bitcode.

Am I doing something wrong? Once I can get this working I'll start opening PRs to RAC, xcconfig and others.

@NachoSoto You have to set the flag in the project which creates the Framework, not in the project that uses the Framework. If the Framework you are adding has not been developed by you, you have to address the developer of the framework, because you have no control on its binary/bitcode.

That's what I did, see the commit I referenced in my comment: https://github.com/NachoSoto/ReactiveCocoa/commit/c41b7b79de6156118c96073a80b6858aaef62e2b

@NachoSoto Strange. Try to add OTHER_CFLAGS="-fembed-bitcode" I had also this set.

@NachoSoto have you set the "Enable Bitcode" option in the build settings to Yes? I just cloned your repo at https://github.com/NachoSoto/ReactiveCocoa.git and the iOS target had enabled bitcode set to No - assuming that's what youre using?

@TomThorpe aaah, well, that would make sense wouldn't it 😗 I only set BITCODE_GENERATION_MODE 😅
Thanks! I'll give that a try :)

@NachoSoto - hope it works! :-) It doesnt help that there's about 3 different places we have to set this stuff! (Enable Bitcode, BITCODE_GENERATION_MODE and the final tickbox when submitting to iTunes Connect!)

Right, because only having one source of truth for this setting wouldn't be very Xcode. Also it makes a lot of sense that BITCODE_GENERATION_MODE exists, in case you want something like BITCODE_GENERATION_MODE="just kidding, no bitcode".

@NachoSoto So the issue was that Enable Bitcode was set to no? Anybody needed to set OTHER_CFLAGS="-fembed-bitcode" ? I had it set, but maybe this last flag is useless.

I'm getting the following error when trying to embed ReactiveTask in a mac application:

Build settings from command line:
    ONLY_ACTIVE_ARCH = NO

=== BUILD TARGET Box-Mac OF PROJECT Box WITH CONFIGURATION Release ===

Check dependencies
target 'Box-Mac' has bitcode enabled (ENABLE_BITCODE = YES), but it is not supported for the 'macosx' platform

Is there a workaround for mac apps?

You should be able to override that flag only for the Mac target to disable Bitcode.

This is working great, thanks a lot @conradev!!

I added it to xcconfigs, and I'll be opening more PRs to the frameworks I use :+1:

Can BITCODE_GENERATION_MODE be removed from project settings with new Carthage release?

Theoretically, yes :)

And it's a good idea?

Yeah I would probably remove it. It's only an implementation detail due to how Xcode works and the fact that Carthage uses archive instead of build.

That's true, thank you! :clap:

Are you talking about this change? https://github.com/Carthage/Carthage/commit/8fdc17d8bf3ff9180e96a1a1e27dcabce714d171

If I am reading this right, you are saying the next release of Carthage (0.9.4) should automatically handle setting BITCODE_GENERATION_MODE correctly without requiring every project change their own settings, yes?

I don't know which version number next Carthage release will have but this issue should be solved in it. I don't know specific commit as well.

I do not understand what happens, but with the new version of Xcode 7.3, the same dynamic library that I built with the flag BITCODE_GENERATION_MODE to bitcode, and which was working perfectly until now, does not work anymore. The project where I import my dynamic library gives again (when archiving) the error "You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE) or obtain an updated library from the vendor for architecture armv7k". Any clues?

@drskywalkerluke Can you please open a new issue with the details of your problem? This thread is very long, and your issue is related but distinct.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

willhains picture willhains  Â·  3Comments

faustperic picture faustperic  Â·  3Comments

3lvis picture 3lvis  Â·  3Comments

jdecarlo picture jdecarlo  Â·  3Comments

akaffenberger picture akaffenberger  Â·  3Comments