首页 > 解决方案 > 使用 emscripten 构建项目 - 卡在 acorn-optimizer

问题描述

我正在编写一个中型 C++ 程序(大约 900 行;很多模板,惯用的 C++,只有 RAII 和集合,没有原始数组,没有指针,没有手动内存分配)。我的应用程序的本地构建大约需要 5 分钟,但问题从 emscripten 构建开始。

Webassembly 会在几秒钟内相对较快地发出。在尝试优化 libstdc++ 运行时 (?) 的 acorn-optimizer 上构建停滞。它已经运行了 20 分钟,我尝试重新运行并多次杀死它以使其构建我的应用程序。

我使用以下命令行:

em++ -std=c++20 -o tau.html lexer.cpp symtab.cpp parser.cpp decl.cpp tau.cpp -O3 -s WASM=1

em++使用以下命令行启动进程:

/usr/bin/node /usr/share/emscripten/tools/acorn-optimizer.js /tmp/emscripten_temp_gwg74gkp/tau.js AJSDCE minifyWhitespace

它一直在使用我的处理器的一个核心和大约 50MB(波动)的 RAM,因此,编译没有完成。

在此处输入图像描述

tau.js内容如下:链接。我设法(在某种程度上)找到了这个问题——一个 800 行的 C++ 项目对于 Emscripten 来说似乎太大了。asm.js 输出在-g3 -O0构建时远远超过 6 兆字节(不运行压缩器的那个)

在此处输入图像描述

我对 Emscripten ABI 的低效和可怕感到惊讶。

我的问题如下 - 我如何让这个项目构建和优化?每次我想编译某些东西时,我是否必须在一夜之间离开构建?有没有更好的工具来编译 C++ 并以 webasm 或 asm.js 为目标?

我放弃-O3并决定尝试-O1,但没有成功 - 编译器崩溃:

em++ -std=c++20 -o tau.html lexer.cpp symtab.cpp parser.cpp decl.cpp tau.cpp -O1 -s WASM=0
Traceback (most recent call last):
  File "/usr/share/emscripten/em++.py", line 14, in <module>
    sys.exit(emcc.run(sys.argv))
  File "/usr/share/emscripten/emcc.py", line 2156, in run
    post_link(options, wasm_target, wasm_target, target)
  File "/usr/share/emscripten/emcc.py", line 2320, in post_link
    generate_html(target, options, js_target, target_basename,
  File "/usr/share/emscripten/emcc.py", line 3075, in generate_html
    minify_html(target)
  File "/usr/share/emscripten/emcc.py", line 3049, in minify_html
    shared.check_call(['htmlmin', opts, '--', filename, filename])
  File "/usr/share/emscripten/tools/shared.py", line 104, in check_call
    return run_process(cmd, *args, **kw)
  File "/usr/share/emscripten/tools/shared.py", line 94, in run_process
    ret = subprocess.run(cmd, check=check, input=input, *args, **kw)
  File "/usr/lib/python3.9/subprocess.py", line 505, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/usr/lib/python3.9/subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.9/subprocess.py", line 1756, in _execute_child
    self.pid = _posixsubprocess.fork_exec(
TypeError: expected str, bytes or os.PathLike object, not list
make: *** [Makefile:44: webasm] Error 1

我也试过-g3 -O0了,但输出代码不起作用:

在此处输入图像描述

emscripten for -g3 -O0 的 7zip 压缩输出如下:link。我不认为我的源代码在这里很重要——这个问题显然发生在 emscripten 运行时中。

郑重声明,我用的是今年 1 月 24 日,也就是 2021 年使用 emsdk 构建的 emscripten。

我选择 asm.js 还是 webasm 目标并不重要,因为阻碍编译的瓶颈是修改 emscripten 生成的样板 JS(如果 C++ 代码不够的话,这足以让编译器停止工作)。

标签: c++emscriptenasm.js

解决方案


推荐阅读