在Emscripten中使用Boost

Jul*_*ien 26 javascript c++ boost emscripten

我有一个c ++项目,我想转换为Web应用程序.为此,我想使用Emscripten来构建项目.

该项目使用一些外部库.我设法编译或找到大多数库的JavaScript版本,现在我陷入了Boost的困境.实际上我甚至不知道如何启动Boost:他们使用boostrap脚本生成文件来构建库.可以将工具集传递给此脚本,但显然不支持Emscripten.

我的项目使用Boost的以下部分:Thread,Regex,FileSystem,Signals,System.如何使用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 ;
}
Run Code Online (Sandbox Code Playgroud)

# 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++" ;
}
Run Code Online (Sandbox Code Playgroud)

现在,键入./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());
                      ^
Run Code Online (Sandbox Code Playgroud)

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);
                                                                                       ^
Run Code Online (Sandbox Code Playgroud)

由于emscripten,Boost.FileSystem似乎也失败了:

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;
      ~~^
Run Code Online (Sandbox Code Playgroud)

Jul*_*ien 24

我终于设法用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
Run Code Online (Sandbox Code Playgroud)

添加以下行 system/include/libcxx/cwchar

#include <cstdio>
Run Code Online (Sandbox Code Playgroud)

将Boost编译为共享库

正如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 ;
}
Run Code Online (Sandbox Code Playgroud)

# 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++" ;
}
Run Code Online (Sandbox Code Playgroud)

在线67周围强行BOOST_HAS_SCHER_YIELD进入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]) ;
Run Code Online (Sandbox Code Playgroud)

toolset.flags gcc.archive .AR $(condition) : "/full/path/to/emscripten/emar" ;
Run Code Online (Sandbox Code Playgroud)

toolset.flags gcc.archive .RANLIB $(condition) : $(ranlib[1]) ;
Run Code Online (Sandbox Code Playgroud)

toolset.flags gcc.archive .RANLIB $(condition) :
  "/full/path/to/emscripten/emranlib" ;
Run Code Online (Sandbox Code Playgroud)

编译库: ./b2 link=static variant=release threading=single runtime-link=static thread signals system filesystem regex


小智 8

为了记录,Boost现在包括一个"emscripten"工具集,(根据我的经验)使上述过程变得不必要.

要正常使用boostrap boost,然后使用b2(或bjam)进行编译,如下所示:

b2 toolset=emscripten 
Run Code Online (Sandbox Code Playgroud)

  • 这确实是有希望的,但是我遇到了诸如“错误:在寻找最佳转换时发现歧义”之类的问题。试图从以下方式产生类型“ SEARCHED_LIB”:...您是否成功在OSX上使用Emscripten构建Boost? (2认同)
  • 看来这个错误是由 b2 寻找外部库(例如 zlib、icu、bzip2 等)的方式引起的。我能够通过修改 `boost_1_67_0/tools/build/src/build/generators.jam` 来明确忽略生成器 `searched-lib-generator` 来解决这个问题 (2认同)

小智 7

在较新版本的 emscripten 中,您可以使用ports简单地添加 Boost 库。现在就像将此标志添加到编译器链接器一样简单: -s USE_BOOST_HEADERS=1

如果您使用的是 CMake,则可以像这样添加标志:

set_target_properties(your_targets_name_here PROPERTIES COMPILE_FLAGS "-s USE_BOOST_HEADERS=1" LINK_FLAGS "-s USE_BOOST_HEADERS=1")
Run Code Online (Sandbox Code Playgroud)

问题的更多细节