Rust: Apple AppStoreのビットコードをサポートする

作成日 2016年08月24日  ·  89コメント  ·  ソース: rust-lang/rust

ビットコードはAppleのアプリ配布の未来であり、現在はサポートしていません。 AppleはLLVMの任意のリビジョンを選択し、気まぐれごとにアップグレードするため、これを行うのは難しいです。 LLVMをそれらに結合することはできません。これは、私たち自身のニーズがあり、Appleが決定するたびにアップグレードを強制することができないためです。

ここにいくつかのオプションがあります:

  • Appleビットコードをターゲットにするための完全に別個のツールチェーンを出荷します。 これはかなり醜いです。
  • rustcを変更してLLVMを動的にロードし、rust-llvmパッケージとオプションのrust-llvm-appleパッケージを作成し、rustcにアップルのLLVMをロードしてビットコードを処理させます。
  • rustc_llvm_appleクレートを作成し、2つのLLVM全体を常にrustcにリンクします。 これはおそらく飛ばないでしょう
  • rustc-appleと呼ばれるrustcのビルドを作成し、オプションのrustc-appleパッケージで出荷します。 rustc_llvmにリンクする代わりに、rustc_llvm_appleにリンクすることを除けば、rustcとまったく同じです。 rustcがビットコードを発行するリクエストを受け取ると、rustc-appleバイナリに完全に依存します。 私は実際にこのソリューションをかなり気に入っています。
  • ビットコードサニタイザーを調査して、ビットコードをそれらに変換することができます。 メンテナンスのため、ここで成功する可能性は低いと思います。 RenderScriptがこれを行うと思います。

LLVMの動的ローディングとdefer-to-alternate-rustcソリューションが最も有望だと思います。

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

cc @bluejekyll

A-LLVM A-rustbuild C-enhancement E-hard O-ios T-compiler T-dev-tools

最も参考になるコメント

rustc nightly-2019-09-05 aarch64-apple-ios and rustflags = "-C lto -Z embed-bitcode" staticlibをclang-1100.0.33.5 (Xcode 11 beta 7) and -fembed-bitcodeアプリにリンクすることに成功しました。 ソースコードはhttps://github.com/saturday06/rust-ios-bitcode-testです。

全てのコメント89件

rustcを変更してLLVMを動的にロードし、rust-llvmパッケージとオプションのrust-llvm-appleパッケージを作成し、rustcにアップルのLLVMをロードしてビットコードを処理させます。

LLVMを動的にロードすることは確かにオプションではありません。 LLVM APIはそのビットコードよりも安定性が低く、LLVM xyに対してビルドする場合、xyの代わりにLLVM xzを使用すると、ほぼ確実にrustcが壊れます。 システムLLVMに静的にリンクするだけです( --llvm-rootすでに行っているように)。

rustc_llvm_appleクレートを作成し、2つのLLVM全体を常にrustcにリンクします。 これはおそらく飛ばないでしょう

アップルの配布用にシステムLLVMを(静的に)リンクするだけです。 私の経験では、それはすでにちょっとうまく機能しています。

ビットコードサニタイザーを調査して、ビットコードをそれらに変換することができます。 メンテナンスのため、ここで成功する可能性は低いと思います。 RenderScriptがこれを行うと思います。

わかりました…つまり、LLVMビットコード形式はLLVMのバージョン間である程度安定しているということです。 アップルはそれを真実にしないために何か変わったことをしますか、それとも使用されるビットコード形式はLLVMではありません(つまり、アップル固有のものがあります)?


2013年にずっと聞いたような気がします。配布フォーマットとしてLLVMビットコードを使用するのはばかげていると思います。 私は確かに同意します。 ネイティブバイナリライブラリの配布はiOSでは機能しなくなりましたか?

また、Appleが内部的に互換性のないビットコード形式のLLVMバージョンにアップグレードし、人々がまだ古いコンパイラでコンパイルした場合にどうなるかについても非常に興味があります。

私はこれを簡単に試しました。つまり、貨物のビルド中にビットコードを出力してから、ビットコードを含めて静的ライブラリを作成しようとしました。 ビットコードライブラリに対してllvm-linkを実行しようとすると、ビットコードから互換性のないLLVMバージョンを取得しました。

これを再現する簡単なテストはありませんが、異なるLLVMバージョン間のリンクを拒否するダムバージョンチェックがあるだけだと思いますか? または、私はまったく間違ったことをしました。 これをもう一度見る時間があれば、テストケースを考え出すつもりです。

llvm-linkから正確なエラーメッセージを受け取ると便利です。

@bluejekyll LLVMのテストディレクトリには、多数のビットコードファイルがあります。 これらのビットコードファイルに対するテストは継続的に実行されるため(たとえば、llvm-dis-3.8 / opt-3.8は3.2からの3年前のビットコードファイルを問題なく理解します)、それはアップルのものである必要があります。

アップルの配布用にシステムLLVMを(静的に)リンクするだけです。 私の経験では、それはすでにちょっとうまく機能しています。

これは言うよりもやや簡単です-私が知る限り、App Storeアップロード用の唯一の祝福されたapple-llvmバージョンは、現在のXcodeに付属しているものです。 これは、2つのLLVMバージョン(必ずしも2つの隣接するマイナーバージョンでもない)のLLVMバインディングを維持することも意味する可能性があります。 古いバージョンのapple-llvmを使用するだけでは有効ではないと思います。

また、Appleが内部的に互換性のないビットコード形式のLLVMバージョンにアップグレードし、人々がまだ古いコンパイラでコンパイルした場合にどうなるかについても非常に興味があります。

最新のXcodeにアプリの送信のみを許可することで、これを回避していると思います(そして、使用したLLVMバージョンの出力イメージに焼き付けられていると確信しています)。

IIRC、ビットコードはアーキテクチャごとにパッケージ化されています。これは、アーキテクチャ間のビットコードがclangによって生成されないためです(これは、一般的にclangとビットコードの反目標だと思います)。 各オブジェクトファイルのセクションに保存されるため、少なくとも複製されます。 これは、ビットコードがこれを行うための最良の方法ではない可能性があると誰かが述べた理由の一部である可能性があります。

推奨されるすべての解決策がやや厄介だと少し感じます。 私が考えることができる最も厄介な方法は、さまざまなターゲットがcodegenの動作をオーバーロードし、Applecodegenパスを動的なクレートに入れることを許可することです。 (これは、apple-llvmに対してコンパイルされた通常のcodegenパスになります。)

このバグはAppStoreに言及しているので、ここで例外処理の話をする価値がありますか? (つまり、現時点ではpanic=abortが厳密に必要です。)

LLVMのテストディレクトリには多数のビットコードファイルがあります。 これらのビットコードファイルに対するテストは継続的に実行されるため(たとえば、llvm-dis-3.8 / opt-3.8は3.2からの3年前のビットコードファイルを問題なく理解します)、それはアップルのものである必要があります。

@nagisaこれを知らせてくれてありがとう。 ここにはまだ解決策があるかもしれないし、おそらく何か間違ったことをしているのではないかという希望を私に与えてくれます。

@ ricky26良い点。

私の知る限り、App Storeアップロード用の唯一の祝福されたapple-llvmバージョンは、現在のXcodeに付属しているものです。

Apple上のXcodeLLVMは、システムLLVMと同じものではありませんか? その時、私はXcodeLLVMを意味しました。 rustcトレインを出荷するときは、xcodeが常に最新バージョンであることを確認する必要があります。

もちろん、アップルのやり方は、古いバージョンのrustcで有効なアップルビットコードを作成することを除外し、基本的に、安定性の話が提供するすべての利点を窓の外に投げ出すことを強制します。これを修正できる方法はありません。

これは、2つのLLVMバージョンのLLVMバインディングを維持することも意味する可能性があります

LLVMバージョン3.7から3.9(および場合によってはトランク)のサポートはすでに維持されています¹。 XcodeのLLVMが古いバージョンでない限り、私たちはその点で優れていると思います。 Xcode LLVMが実際に古代/カスタム/その他のバージョンである場合、この機能をサポートできるとは思えません。 特に、必要な機能を追加するために_that_LLVMにパッチを送信するオプションがないためです。 また、Appleが2038年までXcode LLVMを更新しないことを決定した場合に備えて、rustcを3.7のサポートに永久に固定したくありません。

¹:ただし、rustcがLLVM xyに対して構築されている場合は、LLVMxyに正確にリンクする必要があります。

LLVMを動的にロードすることは確かにオプションではありません。 LLVM APIはそのビットコードよりも安定性が低く、LLVM xyに対してビルドする場合、xyの代わりにLLVM xzを使用すると、ほぼ確実にrustcが壊れます。 システムLLVMに静的にリンクするだけです(--llvm-rootがすでに行っているように)。

@nagisa C ++ APIは不安定ですが、C APIを使用しており、一度に複数のバージョンのLLVMをサポートすることに多くの成功を収めています。 APIサポートの点で違いはわかりません。

アップルの配布用にシステムLLVMを(静的に)リンクするだけです。 私の経験では、それはすでにちょっとうまく機能しています。

すべてのAppleプラットフォームにAppleのLLVMを包括的に出荷することもできますが、これは、デスクトップマシンコードの生成でもLLVMをAppleに結合することを意味し、Apple以外のホストでiOSビットコードをサポートするオプションを排除します。

わかりました…つまり、LLVMビットコード形式はLLVMのバージョン間である程度安定しているということです。 アップルはそれを真実にしないために何か変わったことをしますか、それとも使用されるビットコード形式はLLVMではありません(つまり、アップル固有のものがあります)?

ビットコード形式はバージョン間で安定していません。

ネイティブバイナリライブラリの配布はiOSでは機能しなくなりましたか?

今日は機能します。 これは推奨される方法ではなく、引き続きサポートされるかどうかは明らかではありません。

これは、2つのLLVMバージョン(必ずしも2つの隣接するマイナーバージョンでもない)のLLVMバインディングを維持することも意味する可能性があります。 古いバージョンのapple-llvmを使用するだけでは有効ではないと思います。

@ ricky26いくつかのバージョンのLLVM間の互換性を正常に維持しています。 Appleと私たちがあまり離れていない限り、それは実行可能であるはずですが、分割を超えることができないほど大きな破損のリスクが常にあり、APIの大きな変更が来ることを私は知っています。

XcodeのLLVMが古いバージョンでない限り、私たちはその点で優れていると思います。

このページからhttps://gist.github.com/yamaya/2924292

clang-700.0.72 => LLVM 3.7.0
clang-700.1.76 => LLVM 3.7.0
clang-700.1.81 => LLVM 3.7.0
clang-703.0.29 => LLVM 3.8.0
clang-703.0.31 => LLVM 3.8.0

C ++ APIは不安定ですが、C APIを使用しており、一度に複数のバージョンのLLVMをサポートすることに多くの成功を収めています。 APIサポートの点で違いはわかりません。

それは真実ではありません。 rustllvmの形式でC ++ APIへのバインディングが多数あります(かなり大きいです!)。 コンパイル対象のLLVMのバージョンに応じて、そのラッパーをコンパイルする場合がいくつかあります。 使用およびコンパイルされたLLVMのバージョンが一致しない場合、動的リンカーエラーが発生するか、さらに悪いことに、実行時に問題が発生します。

Apple以外のホストでiOSビットコードをサポートするオプションを除外します。

AppleがLLVMのフォーク以外で生成されたビットコードを取得したくない場合は、同様のフォークを維持し、内部パッチをリバースエンジニアリングする以外に、ここで何ができるかわかりません。

ビットコード形式はバージョン間で安定していません。

もちろんですが、たとえば3.7.0と呼ばれるLLVMのさまざまなリビジョン間のビットコードは、3.7.0シリーズのLLVMの別のビルドで使用するビットコードを生成するために十分な互換性があると想定するのはかなり公正です。 libLLVMに動的にリンクするよりも確かに優れています。

¹:特に、3.2シリーズのビットコードは、非常に小さな標本であっても、3.8LLVMと互換性があります。

いくつかのメモ:

  • Xcodeには、リンク可能なlibLLVM(静的または動的)は付属していません。LLVMに静的にリンクするlibclang.dylibのみが付属しています。
  • Appleは、 https: //opensource.apple.comの「DeveloperTools」の下にある「clang」(LLVMを含む)にソースを出荷してい
  • ストーリーは、リリースタグ付きのLLVMの独自のフォークを備えたSwiftの方が良いかもしれませんが、Xcodeに付属しているものと完全には対応していない可能性があります。 (Xcodeでオープンソースのツールチェーンスナップショットを使用することは可能ですが、そのようなツールチェーンで構築されたプロジェクトをApp Storeに送信することはできません。)

cc @ rust-lang / compiler

他のプログラミング言語がこれに対処するためにどのように計画しているのか知りたいと思います。 特にモノと行く。

この問題に対するUnityの答えはil2cppです-すべてのILアセンブリをC ++コードにビルドします。

関連するgolangのバグ: https

全体として、Apple以外のビットコードサポートの話は貧弱です。

モノラルプロパーはアップルLLVMを経由して表示されます: http

1つの障害は、ビットコードでインラインアセンブリを実行できないことです:(

モノストーリーについては、モノが好奇心旺盛な人のために何をするかについて、ミゲル・デ・イカザと簡単に交換しました: https

@mitsuhiko何らかの理由で、iOSとtvOSではビットコードでインラインアセンブリを使用できますが、watchOSでは使用できません。

これに関する動きはありますか? 私は、ビットコードをサポートする計画がなければ、iOSでRustを使用することにまったく満足していません。 Appleには、このようなオプションのものをかなり突然作成した歴史があり、実際、watchOSとtvOSではすでにビットコードが必要です。

推奨されるすべての解決策がやや厄介だと少し感じます。 私が考えることができる最も厄介な方法は、さまざまなターゲットがcodegenの動作をオーバーロードし、Applecodegenパスを動的なクレートに入れることを許可することです。 (これは、apple-llvmに対してコンパイルされた通常のcodegenパスになります。)

このアプローチ(@ ricky26による)は、rustcユーザーとして私にとって最も自然なようです。

少なくとも私の知る限り、これに関して最近何も変わっていないと思います。 バージョニングに関するLLVMの最近の発表で、彼らはビットコードが(私が思うに)LLVMの将来のバージョンによって常にロード可能であるべきであることを示しました。 これ、この問題が基本的なレベルで「解決」されている場合がありますが、すべてのビットコードを抽出するには、より人間工学的なインターフェイスが必要です。

これに関する更新はありますか?

HackerNewsに関するこのコメント投稿者は、macOSおよびiOSでRustから生成されたビットコードを使用することに成功しました。 スレッドには、錆びたバイナリのビットコードを有効にする方法に関する詳細な情報があります。これは素晴らしいニュースのようです。

https://news.ycombinator.com/item?id=14305084

問題のコメント投稿者として、簡単なメモ:

  • -C lto --emit llvm-bcを使用して、rustcに現在のクレートとすべての依存関係を含む1つの.bcファイルを出力させました。 これは機能しますが、本質的にはハックです。 特に、jemallocを含むCの依存関係では機能しません(ただし、iOSでは使用されません)。 rustcが「埋め込みビットコード」を使用したMach-Oの発行を適切にサポートしているとよいでしょう。 clangソースを見て、それがどのように行われるかを確認できます。

  • あなたがそれを試してみて、ハックを気にしないのであれば、バージョンの問題を除いて、それは「うまくいく」ようです:

  • 主な実際的な障害は、RustがXcodeよりも頻繁にLLVMトランクと同期することです。これは、毎年しか同期しないようです。 新しいバージョンのLLVMは古いビットコードをロードできますが、その逆はできません。そのため、古いバージョンのrustcを使用するか、古いLLVMに対して最新のバージョンをビルドする必要があります。 (実際、rustc1.17はXcode8.xでも機能するようですが、LLVM 4.0のアップグレード以降、毎晩ではありません。それは偶然です。)

  • 理想的には、Rustは適切なLLVMバージョンに対して構築された公式バイナリを出荷します。 実際には、正しいバージョンのストックLLVMを使用するのは問題ないようですが、Appleのフォークを使用する場合は次のようにします。

    • 以前のコメントで述べたように、XcodeはLLVMバイナリを動的であってもリンク可能な形式で出荷しません。 clangとlibclang.dylibのみ(Clang APIをエクスポートしますが、LLVM APIはエクスポートしません)。
    • しかし、私も言ったように、ソースコードは通常opensource.apple.com(Developer Tools-> clangの下。アーカイブにはすべてのLLVMが含まれています)に、多少一貫性がないか、遅れて表示されます。 ただし、特に@alexcrichtonによって示される拡張された下位互換性の保証を

(テストとして、Xcode 8.2.1 Clangに対してRustをコンパイルしようとしました。 #if LLVM_VERSION_GE(..)条件付きのネストが両方に対してコンパイルできるようにするため、 rustllvmはビルドに失敗します。古いLLVMと新しいLLVMは、このブランチによって混乱します。これはLLVM 3.9svnであると主張していますが、APIに関しては3.8から3.9の間のどこかにあります。Xcodeはとにかく来年の更新がほぼ予定されているため、おそらく修正する価値はありません。)

この面で何か進展はありましたか? あるいは、あなた(コアチーム)は、この試練を確実な恒久的な修正が見込まれる問題と見なしますか、それともこのバージョンのホッピングが予見可能な将来にわたって残ると思いますか?

優れた型システムと低レベルのセマンティクスのためにiOSアプリの一部をRustに実装することを検討しており、Xcodeまたはrustcのいずれかが更新されるたびに、非ビットコードや通常のハッキング/遅延にとらわれたくないと考えています。

@regexident

他の理由で、スワップ可能なLLVMバージョンを実装する予定だと思います。 それが実装されていれば、Apple、wasm、その他すべてに別々のトランスを出荷するのに問題はないはずです。

cc#45684

Appleのビットコードはまだ本当に危険ではありませんhttps://medium.com/@FredericJacobs/why-im-not-enabling-bitcode-f35cd8fbfcc5ビルドを検証することは不可能です。 暗号化の問題。 等

@burdges特定のアプリでは、これは絶対に問題です。

しかし、watchOSとtvOSの場合、Appleは実際にAppStoreの提出にビットコードを必要とします。 選択の余地はありません。 「これらのプラットフォームで暗号化や重要なことを行わない」以外。 また、将来のある時点でAppleがiOS用のビットコードを施行することを恐れる必要があります。 その時点では、レンガの製品は使いたくありません。

-C lto --emit=llvm-bcトリックを使用してiOS用のRust 1.24.0でビルドしようとしましたが、リンカーで次のエラーが発生しました。

Undefined symbols for architecture x86_64:
  "_backtrace_create_state", referenced from:
      std::sys_common::gnu::libbacktrace::init_state::h686c3e443c712b0f in Logger(x86_64.o)
  "_backtrace_syminfo", referenced from:
      std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h598a932d5bb0d80b in Logger(x86_64.o)
      core::iter::iterator::Iterator::position::_$u7b$$u7b$closure$u7d$$u7d$::hbf03153d55553502 in Logger(x86_64.o)
  "_backtrace_pcinfo", referenced from:
      std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::h598a932d5bb0d80b in Logger(x86_64.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

問題になる可能性のあるアイデアはありますか?

編集:各public extern fnのすべてのコードをAssertUnwindSafeラップすることで、少なくともその問題を抑制できるようです。

libbacktraceは、Rustソースツリーに含まれているCライブラリです。

https://github.com/rust-lang/rust/tree/master/src/libbacktrace

どういうわけかそれをビットコードとしてコンパイルする必要があります。

自分のラップトップ用に構築されたlibbacktraceしか見つからず、電話のOS用には見つからないため、混乱しています。 rustはこれらのシンボルをstdlibにどのように挿入しますか? どういうわけかバックトレース機能を無効にすることで、これを行う簡単な方法はありますか? RUST_BACKTRACE env varを削除しましたが、役に立ちませんでした。 バックトレースなしでrustcをコンパイルできることを読みましたが、プロジェクトのcargo.tomlファイルなど、もっと簡単なものを望んでいました。

基本的には、Cコンパイラに-fembed-bitcodeを渡すように指示しながら、rustcソースツリーを構築する必要があります。 理想的には、それをCFLAGSに追加することができます。 残念ながら、私はそれを試しましたが、 gcc-rs (Cの依存関係をビルドするためにrustcのビルドシステムによって使用される)に関する2つの問題のために正しく機能しませんでした。 しかし、私はそれを少しハッキーな手順で動作させることができました:

cd /tmp/build
cat >ccwrap.py <<END

#!/usr/bin/env python
import os, sys
os.execv('/usr/bin/xcrun', ['clang', '-fembed-bitcode'] + [arg for arg in sys.argv[1:] if arg not in {'-ffunction-sections', '-fdata-sections'}])

END

chmod 755 ccwrap.py
ln -s /usr/bin/ar ar
export CC_aarch64_apple_ios=`pwd`/ccwrap.py
/usr/src/rust/configure --target=aarch64-apple-ios
make

これにより、ビットコードが埋め込まれたlibbacktrace.a./build/aarch64-apple-ios/native/libbacktrace/.libs/ )が表示されます。 __LLVM,__bitcodeに埋め込むことです。 clangと同じように、ネイティブライブラリの

(実際、引用したエラーは通常のリンカーエラーのように見えるので、通常のビットコードが埋め込まれていないlibbacktrace.aをリンクするだけで、それを乗り越えることができると思います。しかし、せいぜい出力ファイルになります。埋め込まれたビットコードが壊れています。)

前述の問題:

  • gcc-rsは-ffunction-sections-fdata-sectionsを渡しますが、それらをオフにする方法はありません。 clangは、 -fembed-bitcodeと組み合わせると、これらについて不平を言います( -fno-function-sectionsが後で渡された場合でも)。

問題レポートを提出しましたが、回避策として、上記の手順では、これらの引数を取り除くラッパースクリプトを使用しています。 しかし、それは2番目の問題を引き起こしました:

  • gcc-rsは、 CC_aarch64_apple_ios (!?)と同じディレクトリでarを見つけようとします。 AR_aarch64_apple_ios手動で設定しても効果はありません

最新のcc-rsgcc-rsから名前が変更されました)ではこれを再現できなかったため、問題を提起しませんでした。 回避策として、上記の手順はarを同じディレクトリにシンボリックリンクします。

提案をありがとう! 私は実際には、バックトレースのものではなく、自分のコードにビットコードが必要だったので、ビットコードを埋め込まずにコンパイルされたlibbacktraceを使用しました

私が試したハックで、別の問題が発生しています。dSYMを作成しようとすると、dsymutilsegfaultsが発生します。 dSYMを使用しない通常の実行は正常に機能しますが、何らかの理由でdSYMの作成が失敗します。 libbacktrace.aを削除し、空のプレースホルダー関数に置き換えましたが、問題なく動作したため、rustlibに問題があるようです。

これはdsymutilのバグのように聞こえますが、LLVMのアップストリームに報告する必要があります。 LLDBでdsymutilを実行し、クラッシュのバックトレースを投稿してみてください。 または、より良いデバッグ情報を取得するには、デバッグモードでLLVMをビルドし、それを使用して再現してみてください。

(ストックLLVMインストールのバイナリはllvm-dsymutilと呼ばれますが、最近のXcodeのdsymutilllvm-dsymutilへのシンボリックリンクにすぎないことに注意してください。 dsymutil以前は別のクローズドソースユーティリティですが、数年の間、そのバージョンはdsymutil-classicとして出荷され、デフォルトでは使用されていません。)

@comexは好奇心から、 ccクレートはすべて-fembed-bitcodeコンパイルする必要がありますか? または、「公式」clangを使用している場合、ビットコードの埋め込みを避けても大丈夫ですか?

(申し訳ありませんが、iOSのベストプラクティスに精通していません!)

Rustコード自体については、オブジェクトファイルの代わりにバイトコードを出力するのが最善でしょうか? それはClang /リンカーが理解できるものですか?

@alexcrichton

ccクレートはすべて-fembed-bitcodeコンパイルする必要がありますか? または、「公式」clangを使用している場合、ビットコードの埋め込みを避けても大丈夫ですか?

公式のclangを使用しても、埋め込まれたビットコードが不要になるわけではありません。 むしろ、ビットコードは、ネイティブコードに加えて、Appleにアップロードされたアプリアーカイブに含まれます。その後、Appleは、たとえばさまざまなマイクロアーキテクチャ用に最適化するために、サーバー側でビットコードを再コンパイルできます。

iOS / watchOS / tvOSでは、デフォルトで-fembed-bitcodeを渡すのがおそらく理にかなっています。 その場合、デバッグモードでビルドするときは、 -fembed-bitcode-markerを渡す必要があります(代わりに、またはそれに加えて、関係ありません)。 これにより、実際のビットコードではなくダミーのビットコードセクションのみを含めるようにclangに指示されます。これは、埋め込まれたビットコードは最終的なアプリアーカイブにのみ必要であり、コンパイルをわずかに高速化して省略できるためです。 実際、Xcodeは最終的なアプリアーカイブの構築以外のすべてに-fembed-bitcode-markerを渡しますが、たまたま最適化が行われている開発ビルドでも、 ccは「本当に最終的なリリース」という別の概念がありません。モード」、それはおそらくデバッグモードでそれを渡す必要があります。 最終ビルドでビットコードが必要ない場合でも、ビットコードを埋め込んでも安全であることに注意してください。

Rustコード自体については、オブジェクトファイルの代わりにバイトコードを出力するのが最善でしょうか? それはClang /リンカーが理解できるものですか?

clangとldはどちらも、入力として渡される生のビットコードファイルをサポートしています。 これは通常、LTOが有効になっている場合( -flto )に使用されます。この場合、clangが生成する.oファイルは実際にはMach-Oではなく生のビットコードです。 (これらは、通常のlipoコマンドを使用して静的ライブラリに形成できます。)ただし、これは、ビットコードが__LLVM,__bitcodeセクションに詰め込まれたMach-Oで構成される「埋め込みビットコード」形式とは別のものです。通常のセクションのネイティブコードに追加します。 この形式は、LTOがオフの場合のオブジェクトファイル、およびLTO設定に関係なく最終的にリンクされた実行可能ファイルまたはダイナミックライブラリで使用されます。 (LTOがオンの場合、リンカーはこのセクションの作成を担当します。LTOがオフの場合、リンカーは、単一の結合を生成するのではなく、他のセクションの場合と同様に、各オブジェクトファイルの__LLVM,__bitcodeセクションを単純に連結します。ビットコードモジュール。 )編集:実際には、少し複雑なことを行い、ビットコードセクションのxarアーカイブを生成し、それらを__LLVM,__bundleという名前のセクションに配置します。 とにかく、私たちが気にしなければならないことではありません。

理想的には、rustcは、生のビットコードではなく、iOSでデフォルトで「埋め込みビットコード」を生成する必要があると思います。 実行するのはそれほど難しくなく、インクリメンタルコンパイルの中断を回避します-特に、ダミーのビットコードセクション( -fembed-bitcode-marker )を生成できるデバッグモードでは、リンカーがオブジェクトを詰め込むだけなので、リリースモードでも可能です'リンク時に高価なことをするのではなく、ビットコードセクションを一緒に。

clangが埋め込みビットコードを生成する方法は次のとおりです。

https://github.com/llvm-mirror/clang/blob/master/lib/CodeGen/BackendUtil.cpp#L1242

比較的単純です-バックエンドを呼び出す前に、現在のLLVMモジュールをビットコードとしてダンプしてから
__LLVM,__bitcodeセクションに配置された新しいグローバル変数(同じモジュール内!)にバイナリデータとして詰め込みます。 一種のハッキーなデザインのように見えますが(フロントエンドがこれを手動で行う必要があるのはなぜですか?)、rustcで再現するのはそれほど難しくないはずです。

@comexのアプローチは理にかなっていますが、このような変更を検討しているときに、Appleのclangをバックエンドとして使用する理由があると思います(私が作成した#48833を参照)。 また、埋め込まれたビットコードから自分自身をコンパイルするのはどれくらい簡単ですか?

@michaeleiselsc申し訳ありませんが、「埋め込まれたビットコードから自分自身をコンパイルする」とはどういう意味かわかりません。

のように、ビットコードが埋め込まれたバイナリをApp Storeに提供するだけでなく、Appleclangを使用してビットコードを取得して構築することにもメリットがあります。 私が興味を持っている2つの利点は、Apple clangが持つダウンストリームの修正と、カバレッジサニタイザーなどのclangサニタイザーを使用できることです。

@comexわかりました。少し掘り下げてみると、rustcでの実装は(比較的)簡単なようですが、いくつか質問があります。

  • なぜ-fembed-bitcode-markerが問題なのですか? clangをローカルで使用すると、空のstaticがセクションに出力されます。 それは、セクションの単なる存在が何かを意味することを意味しますか? セクションがない場合、iOSの道に沿ったいくつかのツールが壊れますか? (しかし、それは空なので、実際にはセクションの内部を見ていませんか?
  • __cmdlineセクションが必要かどうか知っていますか? -fembed-bitcodeも、何らかの形式のコマンドラインをバイナリに埋め込んでいるようです。 おそらくrustcのコマンドラインではないので、ここに何を入れるかはよくわかりませんが、ツールはこれを調べますか? -fembed-bitcode=bitcodeをiOSで使用すると、コンパイルが中断しますか?
  • そして最後に、これを無効にしたい理由はありますか? それとも、iOSターゲットに対してこれを無条件に有効にして、先に進む必要がありますか?

-fembed-bitcode-markerが重要なのはなぜですか?

何かがビットコードを使用することになっているが、ビットコードは実際にはコンパイルされていないことを示すためにxcodeによって使用されていると思います。 後でそのようなプロジェクトをアーカイブしようとすると、ldはエラーで失敗します。

これを常に有効にするかどうかという質問に対しては、注意したい場合が確かにあります。 たとえば、誰かがそれをHockeyAppのようなベータアプリ配布プラットフォームに送信した場合、HockeyAppはそのビットコードセクションを削除しますか、それともベータテスターは必要以上に大きなバイナリをダウンロードする必要がありますか?

@mitsuhikoうん、実際にビットコードを必要としないビルドのテストを現在行っている場合でも、リンカーはビルドがビットコード用に適切に設定されていることを確認できるという考えです。

たとえば、ビットコードに言及せずにCファイルをコンパイルし、それを-fembed-bitcode-markerとリンクしようとすると、次のようになります。

$ clang -c -o test.o test.c
$ clang -dynamiclib -o test.dylib test.o -fembed-bitcode-marker
ld: warning: all bitcode will be dropped because 'test.o' was built
without 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.

最初の行でも-fembed-bitcode-markerを渡すと、警告は消えます。

@alexcrichton __cmdline …うーん…リンカーがそれを存在させる必要があるようです(「ビットコードの作成」を検索してください):

https://opensource.apple.com/source/ld64/ld64-274.2/src/ld/parsers/macho_relocatable_file.cpp.auto.html

しかし、実際の価値を気にするものは何も見当たりません。おそらくそこにダミー値を置くのが最善でしょう。

この問題は#48896をマージすることで解決しましたか?

私はナイトリービルドでこれをいじっていますが、Xcodeでアーカイブしようとするまではうまく機能します。 Rust静的ライブラリの出力にfembed-bitcode-markerを追加しているようですが、fembed-bitcodeは追加していないようです。 cargo lipo --releaseでコンパイルされています。

$ cargo --version
cargo 1.27.0-nightly (af3f1cd29 2018-05-03)
$ cargo lipo --version
cargo-lipo 2.0.0-beta-2
$ rustc --version
rustc 1.27.0-nightly (565235ee7 2018-05-07)
ld: '/Users/chrisbal/Documents/Beach/rust-universal-template/target/universal/release/libexample.a(example_generic-be72fb1769c1779b.example_generic6-152d14edfb6970f54250733c74e59b7.rs.rcgu.o)' 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 arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

otool -arch arm64 -l /Users/chrisbal/Documents/Beach/rust-universal-template/target/universal/release/libexample.a | grep bitcodeを実行すると、 sectname __bitcodeがたくさん表示されますが、これがマーカーだけでなく実際のビットコードであるかどうかを確認する方法がわかりません。

ネストされたクレートを使用しているので、内部の「汎用」クレートがビットコードフラグを取得していない可能性がありますか?

編集:これが問題を示すリポジトリですhttps://github.com/Raizlabs/rust-universal-template/tree/879e74​​12d729e8963586c5b083d51b09733aec32

@chrisballinger 、追加のフラグで動作します。を参照してください。
RUSTFLAGS="-Z embed-bitcode" cargo lipo --release

$ cargo --version
cargo 1.28.0-nightly (f352115d5 2018-05-15)
$ cargo lipo --version
cargo-lipo 2.0.0-beta-2
$ rustc --version
rustc 1.28.0-nightly (952f344cd 2018-05-18)

しかし、arm7archに対してのみ別のコンパイルエラーがあります。

.rs.rcgu.o)' 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

arm7 archを修正する方法を知っている人はいますか?

残念ながら、それも機能させることができず、 @ chrisballingerと同じエラーが発生し

ld: '/sandbox/target/universal/release/librgame.a(std-da6dba40351cda22.std3-d36cd881bae00a8b5fc36289b5737f78.rs.rcgu.o)' 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 arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

私はそれをコンパイルしようとしたRUSTFLAGS="-Z embed-bitcode" cargo lipo --releaseとのそれを設定する.cargo/config 。 ただし、フラグを追加します。

` Executing: "cargo" "build" "--target" "x86_64-apple-ios" "--lib" "--features" "" "--color" "auto" "--release" "--verbose" Compiling libc v0.2.42 Compiling rand_core v0.2.1 Running `rustc --crate-name libc /Users/aleksandrivanov/.cargo/registry/src/github.com-1ecc6299db9ec823/libc-0.2.42/src/lib.rs --crate-type lib --emit=dep-info,link -C opt-level=3 --cfg 'feature="default"' --cfg 'feature="use_std"' -C metadata=dce309634355ac97 -C extra-filename=-dce309634355ac97 --out-dir /Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/x86_64-apple-ios/release/deps --target x86_64-apple-ios -L dependency=/Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/x86_64-apple-ios/release/deps -L dependency=/Users/aleksandrivanov/Sandbox/Projects/tetris/rgame/target/release/deps --cap-lints allow -Zembed-bitcode` ...

ここに更新はありますか? 私たちのアプリの共有コアライブラリを慎重に検討し、この修正されたc ++がない場合はおそらくオプションです。

@ chrisballingerhttps://github.com/rust-lang/rust/issues/52686に関連付けることができ

@volodgいいえ、この問題は少し前のものです。

#48896のマージで、それは箱から出して動作することになっていますか?

私は1.29.1を使用していますが、オブジェクトにはまだデフォルトでビットコードが埋め込まれていません。 @volodgで前述したように、 RUSTFLAGS="-Z embed-bitcode"を使用してそれらを埋め込むために錆びることがあります。 しかし、私が経験したことから、Rust自身のライブラリ(compiler_builtins、std)がembed-bitcodeでコンパイルされていないという問題が発生します。 おそらく、embed-bitcodeを使用してxargoを使用してiOSターゲットを再構築することは機能しますが、私は試しませんでした。

私はあなたが提案したようにxargoを使おうとしましたが、問題はまだここにあるようです:(

このXargo.toml

[dependencies]
std = {}
[target]
features = ["jemalloc"]

また、これをCargo.toml追加します:

[profile.release]
panic = "abort"

これらすべてのターゲットに対してxargo build --release --target $TARGETを使用してコンパイルしました。

  • aarch64-アップル-ダーウィン
  • armv7-apple-darwin
  • armv7s-apple-darwin
  • i386-アップル-ダーウィン
  • x86_84-アップル-ダーウィン

次に、 lipoを使用して1つの静的ライブラリを作成しました。

まだリンカーエラーがあります:

ld: '../../cargo/target/universal/libgreetings.a(greetings-ceeec73d35f7dbe0.greetings.9kcaav8v-cgu.2.rcgu.o)' 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 arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

xargoパスでもう少し進んだ。

私のXargo.toml

[dependencies]
std = {}

私のCargo.toml

[profile.release]
panic = "abort"

必要かどうかはわかりませんが、xargo docから、lib.rsに追加したextern crate compiler_builtinsを明示的に使用する必要があります。

次に、 RUSTFLAGS="-Z embed-bitcode" xargo build --target $TARGET --releaseを使用してコンパイルしました。 core / std / compiler_bultinsをビルドすることを確認してください。 xargo cleanは、以前のビルドを私が経験したものから正しくクリーンアップしないため、さまざまなXargo.toml調整を試みたときに、stdを再コンパイルするためにrm -rf ~/.xargoが必要Xargo.toml

しかし、Xcode 10でアーカイブすると、次のようになります( armv7リンクで):

Intrinsic has incorrect argument type!
void (i8*, i8, i32, i1)* @llvm.memset.p0i8.i32
Intrinsic has incorrect argument type!
void (i8*, i8*, i32, i1)* @llvm.memcpy.p0i8.p0i8.i32
Intrinsic has incorrect argument type!
...
(lots of it)
...
LLVM ERROR: Broken module found, compilation aborted!
clang: error: linker command failed with exit code 1 (use -v to see invocation)

バグがLLVM側に依存しているということですか?

編集:この問題を進めるためにどのように役立つことができますか?

最近誰かがこれを試しましたか? armv7が最大の問題のようですか?

皆さんこんにちは。 私はしばらくこのスレッドをフォローしていて、AppleビットコードがRustでサポートされているのを見てとても興奮しています。 これまでに誰かがこの仕事をすることができましたか? 現在不足しているものと、どのように支援できますか?
ありがとう!

この問題を数時間探し出した後、Rustのビットコード埋め込みがXcodeで機能しない理由を見つけました。 簡単に言えば、XcodeのLLVMバージョンはLLVM 6.0ビットコードを期待しているのに対し、Rustは2018年7月にLLVM7.0にバンプしました。

さて、長い答え...

LLVM 7.0の変更ログでわかるように、 @llvm.memcpy@llvm.memmove 、および@llvm.memset署名が変更され、Xcodeビルドエラーは、見られるように間違った引数タイプについて明確でした。私の以前のコメントで

ちなみに、Kotlin Nativeは2018年10月にembed-bitcodeのサポートを追加し、Xcodeでは正常に機能しているようです。 その理由は、Kotlinはまだ使用していることであるLLVM 6.0を

それを見て、7.0にバンプする前に古いバージョンのRustを使用してコンパイルしようとしました。 nightly-2018-06-01-x86_64-apple-darwinで試してみましたが、成功するとコンパイルされます。

また、Xargoを使用せずにコンパイルしようとしましたが成功しませんでした。 すべての依存関係は、ビットコード埋め込みを使用してコンパイルする必要があります。

つまり、AppleがLLVMバージョンを発表しない限り、すぐに組み込みビットコードのサポートが見られるとは思わない...誰かが組み込みビットコードを6.0のビットコードに変換する賢い方法を見つけない限り...

@appaquetそれの底に到達していただきありがとうございます! それは私にとってかなり謎でした、そして私はあなたがしたほど深く潜るつもりはなかったと思います。 AppleがLLVMバージョンをバンプすると、動作を開始する可能性が高いことを知っておくとよいでしょう。

明確な回答をありがとう@appaquet 。 今、私たちは正しいことをするためにアップルに頼る必要があると思います

モバイル向けのマルチプラットフォームに関心があり、有望なソリューション(React Native、Flutter、Kotlin / Native、Rust)のほとんどを比較した人からのサイドビュー

リアクトネイティブ。 基本的にブリッジはC ++で記述されており、実行時にJSコ​​ードを解釈しているだけなので、最初からビットコードをサポートします。

フラッター。 まだビットコードをサポートしていません-https ://github.com/flutter/flutter/issues/15288

Kotlin / Native。 JetBrainsはモバイルプラットフォームを優先事項と見なしており、しばらく時間がかかり、ビットコードマーカー(完全なビットコードではありません)のみですが、作業を開始するのに十分です-https ://github.com/JetBrains/kotlin-native/を参照してhttps://github.com/JetBrains/kotlin-native/issues/1202#issuecomment-444022513

さび。 Appleはバージョン6を使用しているのに対し、LLVM7のビットコードをサポートしています。

ビジネスロジックとUIクロスプラットフォームの両方が必要な場合は、ReactNativeまたはFlutterを使用します。 しかし、多くの深刻なアプリにとって、このパスはリスクが高すぎます。 React Nativeは十分なパフォーマンスを発揮せず、APIと依存関係の安定性問題になります(v1.0が登場する予定はありますか?)。 フラッターは少し未熟ですが、ますます牽引力を獲得しているようです。

ある種のモジュールでビジネスロジックのみを共有し(以前の大きなアプリがC ++およびJNI / Obj-C ++で行ったように)、真にネイティブなUIを上に構築したい場合、最初は4つすべてから選択できます。 次に、React Nativeを取り消します。これは、本格的なJavaScriptCoreとブリッジを使用してJS <-> Native間でビジネスロジックを実行するのは少しやり過ぎのようです(このブリッジの初期化にもかなりの費用がかかります)。 Flutter使用できる可能性がありますが、意図されているわけで
RustとKotlin / Nativeはどちらもこのニッチを目指しており、適切なツールを備え、ネイティブバイナリを生成します(パフォーマンスとフットプリント!)。 ビットコードは、モバイルプラットフォームでマルチプラットフォームモジュールを構築するための言語としてRustを採用したい人にとって大きな問題です。 そして今、Kotlin / Nativeには利点があります。

iOS開発者にとってビットコードが非常に重要である理由を要約すると。 tvOSやwatchOSには何も書き込めません。 バイナリとして配布されている多くのサードパーティフレームワークでは、ビットコードが有効になっています(数十の例、頭のてっぺんからGoogle IMA-最も人気のあるビデオ広告)。 一部のセキュリティ監査ではそれが必要です。 そして最後に、Appleが「来年から、完全に埋め込まれたビットコードのないアプリはもう受け入れない」と言うときはいつでも、誰もが時を刻むタイマーを手に入れる。

今、私たちは正しいことをするためにアップルに頼る必要があると思います

ええ、そうです、これはAppleが悪名高いものです;)
最善の解決策はわかりませんが(一時的にLLVM 6にダウングレードすることはできませんよね?)、RustはiOSとモバイルのクロスプラットフォーム開発者を完全に失っています。

この詳細な説明@ oleksandr-yefremovをどうもありがとうございました。 私はこのテーマについて少し読んでいて、この興味深いコメントを見つけました: https ://gist.github.com/yamaya/2924292#gistcomment -2738480

LLVMのバージョンは、XCodeで使用されるSwiftのバージョンに関連付けられています。 これまでのところ、次のサポートが適用されています。

Xcode 8.3  --> swift 3.1 --> llvm 4.0.0
Xcode 9.0  --> swift 4.0 --> llvm 4.0.0
Xcode 9.3  --> swift 4.1 --> llvm 5.0.2
Xcode 10.0 --> swift 4.2 --> llvm 6.0.1

swift-5.0-branchを見ていると、その中で宣言されているLLVMのバージョンが7.0.0であることに気付きました: https

ここにさらにブロッカーがあるかどうかはわかりませんが、Rustを使用してビットコードバイナリを出力できる可能性があるようです🎉

Xcode10.2にはSwift5.0が含まれているようで、まもなくリリースされるはずです。 しかし一方で、LLVM8.0は来週リリースされる予定です。 Rustは、Appleが使用を開始する前にアップグレードされる可能性があります。

Rustがビットコードを適切にサポートするには、ピン留めされたバージョンのLLVMを使用するためにRustのApple ARMアーキテクチャビルドが必要になります(おそらくhttps://github.com/apple/swift-llvmリポジトリから–AppleはLLVMパッケージをリリースしましたが、独自のブランチです)。 そのバージョンのLLVMは、Appleが別のLLVMバージョンのXcodeの新しい最終バージョンをリリースしたときにのみ更新されます。

ところで、最新のRustはLLVM 6でビルド可能であるため、間違いなく実行可能と思われます: https
必要なバージョンのLLVM(LLVM 6用のもの:https://github.com/rust-lang/rust/issues/55842)を更新するために、問題が作成されたときに必ず参加する必要があります。

@vincentisambart Rustは、
LLVM 6は、自分でビルドする場合は最小限のサポートバージョンであり、CIでテストされています: https

今、私たちは正しいことをするためにアップルに頼る必要があると思います

私はしばらくの間これらの線に沿って何かを追いかけてきました(そして今は終了しています)、そして私はプラットフォームに関してAppleがこれをすることは意味がないと推測しています:理由は:

  • Swiftはさまざまな方法でRustになりたいと考えていますが(所有権マニフェストを参照)、多くの点で遅れをとっています。
  • Appleは、Swiftがメインのプラットフォーム言語であり続ける必要があるため、プラットフォーム上で別の大きな言語を促進したり、Swiftを他の環境にプッシュしたりすることは意味がありません。

Rustは、IIRCの5か月間、ナイトリービルドにLLVM8をすでに使用しています。

その場合、AppleがLLVM 7ビットコードのサポートを開始したとしても、Rustの最近の公式ビルドによって生成されたビットコードは機能しない可能性があります。 たとえそうだとしても、次にRustが生成されたビットコードに互換性のない変更を加えたバージョンのLLVMに移行したときに、破損する可能性があります。

LLVM 6を自分でビルドし、CIでテストする場合は、最小限のサポートバージョンです。

次に、Rustの公式の*-apple-iosビルドをLLVM 6(またはhttps://github.com/apple/swift-llvm/releases/tag/swift-4.2.2-RELEASEのようなもの)でビルドするようにします。それは動作します)ビットコードの問題を修正する可能性があります。

Rustには、 https://github.com/rust-lang/rust/issues/46819をマージした後、現在2つのLLVMバックエンド(Emscriptenと標準)が付属していると思い
#46819はビットコード用のios LLVMバックエンドについて言及していますが、実装されていません。

これを完全に狂わせるわけではありませんが、そのような場合にCへのトランスパイルを有効にしようとする方が全体的に理にかなっているのではないでしょうか。 RustがApple側からのビットコード要件を最新の状態に保つことができる可能性は低いです。

確かに非互換性の潜在的な原因があるとしても、Appleに適したLLVMバージョンを組み込んだ互換性のある古いバージョンのRustでコンパイルを試みることができるテストへの扉が開かれます。

完全なクロスプラットフォームアプローチでは、最新の改善の恩恵を受けるために最新バージョンのRustから同じソースコードをコンパイルできる必要があり、古いバージョンからコンパイルできる必要があるため、これは明らかにブロックされています。 Rustのバージョン、特にAppleエコシステムのビットコード互換バイナリを出力するため。 それは実行可能ですが、適切ではありません。

少なくとも、より多くの人々がこれをテストし、私たち全員を正しい方向に前進させるための扉を開くので、これが起こっているのを見るのはまだかなり興奮しています。

かなり大規模なチーム向けにクロスプラットフォームのモバイルコードを作成するためのアプローチを現在決定しようとしている人と言えば、ビットコードを生成できない場合、文字通りRustを使用することはできません。 私たちのアプリの1つは、セルラーネットワーク経由でダウンロードするのに十分小さいバイナリを生成できるようにビットコードに依存しており、それを主張する大規模な顧客がいます。

Rustについて私が目にするすべてのことに基づいて、私が目にする可能性(Kotlin Multiplatform、Swift、Mono、Dart、C ++、React Nativeのクロスコンパイル)の中で最も長期的な利点があると思いますが、間違いなくビットコードが必要ですたとえそれが最新のRustリリースに追いつくことができないことを意味したとしても、完全にサポートされること。

ビットコードが機能したとしても、RustはwatchOSやtvOSをターゲットにすることはできませんか?

RustがApple側からのビットコード要件を最新の状態に保つことができる可能性は低いです。

ここでの問題は、それが古すぎるではないことを、錆のLLVMが新しすぎるということです。 ここでより良い互換性の話が必要であることに同意します。

rustcが複数のLLVMをサポートすることはどの程度実現可能ですか?

関連: tvOSおよびwatchOS(およびシミュレーター)ターゲットのサポート

すでに複数のLLVMを使用しています。 emscriptenターゲットの場合、LLVM 6atmにあるemscriptenのLLVMフォークを使用します。

ここでの問題は、RustのLLVMが_古すぎる_ということではなく、_新すぎる_ということです。 ここでより良い互換性の話が必要であることに同意します。

問題は、それが古すぎたり新しすぎたりすることではなく、錆がLLVMバージョンと一致したとしても、どのiOSリリースでもこれが再び壊れることがあるということです。 Apple(私が知る限り)は、ビットコードに関する安定性を保証するものではありません。

問題は、それが古すぎたり新しすぎたりすることではなく、錆がLLVMバージョンと一致したとしても、どのiOSリリースでもこれが再び壊れることがあるということです。 Apple(私が知る限り)は、ビットコードに関する安定性を保証するものではありません。

実際には、新しいiOSバージョンがリリースされると、Xcodeのメジャーアップデートが年に1回見られます。 このようなことが起こったとき、開発者は新しいバージョンのXcodeでアプリの送信を開始する必要があることをはっきりと認識しているので、驚くことはめったにありません。 これを計画するのは特に難しいとは言えません。

これを計画するのは特に難しいとは言えません。

ビットコードに関する保証はまったくないので、計画するのが非常に難しいものになる可能性があります。 あるリリースから別のリリースに、LLVMのオープンソースリリースにはならない独自のビットコード形式を使用することを決定すると想像してみてください。

ビットコードに関する保証はまったくないので、計画するのが非常に難しいものになる可能性があります。 あるリリースから別のリリースに、LLVMのオープンソースリリースにはならない独自のビットコード形式を使用することを決定すると想像してみてください。

Appleが他の誰にも関係なく重大な変更を加えると仮定するだけなら、確かに。 Bitcodeの計画に関するより明確なドキュメントがあっても、それらが悪意のあるものであるか、単に気にしないと仮定した場合、それほど改善されません。

しかし、彼らは明らかにSwiftをプラットフォームの重要な部分にしており、自分のチームや最も重要なパートナーを含め、何千人もの開発者がSwiftに依存しています。 Swiftは完全にオープンソースのLLVMに基づいており、Xcodeがアップルが受け入れるビットコードを生成するために使用するツールチェーンを含め、それ自体が完全にオープンで開発されています。

したがって、誰も気付かないうちにそのフォーマットを突然変更するには、SwiftリポジトリとLLVMリポジトリの両方をプライベートにする必要がありますよね? それは確かに可能ですが、私にはそうは思えません。

Rustチームが、そのリスクがビットコードをサポートしない正当な理由であると判断した場合、それは確かに彼らの特権です。 それについては少し悲しいですが、他の人にどこで時間を過ごすかを伝えるのは私の場所ではありません。

ビットコードに関する保証はまったくないので、計画するのが非常に難しいものになる可能性があります。 あるリリースから別のリリースに、LLVMのオープンソースリリースにはならない独自のビットコード形式を使用することを決定すると想像してみてください。

Appleは6月の初め頃にXcodeBetaをリリースし、9月に最終バージョンをリリースします。 6〜9か月後、古いXcodeバージョンでビルドされたアプリのAppstoreへの受け入れを停止します。

そのタイムラインでビットコードの変更を準備するのに十分な時間があると思います。

Xcode 10.2ベータ3(LLVM7付きのSwift5を含む)でテストしたところ、ビットコードが埋め込まれた最近のRustとリンクできました。 明らかに、 RustにはwatchOS / tvOSターゲットがないため、これはiOSターゲットでのみ機能します。

また、ビットコードの互換性を維持するために、RustがすべてのApple関連ターゲットにAppleLLVMフォークを使用できる必要があることに同意します。

ええ、ベータリリースウィンドウは合理的に聞こえます。 AppleがソースLLVMまたはそのビットコード形式をクローズするという考えは非常にありそうもないと思いますが、将来のiOSリリースでAppleがビットコードを要求することは間違いなく起こるように思えます。 そして、誰が知っているか、多分彼らはプロジェクトMarzipanでMac AppStoreの提出のためにビットコードを要求し始めるでしょう。

提案されている互換性に対処するための非保証的な方法は確かに厄介ですが、特にビデオゲーム開発のようにC ++を使用する場合は、モバイルプラットフォームが最終的に

コンパイラチームによって公式に認可されたアプローチが誰かにこれに取り組むことを奨励することを願っていますが、 @ brsonによる以前のコメントはためらいを要約していると思います:

LLVMのいくつかのバージョン間の互換性を正常に維持しています。 Appleと私たちがあまり離れていない限り、それは実行可能であるはずですが、分割を越えることができないほどの大きな破損のリスクが常にあります

あるいは、ビットコードは将来安定し、この議論がこれまでに起こったことを私たちは皆忘れるでしょう🙏

今から帽子を食べます😞

私が言った:

AppleがソースLLVMまたはそのビットコード形式を閉じるという考えはほとんどありません

これは主に@mitsuhikoによって表明された不信に応えたもの

あるリリースから別のリリースに、LLVMのオープンソースリリースにはならない独自のビットコード形式を使用することを決定すると想像してみてください。

しかし、問題#48833を見ると、確かに前例があります。 @comexが以前に書いたように:

LLVMトランクの前にXcodeのLLVMに機能が表示される場合があります。たとえば、Appleがarm64デバイスの出荷を計画していることを秘密にしておきたかったため、最初に開発されたarm64ポート全体などです。

そして同じ問題からの@michaeleiselscの物語:

私が取り組んでいたアプリは、2016年12月のランダムな再起動によって大きな打撃を受けました。これは、オープンソースLLVMが2017年12月にのみ修正した特定の問題が原因です。2016年12月にオープンソースLLVMからAppleのLLVMに移行したとき、問題は修正されました

アイデアがRustでAppleのLLVMを使用していることを考えると、それほど悪くはないように聞こえますが、実装が異なるために、時折厄介なバグが発生するリスクがあります😢。 すべてのプロジェクトが負担できるリスクではありません。 現時点では、トランスパイルはより良いオプションのように聞こえますが、これまでのところ、可能な限りすべてのように聞こえるわけではありません

私はまだAppleのLLVMの使用がサポートされるべきだと思いますが、物事が機能し続けるという保証がないことを説明するドキュメントに明確な警告があるはずです(Tier 1.5か何か)。

Kotlin / Native。 JetBrainsはモバイルプラットフォームを優先事項と見なしており、しばらく時間がかかり、ビットコードマーカー(完全なビットコードではありません)のみですが、作業を開始するのに十分です-JetBrains / kotlin-native#1564およびJetBrains / kotlin-native#を参照してください1202(コメント)

これを指摘してくれてありがとう@ oleksandr-yefremov! 私はさらにビットに掘らとkotlin /ネイティブアプローチを複製することができたgolangに。 皆さんも同じことができるはずだと思います。そうすれば、必ずしもビットコードを発行しなくても、ビットコード対応のiOS / tvOS / watchOSアプリで錆を使用できるようになります。

ビットコードは機能しますか? 誰かやってみましたか?

@volodg私はさびた初心者です。 しかし、私は毎晩最新の錆でこのチュートリアルを実行しました( rustc 1.37.0-nightly (088b98730 2019-07-03)を書いている時点で)、それは機能しませんでした。

マーカーがあるようです。

$ otool -arch arm64 -l librust.a  | grep bitcode
  sectname __bitcode
...

しかし、iOSデバイス用にビルドすると次のエラーが発生します(シミュレーターは機能します)。

ld: '/Users/amrox/Documents/Projects/rust-ios-example/hello-rust/libs/librust.a(rust-e6011ffb55678675.rust.8yq9vjk7-cgu.3.rcgu.o)' 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 arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

それは私が得た限りです。

rustc nightly-2019-09-05 aarch64-apple-ios and rustflags = "-C lto -Z embed-bitcode" staticlibをclang-1100.0.33.5 (Xcode 11 beta 7) and -fembed-bitcodeアプリにリンクすることに成功しました。 ソースコードはhttps://github.com/saturday06/rust-ios-bitcode-testです。

  • __cmdlineセクションが必要かどうか知っていますか?

2年後、私はこれに答えることができます-物理デバイスへのデプロイまたはXcodeアーカイブの作成には、空のコマンドラインで問題ありませんが、App Storeの送信では、Appleはclangコマンドラインの検証を実行します。 私はこのPRにもっと長い説明を入れました。これには、それを機能させるためのハッキーなパッチが含まれています: https

どういうわけかこれを上流に上げたいのですが、オプションは魅力的ではありません。 iOSをターゲットにするときにいくつかのclangオプションを作成しますか? Appleが検証ルールを変更した場合にどのように嘘をつくかを正確に選択するためのenvvarを提供していますか? ここに合理的な選択肢があれば、喜んで変更を加えます。

-Cembed-bitcode = noはiOSターゲットでは機能しません。 .aファイルにはまだビットコードセクションがあります
ビットコードなしでビルドする方法は?

このページは役に立ちましたか?
0 / 5 - 0 評価