Skip to content

Support Apple app store bitcode #35968

Closed
Closed

Description

@brson

Bitcode is the future of Apple's app distribution and we don't support it now. Doing so is tricky because Apple choses whatever rev of LLVM they want and upgrade it per their whims. We can't couple our LLVM to theirs because we have our own needs and can't be forced to upgrade whenever Apple decides.

Here are some options:

  • We ship an entirely separate toolchain for targetting Apple bitcode. This is quite ugly.
  • We change rustc to dynamically load LLVM, create a rust-llvm package and an optional rust-llvm-apple package, and have rustc load the apple LLVM to deal with their bitcode.
  • We create a rustc_llvm_apple crate and just link two entire LLVMs into rustc at all times. This probably would not fly
  • We create a build of rustc called rustc-apple and ship it in an optional rustc-apple package. It is exactly like rustc except instead of linking to rustc_llvm it links to rustc_llvm_apple. When rustc gets a request to emit bitcode it just defers completely to the rustc-apple binary. I actually fancy this solution quite a bit.
  • We could investigate a bitcode sanitizer to translate our bitcode to theirs. I think the likelihood of success here is low because maintenance. I believe RenderScript does this.

I think the LLVM dynamic loading and defer-to-alternate-rustc solutions are most promising.

cc https://users.rust-lang.org/t/ios-rust-integration/6928/4

cc @bluejekyll

Activity

  1. added
    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
    E-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    O-iosOperating system: iOS
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Aug 24, 2016
  2. nagisa commented on Aug 24, 2016

    @nagisa
    Member

    We change rustc to dynamically load LLVM, create a rust-llvm package and an optional rust-llvm-apple package, and have rustc load the apple LLVM to deal with their bitcode.

    Dynamically loading LLVM is certainly not an option. The LLVM API is less stable than its bitcode and, if we build against LLVM x.y, then having LLVM x.z instead of x.y will almost certainly break rustc. Just link to the system LLVM statically (like --llvm-root already does).

    We create a rustc_llvm_apple crate and just link two entire LLVMs into rustc at all times. This probably would not fly

    Just link the system LLVM (statically) for apple distributions. In my experience it already works kinda well.

    We could investigate a bitcode sanitizer to translate our bitcode to theirs. I think the likelihood of success here is low because maintenance. I believe RenderScript does this.

    Okay… so, the thing is that LLVM bitcode format is kinda stable between versions of LLVM. Does apple do something unusual to make that not true, or is the bitcode format used not LLVM altogether (i.e. has apple specific stuff)?


    I feel like I heard all the way back in 2013-ish that using LLVM bitcode as distribution format is stupid. I certainly agree; does distributing native binary libraries not work anymore for iOS?

  3. nagisa commented on Aug 24, 2016

    @nagisa
    Member

    I’m also very interested in what would happen when Apple upgrades to LLVM version with incompatible bitcode format internally and people still compile stuff with old compilers.

  4. bluejekyll commented on Aug 24, 2016

    @bluejekyll

    I experimented briefly with this, i.e. output bitcode during cargo builds, then tried to create a static library with the bitcode included. When I tried to llvm-link against the bitcode library, I got an incompatible LLVM version from the bitcode.

    I don't have an easy test to reproduce this, but my guess is there is just a dumb version check that denies linking between different LLVM versions? Or, I just did something entirely wrong. I will try to come up with a test case when I have some time to look at this again.

  5. sanxiyn commented on Aug 24, 2016

    @sanxiyn
    Contributor

    It would be useful to have exact error message from llvm-link.

  6. nagisa commented on Aug 24, 2016

    @nagisa
    Member

    @bluejekyll LLVM has a number of bitcode files in its test directory. Tests against these bitcode files are run continuously (llvm-dis-3.8/opt-3.8 understands a 3 year old bitcode file from 3.2 just fine, for example), so it must be some apple stuff.

  7. ricky26 commented on Aug 24, 2016

    @ricky26
    Contributor

    Just link the system LLVM (statically) for apple distributions. In my experience it already works kinda well.

    This is somewhat easier said than done - as far as I'm aware, the only blessed apple-llvm version for App Store uploads is the one shipped with the current Xcode. This also potentially means maintaining the LLVM bindings for two LLVM versions (not necessarily two neighbouring minor versions, either). I don't think it's valid to just use an old version of apple-llvm.

    I’m also very interested in what would happen when Apple upgrades to LLVM version with incompatible bitcode format internally and people still compile stuff with old compilers.

    I think they avoid this by only allowing the latest Xcode to submit apps (and I'm pretty sure it's burned into the output image which LLVM version you used).

    IIRC, the bitcode is packaged for each architecture, since cross-architecture bitcode isn't generated by clang (I think that's an anti-goal of clang and bitcode in general). It's stored in a section for each object file so at the very least it's duplicated. That could be part of why someone mentioned that bitcode might not be the best way of going about this.

    I feel a bit like all of the recommended solutions are somewhat icky. The least messy way I can think of is to allow different targets to overload the codegen behaviour and have the Apple codegen path be in a dynamic crate. (Which would just be the regular codegen path compiled against apple-llvm.)

    Since this bug mentions the App Store, is it worth talking about the exception handling story here? (i.e. panic=abort is strictly required at the moment.)

  8. bluejekyll commented on Aug 24, 2016

    @bluejekyll

    LLVM has a number of bitcode files in its test directory. Tests against these bitcode files are run continuously (llvm-dis-3.8/opt-3.8 understands a 3 year old bitcode file from 3.2 just fine, for example), so it must be some apple stuff.

    @nagisa thanks for letting me know this. It gives me hope that there might still be a solution here, and that I was probably doing something wrong.

  9. nagisa commented on Aug 24, 2016

    @nagisa
    Member

    @ricky26 good points.

    as far as I'm aware, the only blessed apple-llvm version for App Store uploads is the one shipped with the current Xcode.

    Isn’t Xcode LLVM on apple the same thing as system LLVM? I meant the Xcode LLVM then. We would have to make sure xcode is always the most recent version when shipping rustc trains.

    Of course the way apple does things rules out us producing a valid apple bitcode with an old version of rustc and essentially forces us throw all the benefits our stability story provides out the window, and I don’t see any way this could be fixed.

    This also potentially means maintaining the LLVM bindings for two LLVM versions

    We already maintain¹ support for LLVM versions 3.7 through 3.9 (and potentially trunk). As long as Xcode’s LLVM is not some ancient version, I think we’re good in that regard. If Xcode LLVM is really some ancient/custom/etc version, then I don’t see us being able to support this feature at all, then. Especially since we have no option of sending patches to that LLVM in order to add the features we need. I also wouldn’t want to lock rustc into supporting 3.7 forever in case Apple decided to not update Xcode LLVM until 2038.

    ¹: however, if rustc was built against LLVM x.y, it must be linked to LLVM x.y exactly.

  10. 92 remaining items

  11. Narniab commented on Sep 13, 2020

    @Narniab

    -Cembed-bitcode=no does not work for ios target. there are still bitcode section in .a file
    how to build without bitcode?

  12. fzyzcjy commented on Oct 13, 2021

    @fzyzcjy

    Hi, after years, is there any updates? Thanks! In other words, is there anyone who successfully make an app with Rust to deploy to apple store?

  13. extrawurst commented on Oct 13, 2021

    @extrawurst

    We have an app using rust In the stores. No Bitcode required unless you want to support Apple Watch so far

  14. fzyzcjy commented on Oct 13, 2021

    @fzyzcjy

    @extrawurst Thank you very much! So if I understand correctly: I just need to disable bitcode, and everything would be fine?

  15. thombles commented on Oct 13, 2021

    @thombles
    Contributor

    If you do want the bitcode for some reason or another, the scripts we maintain at $work continue to function for building iOS apps with bitcode and submitting to the app store, up to Xcode 13. More broadly though I'm not aware of any changes regarding Apple's forks of LLVMs and the difficulty of making this work with mainline Rust development.

  16. fzyzcjy commented on Oct 13, 2021

    @fzyzcjy

    @thombles Thank you!

  17. saks commented on Mar 4, 2022

    @saks

    I've encountered an issue that looks similar:

    ld: Invalid record (Producer: 'LLVM13.0.0-rust-1.59.0-stable' Reader: 'LLVM APPLE_1_1300.0.29.30_0') for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    I'm pretty sure that bitcode is disabled, since it works if I use rust 1.55 (before upgrade to LLVM 12) and xcode project is configured to disable bitcode.
    I'd appreciate if anyone can suggest how to debug this further. Thanks!

  18. bernaferrari commented on Jun 7, 2022

    @bernaferrari

    Bitcode is the future of Apple's app distribution

    Not anymore 😛

    https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes

    Starting with Xcode 14, bitcode is no longer required for watchOS and tvOS applications, and the App Store no longer accepts bitcode submissions from Xcode 14.

    Xcode no longer builds bitcode by default and generates a warning message if a project explicitly enables bitcode: “Building with bitcode is deprecated. Please update your project and/or target settings to disable bitcode.” The capability to build with bitcode will be removed in a future Xcode release. IPAs that contain bitcode will have the bitcode stripped before being submitted to the App Store. Debug symbols for past bitcode submissions remain available for download. (86118779)

  19. jzxchiang1 commented on Jun 18, 2022

    @jzxchiang1

    https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes

    Does that mean we no longer need to use a specialized toolchain like https://github.com/getditto/rust-bitcode, and can instead safely disable bitcode in our XCode app?

  20. bernaferrari commented on Jun 18, 2022

    @bernaferrari

    Yes.

  21. workingjubilee commented on Jul 6, 2022

    @workingjubilee
    Member

    @thombles makes a good point here:

    It's exciting news but let's not count our chickens before they hatch. I'll be happy to make some sort of announcement after we've seen:

    libraries produced by vanilla Rust toolchains working in Xcode 14 GM on physical devices
    successful deployments all the way to TestFlight or the App Store, thereby exercising all of Apple's binary analysis checks

    It should work just fine since the no-bitcode path has been reliable so far, but a lot can happen over the course of an Xcode beta.

    I'd also take "Xcode 15 is announced", on the assumption that if anything goes awry we'll hear about it by then, but if anyone wants to reap this issue before then, they're welcome to it.

  22. jfro commented on Jul 12, 2022

    @jfro

    fwiw we currently ship macOS (non-store) & iOS (TestFlight & Store) with a Rust library driving most of our core functionality. We've never used bitcode since we didn't target any of the previously bitcode requiring platforms.
    We'll be shipping an update in the near future that'll also be built with 14 I believe (think they're accepting 14 builds now...)

  23. thombles commented on Sep 22, 2022

    @thombles
    Contributor

    No surprises really, but I've confirmed that the standard Rust toolchain is working fine all the way to App Store validation using Xcode 14. I've added a notice to rust-bitcode to advise users it's no longer needed. Dare we... close this? :)

  24. nagisa commented on Nov 4, 2022

    @nagisa
    Member

    Closing as per the comment above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.C-enhancementCategory: An issue proposing an enhancement or a PR with one.E-hardCall for participation: Hard difficulty. Experience needed to fix: A lot.O-iosOperating system: iOST-bootstrapRelevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-dev-toolsRelevant to the dev-tools subteam, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions