web-dev-qa-db-ja.com

EmscriptenでBoostを使用する

Webアプリケーションに変換したいc ++プロジェクトがあります。この目的のために、Emscriptenを使用してプロジェクトをビルドしたいと思います。

プロジェクトはいくつかの外部ライブラリを使用します。私はほとんどのライブラリのJavaScriptバージョンをコンパイルまたは見つけることができましたが、今ではBoostライブラリで立ち往生しています。実際、私はBoostを開始する方法すら知りません。彼らはboostrapスクリプトを使用して、ライブラリを構築するためのファイルを生成します。ツールセットをこのスクリプトに渡すことは可能ですが、Emscriptenは明らかにサポートされていません。

私のプロジェクトでは、Boostの次の部分を使用しています:スレッド、正規表現、ファイルシステム、シグナル、システム。 Emscriptenを使用してこれらのライブラリをコンパイルするにはどうすればよいですか?

編集

Npclaudiuの回答に続いて、gccツールキットを使用してライブラリをブートストラップし、project-config.jamを編集してコンパイラを構成し、以下を置き換えました。

# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! gcc in [ feature.values <toolset> ]
{
    using gcc ;
}

# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! gcc in [ feature.values <toolset> ]
{
    using gcc : : "/full/path/to/em++" ;
}

これで、./b2と入力すると、ライブラリが効果的に構築されます。 Boost.SignalsとBoost.Systemはうまくコンパイルされます。他にはいくつかのエラーがあります。

Boost.Threadは文句を言います:

libs/thread/src/pthread/thread.cpp:503:27: error: use of undeclared identifier 'pthread_yield'
        BOOST_VERIFY(!pthread_yield());
                      ^

Boost.Regexは、CHAR_BITが宣言されていないことについて多くの不満を述べていますが、emscriptenでは問題があるようです。

In file included from libs/regex/build/../src/c_regex_traits.cpp:28:
In file included from ./boost/regex/v4/c_regex_traits.hpp:26:
In file included from ./boost/regex/v4/regex_workaround.hpp:35:
/path/to/emscripten/system/include/libcxx/vector:1989:92: error: use of undeclared identifier 'CHAR_BIT'
static const unsigned __bits_per_Word = static_cast<unsigned>(sizeof(__storage_type) * CHAR_BIT);
                                                                                       ^

Boost.FileSystemもemscriptenが原因で失敗するようです:

In file included from libs/filesystem/src/windows_file_codecvt.cpp:21:
/path/to/emscripten/system/include/libcxx/cwchar:117:9: error: no member named 'FILE' in the global namespace
using ::FILE;
      ~~^
27
Julien

私はついに必要なライブラリをemscriptenでコンパイルすることができました。これが私が従ったステップです。

Emscriptenの変更

system/include/libcxx/climitsを編集して、次の定義を追加します( http://github.com/kripken/emscripten/issues/531 を参照)。

#ifndef CHAR_BIT
# define CHAR_BIT __CHAR_BIT__
#endif

#ifndef CHAR_MIN
# define CHAR_MIN (-128)
#endif

#ifndef CHAR_MAX
# define CHAR_MAX 127
#endif

#ifndef SCHAR_MIN
# define SCHAR_MIN (-128)
#endif

#ifndef SCHAR_MAX
# define SCHAR_MAX 127
#endif

#ifndef UCHAR_MAX

# define UCHAR_MAX 255
#endif

#ifndef SHRT_MIN
# define SHRT_MIN (-32767-1)
#endif

#ifndef SHRT_MAX
# define SHRT_MAX 32767
#endif

#ifndef USHRT_MAX
# define USHRT_MAX 65535
#endif

#ifndef INT_MAX
# define INT_MAX __INT_MAX__
#endif

#ifndef INT_MIN
# define INT_MIN (-INT_MAX-1)
# define INT_MIN (-INT_MAX-1)
#endif

#ifndef UINT_MAX
# define UINT_MAX (INT_MAX * 2U + 1)
#endif

#ifndef LONG_MAX
# define LONG_MAX __LONG_MAX__
#endif

#ifndef LONG_MIN
# define LONG_MIN (-LONG_MAX-1)
#endif

#ifndef ULONG_MAX
# define ULONG_MAX (LONG_MAX * 2UL + 1)
#endif

system/include/libcxx/cwcharに次の行を追加します

#include <cstdio>

Boostを共有ライブラリとしてコンパイルする

Npclaudiuが提案しているように、bootstrap gccツールキットを使用するライブラリ。次に、project-config.jamを編集してコンパイラを構成し、以下を置き換えます。

# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! gcc in [ feature.values <toolset> ]
{
    using gcc ;
}

# Compiler configuration. This definition will be used unless
# you already have defined some toolsets in your user-config.jam
# file.
if ! gcc in [ feature.values <toolset> ]
{
    using gcc : : "/full/path/to/emscripten/em++" ;
}

BOOST_HAS_SCHER_YIELDの67行目あたりにboost/config/posix_features.hppを強制します。

次に、ライブラリをコンパイルします:./b2 thread regex filesystem signals system

Boostを静的ライブラリとしてコンパイルする

上記のすべての手順を実行してから、tools/build/v2/tools/gcc.jamを編集して、以下を置き換えます。

toolset.flags gcc.archive .AR $(condition) : $(archiver[1]) ;

toolset.flags gcc.archive .AR $(condition) : "/full/path/to/emscripten/emar" ;

そして

toolset.flags gcc.archive .RANLIB $(condition) : $(ranlib[1]) ;

toolset.flags gcc.archive .RANLIB $(condition) :
  "/full/path/to/emscripten/emranlib" ;

ライブラリをコンパイルします:./b2 link=static variant=release threading=single runtime-link=static thread signals system filesystem regex

24
Julien

ちなみに、Boostには「emscripten」ツールセットが含まれているため、(私の経験では)上記のプロセスは不要です。

使用するには、通常どおりブーストラップブーストしてから、次のようにb2(またはbjam)でコンパイルします。

b2 toolset=emscripten 
7
Mike_L

Emscriptenが推奨しているように、ツールセットとしてgccを指定してBoostライブラリを構成することができます gccのドロップイン置換として 。また、この場合の静的ライブラリとしてBoostをビルドする方が良いと思います。 Boostライブラリのほとんどは、テンプレートクラス/関数のみを定義するため、ヘッダーのみであることに注意してください。

2
npclaudiu

[〜#〜] faq [〜#〜] でこの特定の質問を偶然目にしたかどうかはわかりませんが、そうでない場合は:

Q. SDL、ブーストなどのシステムライブラリに対してリンクするにはどうすればよいですか?

A. emscriptenに含まれているシステムライブラリ(libc、libc ++(C++ STL)、およびSDL)は、コンパイル時に自動的に含まれます(およびそれらの必要な部分のみ)。他のコンパイラとは異なり、-lSDLも必要ありません(ただし、-lSDLも問題ありません)。

Emscriptenに含まれていない他のライブラリboostのように、プロジェクトのモジュールであるかのように、自分でコンパイルしてプログラムにリンクする必要があります。たとえば、 libzのBananaBreadリンク を参照してください。 (ブーストの特定のケースでは、ブーストヘッダーのみが必要な場合は、何もコンパイルする必要がないことに注意してください。)

含まれていないライブラリの別のオプションは、emscriptenがlibc(マイナスmalloc)およびSDL(libc ++またはmallocではない)に対して行うように、それらをJSライブラリとして実装することです。 emccの--js-libraryを参照してください。

1

Emscriptenの新しいバージョンでは、 ports を使用してBoostライブラリを追加するだけです。このフラグをコンパイラおよびリンカーに追加するのと同じくらい簡単になりました:-s USE_BOOST_HEADERS=1

CMakeを使用している場合は、次のようにフラグを追加できます。

set_target_properties(your_target's_name_here PROPERTIES COMPILE_FLAGS "-s USE_BOOST_HEADERS=1" LINK_FLAGS "-s USE_BOOST_HEADERS=1)
1
askuri

Emsdkの更新:

多くの試行錯誤の末、次の方法でBoost1.71をコンパイルするためのemscripten1.39を取得することができました。

まだインストールしていない場合は、emsdkをインストールします https://emscripten.org/docs/getting_started/downloads.html

Emsdkインストールフォルダーに移動し、

./emsdk install latest && ./emsdk activate latest && source ./emsdk_env.sh

Boostリポジトリのクローンを作成するディレクトリに移動して実行します

git clone --recursive https://github.com/boostorg/boost.git

引数 '--jobs N'を追加できます。ここで、Nは、サブモジュールのクローンを作成するプロセスの数です(これを行うと、はるかに高速になります)。

cd boost

次に、bootstrapスクリプトを使用して、boost-build実行可能ファイルb2を作成します。

./bootstrap.sh

最後に、emsdkは上記の手順ですでにアクティブ化されているため、emconfigureを使用してBoostをビルドし、gccの呼び出しで代わりにemscriptenを使用するために必要なすべてを構成できます。

emconfigure ./b2 toolset=gcc --prefix=<directory_to_install_to> --build-dir=<directory_for_intermediate_build_files>

インクルードとライブラリを選択したプレフィックスディレクトリにインストールするには、次を実行します。

emconfigure ./b2 toolset=gcc --prefix=<directory_to_install_to> --build-dir=<directory_for_intermediate_build_files> install
0
Scott Butler