
Emscriptenはイスラエル出身の開発者Alon Zakaiが2010年に公開したC/C++をブラウザで動かすためのツールチェーンです。当初はLLVM IRをJavaScriptへ変換するasm.jsターゲットとして登場し、2017年以降はWebAssemblyを主要な出力形式として再構築されました。Unreal EngineやUnityのWebビルド、AutoCAD Web、Figma、Photoshop Webといった著名製品の裏側で動いており、「既存ネイティブアプリをWebへ持ち出す」需要に対する標準的な解として広く採用されています。
この記事の目次
- asm.jsからWebAssemblyへの進化
- ツールチェーンの構成と使い方
- C/C++コードを移植する際の典型課題
- 現代的なWasm環境での位置づけ
- まとめ
asm.jsからWebAssemblyへの進化

Alon ZakaiはMozilla在籍時、ブラウザでC/C++コードを動かす実験的プロジェクトとしてEmscriptenを始めました。初期の出力はasm.jsと呼ばれるJavaScriptの厳密なサブセットで、JITコンパイラに最適化されやすい形に整えられていました。2013年公開のasm.js仕様はFirefoxで先行採用され、ネイティブ比50パーセント程度の実行速度を実現しています。ゲームエンジンUnreal Engine 3が同年にこの技術でWeb版を公開したことが大きな話題を呼びました。
2017年にWebAssembly 1.0が主要ブラウザに揃って実装されたタイミングで、Emscriptenの出力先もWasm中心へ移行しました。asm.jsよりも小さなバイナリ、高速な起動、ベターな最適化を享受でき、ネイティブ比70〜90パーセントの実行速度に到達するケースも増えています。現在の最新版ではWasm出力が標準で、asm.jsはオプトインの遺産機能として残されています。Emscriptenが先行して整備した「C/C++からブラウザ向けバイナリを生成する」というワークフローは、事実上の業界標準として根付いています。
ツールチェーンの構成と使い方

Emscripten SDKをインストールするとemcc、em++、emconfigure、emmake、emrunといったコマンド群が利用できます。emccはclangのラッパーとして振る舞い、C/C++ソースを受け取ってWasmファイルとJavaScriptグルーコードを生成します。emconfigureとemmakeは既存のautoconfやmakeベースのプロジェクトをそのままWasmターゲットでビルドするためのラッパーで、ffmpegやSQLite、OpenCVといった巨大プロジェクトを設定変更最小限でWeb化できます。
出力されるJavaScriptグルーコードは、Wasmモジュールのロード、メモリ初期化、ファイルシステム抽象、EmscriptenのランタイムAPI(emscripten_run_script、Module APIなど)の橋渡しを担います。ファイルシステムについてはMEMFS、IDBFS、NODEFSといった仮想FSが用意されており、C/C++のfopen系APIをそのままJavaScript側のIndexedDBやNode.js環境のディスクへ透過的にマッピングできます。この抽象化のおかげで、ネイティブコード側はあたかも通常のファイルシステムを使っているかのように動作します。
C/C++コードを移植する際の典型課題

EmscriptenでC/C++コードをWebに移植する際は、メインループの構造を変更する必要が出ます。ネイティブ環境では無限ループでフレームを描画するスタイルが一般的ですが、ブラウザではrequestAnimationFrameに基づくイベント駆動が前提となるため、emscripten_set_main_loopなどの専用APIを使ってループ制御をブラウザに委ねる形に書き直します。ゲームエンジンのWeb移植ではこの部分が最初の関門となります。
また、ネイティブのスレッドAPIをそのまま使うコードはSharedArrayBufferとWorkerに基づくpthreadsエミュレーションに置き換える必要があります。Cross-Origin-Embedder-Policyヘッダの設定がブラウザ側の前提となるため、デプロイ環境のHTTPヘッダ設計まで考慮しなければなりません。ネットワーク呼び出しもPOSIX socket APIをそのまま使うことはできず、EmscriptenがWebSocketへとマッピングする限定的なAPIに合わせて書き換える必要があります。こうした制約はWeb側の制限と表裏一体であり、移植作業は事前のアーキテクチャ整理が前提です。
現代的なWasm環境での位置づけ

現在のWebAssembly開発では、RustやCといった言語が直接Wasm出力をサポートしており、「Emscripten必須」だった時代は過ぎ去りました。Rustはwasm-packやwasm-bindgenによって、CはclangとWASI SDKによって、それぞれ独自のWasm出力経路を持ちます。Emscriptenの優位性は、既存C/C++大規模プロジェクトを移植するための周辺機能の充実度にあり、ファイルシステム、SDL、OpenGL ES、pthreadsといった抽象化が現代でも有用です。
WASI Preview 2やコンポーネントモデルといった新しい標準群への対応では、Bytecode Allianceが主導するWasmtimeやwasi-sdkの世界と比べると、Emscriptenは独自レイヤを多く抱えています。そのためサーバサイドWasm用途には別ツールチェーンを使うほうが素直で、Emscriptenはあくまで「ブラウザ向けに特化したC/C++移植ツール」として住み分ける形が落ち着いた現状です。新規にC/C++コードベースをWebへ持ち出すなら、依然としてEmscriptenが第一選択肢に挙がる定番ツールであり続けています。
まとめ
EmscriptenはWebAssemblyという技術が標準化される以前から、C/C++コードをブラウザで動かす道を切り開いてきました。ファイルシステム抽象、メインループ書き換え、pthreadsエミュレーションといった泥臭い周辺機能が巨大なネイティブアプリのWeb移植を現実にした立役者であり、現代でもブラウザ向け移植の標準ツールとして使われ続けています。
※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

コメント