Подтвердить что ты не робот

Использование Boost с Emscripten

У меня есть проект С++, который я хотел бы преобразовать в веб-приложение. Для этой цели я хотел бы использовать Emscripten для создания проекта.

В проекте используются некоторые внешние библиотеки. Мне удалось собрать или найти версию большинства библиотек JavaScript, и теперь я застрял в Boost. На самом деле я даже не знаю, как начать работу с Boost: они используют boostrap script для создания файлов для создания библиотек. Можно передать набор инструментов на этот script, но Emscripten явно не поддерживается.

В моем проекте используются следующие части Boost: Thread, Regex, FileSystem, Signals, System. Как я могу скомпилировать эти библиотеки с помощью Emscripten?

Edit

После ответа 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;
      ~~^
4b9b3361

Ответ 1

Мне удалось собрать необходимые библиотеки с 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, загрузите библиотеку с помощью 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 в boost/config/posix_features.hpp, вокруг строки 67.

Затем скомпилируйте библиотеки: ./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

Ответ 2

Вы можете попробовать настроить библиотеки Boost с указанием gcc в качестве набора инструментов, так как Emscripten рекомендует как замену для gcc. Кроме того, я думаю, что лучше, если вы создадите Boost как статические библиотеки для этого случая. Имейте в виду, что большинство библиотек Boost предназначены только для заголовков, поскольку они определяют только классы шаблонов/функции.

Ответ 3

Я не знаю, видел ли вы этот конкретный вопрос в FAQ, но если у вас нет

Q. Как подключиться к системным библиотекам, таким как SDL, boost и т.д.?

а. Системные библиотеки, входящие в состав emscripten - libc, libС++ (С++ STL) и SDL, автоматически включаются при компиляции (и только необходимых частей). Вам даже не нужно -lSDL, в отличие от других компиляторов (но -lSDL тоже не повредит).

Другие библиотеки, не включенные в emscripten, как boost, вам нужно будет скомпилировать себя и связать с вашей программой, точно так же, как если бы они были модулем в вашем проекте. Например, посмотрите, как ссылки BananaBread в libz. (Обратите внимание, что в конкретном случае boost, если вам нужны только заголовки boost, вам не нужно ничего компилировать.)

Другой вариант для не включенных библиотек - реализовать их как JS-библиотеку, например emscripten для libc (минус malloc) и SDL (но не libС++ или malloc). См. -js-library в emcc.

Ответ 4

Для записи Boost теперь включает в себя набор инструментов "emscripten", который (по моему опыту) делает описанный выше процесс ненужным.

Чтобы использовать boostup boost как обычно, затем скомпилируйте с b2 (или bjam) следующим образом:

b2 toolset=emscripten