LoginSignup
4
3

More than 5 years have passed since last update.

Emscripten で libc をビルドしなおすには

Posted at

libc について

Emscripten は C のソースコードをコンパイルする際に、そのコードで利用されている標準ライブラリも JS にコンパイルします。

例えば次の Hello World は、出力のために prtinf を利用しています。この printf は C の標準ライブラリで定義されている関数です。そのためこのコードを実行するには、C の標準ライブラリである libc に含まれる該当部分とリンクされる必要があります。

helloworld.c
#include <stdio.h>

int main(int argc, char **argv){
  prtinf("Hello, world!\n");
}

Emscripten は libc の変換結果をキャッシュする

JS になった場合も状況は変わりません。ブラウザの提供する API には printf はありません。そのため上記のコードを JS に変換する際には、printf のコードも併せて変換しなければ、実行できません。そのため Emscripten は必ずこのライブラリをコンパイルし、中間コードにした後、対象のコードと一緒に JS へと変換します。

libc は必ず変換されますが、変更はほとんどされないライブラリでもあります。そのため毎回変換を行うのは時間の無駄です。このことから Emscripten は libc の変換結果をキャッシュします。通常は ~/.emscripten_cacheにキャッシュが保存されています。

$ls  ~/.emscripten_cache/
dlmalloc.bc    libc.bc    struct_info.compiled.json

ここでキャッシュされているのは JS ファイルではなく、コンパイル後に生成された中間コードです。これは Emscripten はリンク後 JS に変換を行うためです。

キャッシュをクリアするには

次の場合、キャッシュがクリアされます。

  • 使用する Emscripten のバージョンが変更された場合
  • emcc に --clear-cache オプションをつけて実行した場合

前者は次のように emsdk activate を実行した場合に該当します。

$ emsdk activate latest
$ source ${EMSCRITEN_INSTALL_DIR}/emsdk_env.sh

後者は次のように emcc を実行すればキャッシュがクリアされます。

$ emcc --clear-cache
WARNING:root:clearing cache
INFO:root:(Emscripten: Running sanity checks)
$ ls ~/.emscripten_cache
ls ${HOME}/.emscripten_cache: No such file or directory
$ emcc -o helloworld.js helloworld.c
WARNING:root:generating system library: libc.bc...
WARNING:root:                                     ok
WARNING:root:generating system library: dlmalloc.bc...
WARNING:root:                                     ok

どんなときに使うのか

ほとんど使うときはありません。

ただ LLVM がアップデートされ、Emscripten が期待しているものと違うものが利用された場合、正しくリンクができず、変換が失敗することがあります。そのような場合は、キャッシュを一旦クリアすると正しく変換されることがあります。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3