WebAssemblyでC \ C ++コードをコンパイルします

WebAssemblyは、Webアプリケーションをコンパイルできる新しいバイナリ形式です。 これらの行を読んだ瞬間に設計および実装され、すべての主要なブラウザの開発者が前進しています。 すべてが非常に速く変化します! この記事では、WebAssemblyを操作するためのツールにかなり深く浸りながら、プロジェクトの現在の状態を示します。



WebAssemblyが機能するためには、2つの主要コンポーネントが必要です。コードをWebAssembly形式のバイナリにアセンブルするツールと、このバイナリをダウンロードして実行できるブラウザです。 どちらもまだ完全には作成されておらず WebAssembly 仕様の作業を完了することに大きく依存していますが、一般にこれらは別個のコンポーネントであり、開発は並行して行われます。 この分離は良いことです。コンパイラーはどのブラウザーでも実行できるWebAssemblyアプリケーションを作成でき、ブラウザーはコンパイラーによる作成方法に関係なくWebAssemblyプログラムを実行できます。 言い換えれば、開発ツールとブラウザの間で開かれた競争が行われ、これによりすべてが前進し、エンドユーザーに優れた選択肢がもたらされます。 さらに、この分離により、ツールキットおよびブラウザー開発者のチームは、並行して独立して作業できます。



今日お話ししたい新しいWebAssemblyツールキットプロジェクトはBinaryenと呼ばれます 。 Binaryenは、コンパイラでWebAssemblyをサポートするためのライブラリで、C ++で記述されています。 WebAssemblyコンパイラで個人的に作業していない場合、おそらくBinaryenについて直接知る必要はありません。 WebAssemblyコンパイラを使用している場合、おそらく内部でBinaryenを使用しています。以下の例を見てみましょう。





Binaryenライブラリの中核は、WebAssemblyの解析と生成、およびそのコードを抽象構文ツリー(AST)として表現することです。 これらの機能に基づいて、次の有用なユーティリティが作成されました。







Binaryenについては、 これらのスライドを見ることができます。



WebAssemblyがアクティブな設計中であることをもう一度思い出します。つまり、入力および出力のBinaryen形式(.wast、.s)は最終的なものではありません。 Binaryenは、WebAssembly仕様を更新するために常に更新されています。 変更のカーディナリティの度合いは時間の経過とともに減少しますが、もちろん、誰も互換性を保証できません。



Binaryenが役に立ついくつかの領域を見てみましょう。



Emscriptenを使用したWebAssemblyでのコンパイル



Emscriptenはasm.jsでCコードをコンパイルでき、Binaryen(asm2wasmユーティリティを使用)はWebAssemblyでasm.jsをコンパイルできるため、Emscripten + Binaryenバンドルは、WebAssemblyでCおよびC ++コードをコンパイルするための完全なツールセットを提供します。 asm.jsコードでasm2wasmを実行できますが、次のようにEmscriptenに実行させる方が簡単です:



emcc file.cpp -o file.js -s 'BINARYEN=”path-to-binaryen”'
      
      







Emscriptenはfile.cppをコンパイルし、出力はJavaScriptファイルに加えて、WebAssemblyを含む別の.wastファイルを提供します。 内部では、Emscriptenはasm.jsでコードをコンパイルし、asm2wasmを実行して結果を保存します。 これについては、EmscriptenプロジェクトのWikiで詳しく説明されています。



しかし、ブラウザがまだサポートしていない場合、WebAssemblyで何かをコンパイルする意味は何ですか? いい質問です! :)はい、まだこのコードをどのブラウザでも実行できません。 しかし、私たちはすでにそれで何かをテストできます。 そのため、正しいバイナリがEmscripten + Binaryenバンドルを作成したかどうかを確認します。 これを行う方法? このために、Emscriptがemcc呼び出しコマンドで受信した出力.jsファイルに統合したwasm.jsを使用できます(上記を参照)。 wasm.jsには、インタープリターを含むJavascriptのBinaryenポートが含まれています。 file.jsを(node.jsまたはブラウザで)実行すると、WebAssemblyの実行結果が得られます。 これにより、コンパイルされたWebAssemblyバイナリが正しく機能していることを実際に確認できます。 このようなプログラムの例を見ることができます。さらに、テスト目的のために、リポジトリにさらにいくつかの例があります。



もちろん、私たちはこれらのすべてのツールを使用してまだ安定した地位にありません。 テスト環境は奇妙です。 C ++コードはWebAssemblyにコンパイルされ、WebAssemblyインタープリターで実行されます。インタープリター自体はC ++で記述されていますが、JavaScriptに移植されています。 そして、これまでのところ、すべてを実行する他の方法はありません。 しかし、結果を信じるにはいくつかの理由があります。







これはすべて、すでに何らかの結果が得られていることを示しています。CおよびC ++コードをWebAssemblyにコンパイルし、なんとか起動することができます。



WebAssemblyは単なる別の新機能であり、それから気をそらされ、Emscriptenの他のすべてが引き続き機能することに注意してください。 .d。 その結果、Emscriptenを既に使用しているプロジェクトは、新しいコマンドラインパラメーターを追加するだけでWebAssemblyに切り替えることができます。 これにより、C ++プロジェクトをWebAssemblyにコンパイルし、ブラウザで簡単に作業できるようになります。



EmscriptenでWebAssemblyの新しいLLVM実験的バックエンドを使用する



Emscriptenの開発に新たな重要な段階があり、WebAssemblyモジュールを作成し、それらの作業をテストする機会を彼に与えました。 しかし、作業はそこで終わりではありません。asm2wasmユーティリティと共に、現在のasm.jsコンパイラを使用するだけでした。 LLVM for WebAssemblyの新しいバックエンドがあります(むしろ、まだではありませんが、積極的に作成されています)-LLVMのメイン開発ブランチにあります。 そして、まだ実際に使用する準備ができていませんが、時間が経つにつれて非常に重要なツールになるでしょう。 Binaryenは出力形式をサポートしています。



WebAssemblyのLLVMバックエンドは、ほとんどのLLVMバックエンドと同様に、この場合は特別な.s形式でアセンブリコードを作成します。 この形式はWebAssemblyに近いですが、WebAssemblyの直接構文とは異なります-WebAssemblyの抽象構文ツリーよりも、Cコンパイラの出力(命令の線形リスト、1行に1命令)に似ています。 この.sファイルは、かなり簡単な方法でWebAssemblyに変換できます(一般に、Binaryenにはs2wasmユーティリティが含まれています。 これを単独で実行するか、Emscriptenを使用して、新しいWASM_BACKENDオプションをサポートするようになりました。次のように使用できます。



 emcc file.cpp -o file.js -s 'BINARYEN=”path-to-binaryen”' -s WASM_BACKEND=1
      
      







s2wasmはBinaryenの一部であるため、BINARYENオプションも使用する必要があることに注意してください。 これらのオプションをすべて指定すると、Emscriptenはasm.jsコンパイラーを使用する代わりに、WebAssemblyの新しいバックエンドを使用します。 バックエンドを呼び出し、そこから.s形式のファイルを受け取った後、Emscriptenはs2wasmを呼び出してWebAssemblyに変換します。 この方法で既にビルドできるプログラムのいくつかの例は、Emscriptenプロジェクトwikiにあります



したがって、Binaryenを使用してWebAssemblyモジュールを構築するには2つの方法があります。

  1. Emscripten + asm.jsバックエンド+ asm2wasm 、これは現在動作しており、比較的単純で受け入れ可能なオプションです
  2. Emscripten + WebAssemblyの新しいバックエンド+ s2wasmは 、まだ完全には動作していませんが、WebAssemblyのバックエンドの開発が前面に出ています。




現時点での目標は、最初の方法から2番目の方法への移行をできるだけ難しくしないことです。 理想的には、すべてをコマンドラインの1つの引数に置き換えるだけに減らす必要があります。



したがって、明確な計画があります。



  1. Emscriptenを使用してasm.jsコードを生成します(今日)
  2. asm2wasmを使用してWebAssemblyを生成します(ブラウザーは既に可能ですが、ブラウザーはまだ準備ができていません)
  3. 新しいLLVMバックエンドを通じてWebAssemblyを生成します(準備ができ次第)




各ステップはユーザーに新しい利点をもたらします(スピード!)そして、開発者にとって実際に問題を引き起こすことはありません。



結論として、この記事は、Emscriptenを使用するという文脈でBinaryenについて書かれていますが、一般的な使用のためのWebAssemblyの別個のライブラリであると言いたいと思います。 WebAssemblyを操作するためのツールを作成するためのアイデアがある場合は、Binaryenライブラリを使用して、Emscripten、LLVM、または他のものを見ずに作業できます。



All Articles