I have a c++ project I would like to convert to a web application. For this purpose, I would like to use Emscripten to build the project.
The project uses some external libraries. I managed to compile or find the JavaScript version of most libraries and now I am stuck with the Boost ones. Actually I do not even know how to start for Boost: they use a boostrap script to generate the files to build the libraries. It is possible to pass the toolset to this script but Emscripten is obviously not supported.
My project uses the following parts of Boost: Thread, Regex, FileSystem, Signals, System. How can I compile these libraries using Emscripten?
Edit
Following the answer of npclaudiu, I bootstrapped the library with the gcc toolkit, then I edited project-config.jam
to configure the compiler, replacing:
# 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 ;
}
with
# 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++" ;
}
Now, typing ./b2
effectively builds the libraries. Boost.Signals and Boost.System compile well. The others have some errors.
Boost.Thread complains:
libs/thread/src/pthread/thread.cpp:503:27: error: use of undeclared identifier 'pthread_yield'
BOOST_VERIFY(!pthread_yield());
^
Boost.Regex complains a lot about CHAR_BIT to be undeclared but it seems to be a problem in 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 seems to fail due to emscripten too:
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;
~~^
I finally managed to compile the needed libraries with emscripten. Here are the steps I followed.
Edit system/include/libcxx/climits
to add the following definitions (see 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
Add the following line in system/include/libcxx/cwchar
#include <cstdio>
As suggested by npclaudiu, bootstrap the library using the gcc toolkit. Then edit project-config.jam
to configure the compiler and replace:
# 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 ;
}
with
# 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++" ;
}
Force BOOST_HAS_SCHER_YIELD
in boost/config/posix_features.hpp
, around the line 67.
Then compile the libraries: ./b2 thread regex filesystem signals system
Do all the above steps, then edit tools/build/v2/tools/gcc.jam
and replace:
toolset.flags gcc.archive .AR $(condition) : $(archiver[1]) ;
with
toolset.flags gcc.archive .AR $(condition) : "/full/path/to/emscripten/emar" ;
and
toolset.flags gcc.archive .RANLIB $(condition) : $(ranlib[1]) ;
with
toolset.flags gcc.archive .RANLIB $(condition) :
"/full/path/to/emscripten/emranlib" ;
Compile the libraries: ./b2 link=static variant=release threading=single runtime-link=static thread signals system filesystem regex