2013-03-30 87 views
24

我有一個C++項目,我想轉換爲一個web應用程序。爲此,我想使用Emscripten來構建項目。使用Boost和Emscripten

該項目使用一些外部庫。我設法編譯或查找大多數庫的JavaScript版本,現在我堅持使用Boost。實際上,我甚至不知道如何開始Boost:他們使用boostrap腳本來生成文件來構建庫。可以將工具集傳遞給此腳本,但Emscripten顯然不受支持。

我的項目使用Boost的以下部分:線程,正則表達式,文件系統,信號,系統。我如何使用Emscripten編譯這些庫?

編輯

繼npclaudiu的答案,我自舉庫與海灣合作委員會工具包,然後我編輯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; 
     ~~^ 
+0

Web後端或前端? –

+0

這將是前端。這是一個我想在網絡瀏覽器中播放的遊戲。 – Julien

+1

只是爲了好奇,有多少MB在編譯爲emscripten代碼時需要Boost? :D – GameDeveloper

回答

21

我終於設法用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> 

編譯升壓添加以下行作爲共享庫

按照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_YIELDboost/config/posix_features.hpp,圍繞線67

然後編譯庫:./b2 thread regex filesystem signals system

編譯作爲靜態庫提升

做到以上步驟,然後編輯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

+0

偉大的工作@ julien。您是否嘗試使用'user-config.jam'而不是硬編碼路徑? – abergmeier

+0

@LCIDFire我對Boost的配置文件不夠熟悉,所以我沒有嘗試'user-config.jam'。這真的是一個試錯的過程,在我的遊戲運行之前,我仍然有工作要做。 – Julien

+0

好的,如果你願意,你可以打我irc。 – abergmeier

1

我不知道如果你碰巧看到這個FAQ中的特定問題,但如果您還沒有:

問:如何鏈接系統庫,如SDL,boost等?

答:包含在emscripten - libc,libC++(C++ STL)和SDL中的系統庫在編譯時(以及它們的必要部分)會自動包含在內。與其他編譯器不同,你甚至不需要-lSDL(但-lSDL也不會傷害)。

emscripten不包含的其他庫,像boost,您需要自己編譯並鏈接到您的程序,就好像它們是您項目中的模塊一樣。例如,看如何BananaBread links in libz。 (請注意,在特定情況下,如果只需要升壓頭,則不需要編譯任何東西。)

另一個不包括庫的選項是將它們實現爲JS庫,如emscripten對於libc(減malloc)和SDL(但不是libC++或malloc)。請參閱emcc中的--js-library。

+1

我見過這個問題,這就是爲什麼我試圖用emscripten編譯Boost。 – Julien

2

你可以嘗試配置Boost庫指定gcc的工具集,爲Emscripten建議本身as being a drop-in replacement for gcc。另外,我認爲如果你爲這種情況建立Boost作爲靜態庫,會更好。請記住,大多數Boost庫僅用於標題,因爲它們只定義模板類/函數。

+0

在我的問題中列出的Boost庫不僅僅是頭文件,否則它會太容易了:)我要試試你的解決方案,我只需要找到如何告訴Boost使用'emcc'而不是'gcc'進行編譯。 – Julien

3

爲了記錄,Boost現在包含一個「emscripten」工具集,(根據我的經驗)使上述過程變得不必要。

要使用,自舉升壓爲正常,然後用B2(或bjam的)編譯像這樣:

b2 toolset=emscripten