2015-04-04 70 views
6

我注意到,使用emscripten,即使是相對較小的C++文件也可以很快變成相當大的JavaScript文件。例如:省略一些C++子系統

#include <memory> 
int main(int argc, char** argv) { 
    std::shared_ptr<int> sp(new int); 
} 

與最近emsdk使用命令等

em++ -std=c++11 -s DISABLE_EXCEPTION_CATCHING=1 -s NO_FILESYSTEM=1 \ 
    -s NO_BROWSER=1 -s NO_EXIT_RUNTIME=1 -O3 -o foo.js foo.cc 

所得文件超過400K大編譯此。隨着-g在我拋出能做

grep -n '^function _' foo.js | c++filt -_ 

,看看我們有什麼樣的功能有。這裏有一些例子:

std::__1::moneypunct<char, false>::do_thousands_sep() const 
std::__1::locale::~locale() 
std::__1::basic_string<wchar_t, …>::~basic_string() 
std::__1::time_get<…>::__get_day(…) const 
std::__1::codecvt<wchar_t, char, __mbstate_t>::codecvt(unsigned int) 
std::__1::locale::__imp::install(std::__1::locale::facet*, long) 
_printf_core 

我沒有調用任何這個我自己,但不過功能都包括在內。其中許多可能包含在某個虛函數表中。其他可能是由於一些靜態初始化器。

如果這是正常的代碼鏈接對我的硬盤上的某個單獨的共享庫;我不反對。但是,要傳輸JavaScript代碼中的半個字節,僅用於單個共享指針?必須有一種方法來避免這種情況。

回答

1

一個解決方案,實現了here,簡單地將C++庫分成幾部分。通過將處理I/O和語言環境的代碼移動到單獨的庫中,所有沒有此功能的代碼都可以避免導致依賴於上述功能的I/O子系統的靜態初始化程序。不幸的是,這也會影響strstream,原因很明顯。


更新:由於上游commit 301e4ad(最初包含在釋放1.30.6),系統庫不再編譯爲一個單一的文件*.bc,而是作爲包含幾個不同的對象一個*.a靜態庫。其中,只有實際需要的鏈接進來,這對於簡單情況下的代碼大小來說相當多。