【问题标题】:Omit some C++ subsystems省略一些 C++ 子系统
【发布时间】:2015-04-04 22:18:54
【问题描述】:

我注意到使用 emscripten,即使是相对较小的 C++ 文件也可以很快变成相当大的 JavaScript 文件。示例:

#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 代码,只是为了一个共享指针?必须有办法避免这种情况。

【问题讨论】:

    标签: javascript c++ emscripten libc++


    【解决方案1】:

    实现here 的一个解决方案是将C++ 库简单地拆分为几个部分。通过将处理 I/O 和语言环境的代码移动到单独的库中,所有可以在没有它的情况下工作的代码都可以避免 I/O 子系统的静态初始化程序导致对上述函数的依赖。不幸的是,这也会影响strstream,原因很明显。


    更新: 由于上游 commit 301e4ad(首次包含在版本 1.30.6 中),系统库不再编译为单个 *.bc 文件,而是编译为 *.a 静态文件包含几个不同对象的库。其中,只有需要的才真正链接进去,这大大减少了简单案例的代码大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-06
      相关资源
      最近更新 更多