2015-04-04 16 views
6

Mi accorgo che con l'uso di emscripten, anche i file C++ relativamente piccoli possono essere trasformati rapidamente in file JavaScript piuttosto enormi. Esempio:Omettere alcuni sottosistemi C++

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

compilare questo con un recente emsdk usando un comando come

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 

Il file risultante è di oltre 400k grande. Con -g gettato in quello che posso fare

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

e vedere che tipo di funzioni che abbiamo lì. Ecco alcuni esempi:

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 

Non sto chiamando nulla di ciò, ma comunque le funzioni vengono incluse. Probabilmente molti di questi sono inclusi in alcune tabelle di funzioni virtuali. Gli altri potrebbero essere dovuti ad alcuni inizializzatori statici.

Se questo fosse il normale codice collegato a una singola libreria condivisa da qualche parte sul mio HDD; Non obietterò. Ma mezzo megabyte nel codice JavaScript da trasferire, solo per un singolo puntatore condiviso? Ci deve essere un modo per evitarlo.

risposta

1

Una soluzione, implementata here, divide semplicemente la libreria C++ in diverse parti. Spostando il codice che si occupa di I/O e locale in una libreria separata, tutto il codice che può funzionare senza questo può evitare l'inizializzatore statico del sottosistema I/O che porta ad una dipendenza dalle funzioni sopra descritte. Sfortunatamente ciò influirà anche su strstream, per ovvi motivi.


Aggiornamento: Dal monte commit 301e4ad (prima incluso nella versione 1.30.6), le librerie di sistema non sono più compilati come un unico file *.bc, ma invece come una libreria statica *.a che contiene diversi oggetti distinti. Di questi, solo quelli richiesti vengono effettivamente collegati, il che riduce parecchio le dimensioni del codice per i casi semplici.

Problemi correlati