Skip to content
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.

Bitcode support #119

Closed
olarivain opened this issue Jun 30, 2015 · 49 comments
Closed

Bitcode support #119

olarivain opened this issue Jun 30, 2015 · 49 comments

Comments

@olarivain
Copy link

Hey,

CardIO is bundled as a static library without BitCode support. Is there any plan to ship a CardIO build with bitcode enabled?

As you probably know, watchOS 2 apps require BitCode to be enabled. While cardIO doesn't make a lot of sense in a watch app, it's companion app could require it, and through the magic of shared libraries, the watch app can very easily end up depending on a bitcode-less static lib, which will essentially make it impossible for one to submit to the store.

@dgoldman-pdx
Copy link
Member

@olarivain we don't have the resources to attack this ourselves right now. But if you would like to create a Pull Request at https://github.com/card-io/card.io-iOS-source to accomplish this task, we would certainly be happy to make it part of the official build.

@josharian
Copy link
Member

Good question.

Unfortunately, everything I've seen about BitCode is rather short on technical detail. card.io uses non-vanilla technology like inline assembly, NEON intrinsics, and crazy C++ templating (via Eigen). So the only way to find out is probably to enable the relevant Xcode settings, try recompiling from source, and see what happens. The source is at https://github.com/card-io/card.io-iOS-source. If you want to give it a try and report back, that'd be awesome.

I'd love to see links if you have deeper technical references about BitCode or if you have info about CocoaPod's handling of BitCode.

@josharian josharian reopened this Jun 30, 2015
@dgoldman-pdx
Copy link
Member

Or, what @josharian said. 😺

@olarivain
Copy link
Author

Oh wow, and here I was thinking this was a closed source library.
I'll take a stab at it then.

As for details on bitcode, I don't have much myself – so far it's simply a checkbox in Xcode. I'm suspecting assembly would rule it out though, since the feature is based on LLVM IR.

@olarivain
Copy link
Author

So far haven't had much success, even after stripping all the inline ASM I could find, e.g. a handful of cpp files (but I'm far from being an asm expert).

I found https://forums.developer.apple.com/message/7038#7038 which is the best doc I've found thus far.
I'll keep digging, but I have little hope I have the skills needed to patch anything - so far I can only say out of the box, bitcode seems pretty tough for cardIO.

@josharian
Copy link
Member

Thanks, that's a very interesting link. Good to know we're not alone.

It suggests that the asm should be workable. But if you want to ifdef out all the assembly and NEON in one go, define the preprocessor macro DMZ_HAS_NEON_COMPILETIME to 0.

What is the error message / failure mode you get with the asm in?

Note that the canonical way to build the card.io static library is using fabric (fabfile.py), and I notice that we are using Release mode there, whereas from the link you found, it looks like we need to use Archive mode.

@josharian
Copy link
Member

And: Thanks very much for digging into this.

I really, really wish there were some serious, detailed technical docs about BitCode. It also impacts another project I'm very interested in, which is getting Go running on iOS. There's an arm64 Go compiler, and everything works now, including codesigning etc., but it is not LLVM-based, and it's utterly unclear what BitCode means for non-LLVM compilers. I sincerely hope that the answer is not "LLVM or the highway".

@olarivain
Copy link
Author

I'm able to build the library, bitcode doesn't prevent that, you just get a scary warning from ld at the end.
Looks like it's just an extra segment in the framework that will get stripped out before public distribution by apple, but the library remains a fat library with arm and x86 slices.

As for the thread, the answer is weird, i understand it as "you can still build assembly, but bitcode will be disabled for that .o". Which makes sense considering the point is retargeting a different cpu that isn't backward compatible.

Anyway, thanks for the macro, that's very helpful. I won't have time to look into this until the end of the weekend, i'll be back here early next week with whatever i find.

@olarivain
Copy link
Author

Oh, and yeah, the archive requirement is yet another curve ball thrown at dependency managers.
Considering you distribute the lib in a binary form, as long as you get the bitcode in, you should be fine.
Projects like carthage are in for a fun summer though.

@josharian
Copy link
Member

Thanks for the update!

@olarivain
Copy link
Author

took me a little longer than expected, sorry about that.
In the end, cardIO itself is just fine with -DDMZ_HAS_NEON_COMPILETIME. Even without, ld doesn't seem to complain about anything bitcode related.
libopencv_core.a and its buddy libopencv_imgproc.a are the one causing ld to drop bitcode.
I can see

@olarivain
Copy link
Author

sigh, clicked send too fast.
I can see an opencv_device folder, with what appears to be a build script and source, is that where you guys get those libs built from?
If so, I'm hoping it should get me to next step.

@olarivain
Copy link
Author

Yep! I dropped the code from opencv_device into the project, and now ld happily creates the LLVM segment:

olarivain$ otool -ol build/Build/Intermediates/ArchiveIntermediates/CardIO/IntermediateBuildFilesPath/UninstalledProducts/libCardIO.a | grep LLVM
   segname __LLVM
   segname __LLVM
   segname __LLVM

Next step is for me to actually deploy that on a watch, as it seems to refuse to deploy any binary that doesn't have bitcode enabled, even directly from Xcode.
Oh. and well, test it. make sure it actually works :)

@josharian
Copy link
Member

Any update? I'm curious to hear how it went.

@olarivain
Copy link
Author

Hey,

Sorry i got distracted on a large number of other watchos issues (a number of headers are missing on the watch, and uikit is mostly off bounds).
I got the static lib to build with the llvm segments, so that part is covered. i'd be very suprised if things don't go smoothly from here, but i'm currently on pto, until the 9th, i'll get things cleaned up and submit a pr around that time.

@scalessec
Copy link

@olarivain I'm in the same boat here. Any update? If not, do you have a fork with your progress?

@davidrothera
Copy link

This (CardIO) is my only remaining dependancy that doesnt support bitcode 👎

What is the update here?

@olarivain
Copy link
Author

From what I had tested, it shouldn't be much more complicated than:

  • enable bitcode in the project settings
  • passing -fembed-bitcode and -Qunused-arguments to clang (forces bitcode to embed and tells clang to stfu about unused -fembed-bitcode-marker)
  • potentially setting the precompiler directive to skip the assembly part. I still haven't found any doc there and have no clue if assembly is kosher in bitcode land.

doing more or less that got me the beloved __LLVM segments in otool.

The ramp up to iOS 9 has been crazy (like I imagine it has been for everybody else), and we have so many shitty third party binary that won't even remotely support bitcode that I couldn't justify spending the time to actually build and link the bitcode version.
Things will get saner next week, but in the meantime if anybody feels like trying the above.

@burnto
Copy link
Member

burnto commented Sep 12, 2015

I'm working on getting a direct card.io source integration working (via Carthage) and will try to get bitcode support in there. No eta.

Note this lib is FOSS and maintained by volunteers, not paid staff, so feel free to jump in with contributions. https://github.com/card-io/card.io-iOS-source

@billinghamj
Copy link

I think it'd be better for the CocoaPods package to integrate directly with the source rather than this compiled version. Makes it a bit easier to avoid issues like this one in the future.

@burnto
Copy link
Member

burnto commented Sep 14, 2015

Yep, I think we all agree it definitely would be better to switch to a source distribution. I'll try to address CocoaPods as well. The current .a distribution is a remnant of the origins of this project as a commercial, closed-source product.

I will hopefully have some time to work on this on Friday.

@billinghamj
Copy link

Interestingly, I cloned the source project, turned bitcode on and compiled it, and it seems like it is working fine. No errors came up at all. Might be missing something though.

@burnto
Copy link
Member

burnto commented Sep 14, 2015

@billinghamj yeah feel free to go ahead with that approach, or to work on a CocoaPods PR for the source project.

@billinghamj
Copy link

I'd be happy to try. The only problem is I have virtually no knowledge of how this project works, so it might just break everything.

@billinghamj
Copy link

Also seems like opencv would be better as a dependency rather than trying to embed it. Seems very strange to avoid using dependencies.

@burnto
Copy link
Member

burnto commented Sep 14, 2015

We've shied away from forcing developers to use a specific dependency management system. Keep in mind that this lib has been around since 2011… 😄

@billinghamj
Copy link

Totally agree it shouldn't be forced. As long as manual installation is still easy though, doesn't mean you shouldn't take advantage of Carthage and Cocoapods when they're available.

@davidrothera
Copy link

I tried that (compiling from source with Bitcode) and whilst it works fine locally in the sim etc when you try and submit to Apple I was getting binary rejected due to some indecipherable Swift support error.

I spent all weekend looking into the issue and this morning after removing the Card.IO dependency it worked without issues.

Don't get me wrong though, it could just be that Apple's systems were screwed all weekend and they pushed a new version of their 'linter' this morning :/

@olarivain
Copy link
Author

Apple is infamous for server side screw ups, but I doubt their binary checker would have this kind of issues, specially considering iOS goes live in less than 48 hours.

Have you tried disabling the assembly part with DMZ_HAS_NEON_COMPILETIME?

@williamnoto
Copy link

Shaminy, this is my last bitcode linker error too. Just upgraded Flurry and FB.

@willlarche
Copy link

So enthused to see so many smart engineers working on this issue. Thanks, guys! #openSourceWorking

@jakedunc
Copy link

Also my last dependency to be upgraded.. I will watch patiently :)

@burnto
Copy link
Member

burnto commented Sep 22, 2015

@davidrothera take a look at @bluk's work on card-io/card.io-iOS-source#39

@nickbit
Copy link

nickbit commented Sep 24, 2015

How far is this from being done? It should be marked as a bug and not as an enhancement though.

@bluk
Copy link
Contributor

bluk commented Sep 24, 2015

@nickbit If you want, you can try out card-io/card.io-iOS-source#39 and see if it works for you. As far as I know, it is done. I plan to merge it in soon but wanted to give one more day to see if there was any other feedback. Note that once this is merged, if you are using Xcode 6.4 or lower, you will be forced to either rebuild the library or upgrade to Xcode 7 (Bitcode enabled static libraries and Xcode 6.4 do not seem to get along).

@nickbit
Copy link

nickbit commented Sep 24, 2015

@bluk I tried it and it does not work for me.
It compiled OK, the bitcode flag was set, I copied the file to our Xcode project and I got the bitcode error for CardIO.
I run otool -l libCardIO.a | grep LLVM and otool -l libCardIO.a | grep bitcode and got no results. It seems that no bitcode segments are present in the library. Maybe something prevents it from building right (although no error occurred in the build process).
Any suggestions?

@bluk
Copy link
Contributor

bluk commented Sep 24, 2015

@nickbit Did you try to run it via the fabfile (instructions in the README)? I ran fab build:outdir=~ and did otool -l /Users/brluk/card.io_ios_sdk_5.1.1-6-ga422a81/CardIO/libCardIO.a | grep LLVM and it had about 44:

Section
  sectname __bitcode
   segname __LLVM

@nickbit
Copy link

nickbit commented Sep 24, 2015

@bluk I will test it and let you know. Thank you!

@nickbit
Copy link

nickbit commented Sep 24, 2015

@bluk fab command issues an error when trying to build target i386:
Fatal error: local() encountered an error (return code 65) while executing 'xcrun xcodebuild -target CardIO -arch i386 -sdk iphonesimulator -configuration Release -parallelizeTargets CONFIGURATION_BUILD_DIR=/var/folders/15/wn_d95051_7cmjfkt0l5lfm80000gn/T/tmplD6UFB/Release/i386 GCC_PREPROCESSOR_DEFINITIONS='$(value) ''

@bluk
Copy link
Contributor

bluk commented Sep 24, 2015

@nickbit I expected the command to also include OTHER_CFLAGS='-fembed-bitcode' as seen https://github.com/card-io/card.io-iOS-source/pull/39/files#diff-65218180447789ae9b6a89838c1966c9R169 so I would double-check the branch you are on. I would also check if your Xcode 7 command line tools are correctly installed and you have selected them via xcode-select in your shell.

@nickbit
Copy link

nickbit commented Sep 25, 2015

@bluk I did everything from the beginning and now it compiled ok. __LLVM segments are there now. Probably I was building in the wrong branch. Thank you very much for your help!

@bluk
Copy link
Contributor

bluk commented Sep 25, 2015

@nickbit Great. I'll try to merge and see if I can do an official release soon.

@bielikb
Copy link

bielikb commented Sep 29, 2015

I recommend to read this article, if you're interested to know more about bitcode and it's security pitfalls https://medium.com/@FredericJacobs/why-i-m-not-enabling-bitcode-f35cd8fbfcc5

@sanchexx
Copy link

Any idea when these changes should be reflect in the Card.io SDK? Or should we use the Source instead?

@josharian
Copy link
Member

@bluk said elsewhere that he plans to cut a release "soon (tomorrow?)".

As to BitCode security concerns, I am sympathetic to them. And it makes me very sad that LLVM is now the One True Compiler—or at least that other compilers must learn to emit LLVM IR, which is itself a fraught enterprise. (I have worked on Go's arm64 support, so I have a bit of skin in the game.)

That said, I believe that you can remove the BitCode segments from the card.io with a quick lipo invocation if you don't want it (or use the source). And initial indications are clearly that the vast majority do want it, so providing it seems like the right default.

@billinghamj
Copy link

Moving from a binary distribution to compiling both cardio and opencv directly from source would fix the security concerns - as cocoapod/carthage bitcode compilation follows the settings of the project they're imported into.

@bluk
Copy link
Contributor

bluk commented Sep 30, 2015

I have released version 5.2.0 of card.io iOS SDK with Bitcode enabled. Sorry for the delay. I am working on pushing it out to CocoaPods and hope to have that out tomorrow (need to get permissions).

Note that the library is now zipped initially as libCardIO.a.zip. The library unzipped is over 200MB, and I do understand that it is large. I experimented with a few different compiler/linker settings but wasn't able to produce significant savings. The x86_64 and i386 parts do not make a significant difference since they are against the Simulator SDK so do not have any real Bitcode enabled parts.

When Apple compiles your Bitcode version of your app, it should be roughly the same size before Bitcode-enablement.

In order to deal with the increased size, I like the idea of moving to a source distribution and I see PR card-io/card.io-iOS-source#36 . If others can comment in card-io/card.io-iOS-source#32 or the PR to see if that's the right direction, it would be appreciated.

I'll close this issue for now but if you have any additional Bitcode specific issues or suggestions, please re-open or open a new issue. Thanks for your patience!

@bluk bluk closed this as completed Sep 30, 2015
@billinghamj
Copy link

@bluk 5.2.0 hasn't been pushed to Cocoapods yet. Could you do that please?

@bluk
Copy link
Contributor

bluk commented Oct 1, 2015

@billinghamj Done. 5.2.0 should now be available via CocoaPods.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests