javascript - Emstripten 可以编译 iostream 库吗?

标签 javascript c++ iostream emscripten asm.js

我在 Ubuntu 上。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.2 LTS
Release:    14.04
Codename:   trusty

我安装了 Emscripten .

$ sudo apt-get install emscripten

我写了下面的 C++ 程序:

#include <iostream>

int main(){
  printf("hello world\n");
}

它按预期编译。

$ emcc -O1 -s ASM_JS=1 main.cpp
$

但是,当我使用 iostream 工具编写类似的程序时:

#include <iostream>

int main(){
  std::cout << "hello world" << std::endl;
}

构建失败。

$ emcc -O1 -s ASM_JS=1 main.cpp
aborting from js compiler due to exception: unknown vector type <4 x i8> | undefined
aborting from js compiler due to exception: unknown vector type <4 x i8> | undefined
aborting from js compiler due to exception: unknown vector type <4 x i8> | undefined
Traceback (most recent call last):
  File "/usr/share/emscripten/emscripten.py", line 1352, in <module>
    _main(environ=os.environ)
  File "/usr/share/emscripten/emscripten.py", line 1340, in _main
    temp_files.run_and_clean(lambda: main(
  File "/usr/share/emscripten/tools/tempfiles.py", line 39, in run_and_clean
    return func()
  File "/usr/share/emscripten/emscripten.py", line 1348, in <lambda>
    DEBUG_CACHE=DEBUG_CACHE,
  File "/usr/share/emscripten/emscripten.py", line 1235, in main
    jcache=jcache, temp_files=temp_files, DEBUG=DEBUG, DEBUG_CACHE=DEBUG_CACHE)
  File "/usr/share/emscripten/emscripten.py", line 292, in emscript
    assert len(output) == 2, 'Did not receive forwarded data in an output - process failed? We only got: ' + output[0][-3000:]
AssertionError: Did not receive forwarded data in an output - process failed? We only got: ((HEAP32[(($1)>>2)])|0);
 $3=((($2)-(12))|0);
 $4=$3;
 $5=((HEAP32[(($4)>>2)])|0);
 $6=$this;
 $_sum=((($5)+(24))|0);
 $7=(($6+$_sum)|0);
 $8=$7;
 $9=((HEAP32[(($8)>>2)])|0);
 $10=($9|0)==0;
 if ($10) {
  STACKTOP=sp;return (($this)|0);
 }
 $12=(($__s)|0);
 HEAP8[($12)]=0;
 $13=(($__s+4)|0);
 HEAP32[(($13)>>2)]=$this;
 $_sum_i=((($5)+(16))|0);
 $14=(($6+$_sum_i)|0);
 $15=$14;
 $16=((HEAP32[(($15)>>2)])|0);
 $17=($16|0)==0;
 do {
  if ($17) {
   $_sum1_i=((($5)+(72))|0);
   $19=(($6+$_sum1_i)|0);
   $20=$19;
   $21=((HEAP32[(($20)>>2)])|0);
   $22=($21|0)==0;
   if (!($22)) {
    $24=((__ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5flushEv($21))|0);
   }
   HEAP8[($12)]=1;
   $26=((HEAP32[(($1)>>2)])|0);
   $27=((($26)-(12))|0);
   $28=$27;
   $29=((HEAP32[(($28)>>2)])|0);
   $_sum1=((($29)+(24))|0);
   $30=(($6+$_sum1)|0);
   $31=$30;
   $32=((HEAP32[(($31)>>2)])|0);
   $33=$32;
   $34=$32;
   $35=((HEAP32[(($34)>>2)])|0);
   $36=(($35+24)|0);
   $37=((HEAP32[(($36)>>2)])|0);
   $38=((FUNCTION_TABLE_ii[($37)&{{{ FTM_ii }}}]($33))|0);
   $39=($38|0)==-1;
   if (!($39)) {
    break;
   }
   $41=((HEAP32[(($1)>>2)])|0);
   $42=((($41)-(12))|0);
   $43=$42;
   $44=((HEAP32[(($43)>>2)])|0);
   $45=(($6+$44)|0);
   $46=$45;
   $_sum2=((($44)+(16))|0);
   $47=(($6+$_sum2)|0);
   $48=$47;
   $49=((HEAP32[(($48)>>2)])|0);
   $50=$49|1;
   __ZNSt3__18ios_base5clearEj($46,$50);
  }
 } while(0);
 __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD2Ev($__s);
 STACKTOP=sp;return (($this)|0);
}


function __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv($this){
 $this=($this)|0;
 var $1=0,$2=0,$3=0,$4=0,$5=0,$6=0,$7=0,label=0;

 $1=(($this+16)|0);
 $2=((HEAP32[(($1)>>2)])|0);
 $3=$2|1;
 HEAP32[(($1)>>2)]=$3;
 $4=(($this+20)|0);
 $5=((HEAP32[(($4)>>2)])|0);
 $6=$5&1;
 $7=($6|0)==0;
 if ($7) {
  return;
 } else {
  ___cxa_rethrow();

 }
}


function __ZNSt3__113basic_istreamIwNS_11char_traitsIwEEED0Ev($this){
 $this=($this)|0;
 var $1=0,$2=0,label=0;

 $1=(($this+8)|0);
 __ZNSt3__18ios_baseD2Ev($1);
 $2=$this;
 __ZdlPv($2);
 return;
}


function __ZNSt3__113basic_istreamIwNS_11char_traitsIwEEED1Ev($this){
 $this=($this)|0;
 var $1=0,label=0;

 $1=(($this+8)|0);
 __ZNSt3__18ios_baseD2Ev($1);
 return;
}


function __ZTv0_n12_NSt3__113basic_istreamIwNS_11char_traitsIwEEED0Ev($this){
 $this=($this)|0;
 var $1=0,$2=0,$3=0,$4=0,$5=0,$6=0,$7=0,$_sum=0,$8=0,$9=0,label=0;

 $1=$this;
 $2=$this;
 $3=((HEAP32[(($2)>>2)])|0);
 $4=((($3)-(12))|0);
 $5=$4;
 $6=((HEAP32[(($5)>>2)])|0);
 $7=(($1+$6)|0);
 $_sum=((($6)+(8))|0);
 $8=(($1+$_sum)|0);
 $9=$8;
 __ZNSt3__18ios_baseD2Ev($9);
 __ZdlPv($7);
 return;
}


function __ZTv0_n12_NSt3__113basic_istreamIwNS_11char_traitsIwEEED1Ev($this){
 $this=($this)|0;
 var $1=0,$2=0,$3=0,$4=0,$5=0,$6=0,$_sum=0,$7=0,$8=0,label=0;

 $1=$this;
 $2=$this;
 $3=((HEAP32[(($2)>>2)])|0);
 $4=((($3)-(12))|0);
 $5=$4;
 $6=((HEAP32[(($5)>>2)])|0);
 $_sum=((($6)+(8))|0);
 $7=(($1+$_sum)|0);
 $8=$7;
 __ZNSt3__18ios_baseD2Ev($8);
 return;
}


Traceback (most recent call last):
  File "/usr/bin/emcc", line 1864, in <module>
    final = shared.Building.emscripten(final, append_ext=False, extra_args=extra_args)
  File "/usr/share/emscripten/tools/shared.py", line 1276, in emscripten
    assert os.path.exists(filename + '.o.js') and len(open(filename + '.o.js', 'r').read()) > 0, 'Emscripten failed to generate .js: ' + str(compiler_output)
AssertionError: Emscripten failed to generate .js:

我的印象是 Emscripten 已经走了很长一段路,能够为浏览器编译整个 C++ 游戏!为了成功编译 C++ 标准库的某些部分,我是否错过了某种标志或配置?我知道 clang/gcc 编译器默认会链接到 C++ 标准共享库。这个问题和你的想法有关系吗?

我也尝试使用命令 em++ 代替 emcc 并收到相同的错误消息。


如果相关,这里是第一次运行 emscripten 时构建的默认配置:

$ cat ~/.emscripten

# Note: If you put paths relative to the home directory, do not forget os.path.expanduser

import os

# this helps projects using emscripten find it
EMSCRIPTEN_ROOT = os.path.expanduser(os.getenv('EMSCRIPTEN') or '/usr/share/emscripten') # directory
LLVM_ROOT = os.path.expanduser(os.getenv('LLVM') or '/usr/bin') # directory
PYTHON = os.path.expanduser(os.getenv('PYTHON') or '/usr/bin/python2') # executable

# See below for notes on which JS engine(s) you need
NODE_JS = os.path.expanduser(os.getenv('NODE') or '/usr/bin/node') # executable
SPIDERMONKEY_ENGINE = [os.path.expanduser(os.getenv('SPIDERMONKEY') or 'js')] # executable
V8_ENGINE = os.path.expanduser(os.getenv('V8') or 'd8') # executable

JAVA = 'java' # executable

TEMP_DIR = '/tmp'

CRUNCH = os.path.expanduser(os.getenv('CRUNCH') or 'crunch') # executable

#CLOSURE_COMPILER = '..' # define this to not use the bundled version

########################################################################################################


# Pick the JS engine to use for running the compiler. This engine must exist, or
# nothing can be compiled.
#
# Recommendation: If you already have node installed, use that. Otherwise, build v8 or
#                 spidermonkey from source. Any of these three is fine, as long as it's
#                 a recent version (especially for v8 and spidermonkey).

COMPILER_ENGINE = NODE_JS
#COMPILER_ENGINE = V8_ENGINE
#COMPILER_ENGINE = SPIDERMONKEY_ENGINE


# All JS engines to use when running the automatic tests. Not all the engines in this list
# must exist (if they don't, they will be skipped in the test runner).
#
# Recommendation: If you already have node installed, use that. If you can, also build
#                 spidermonkey from source as well to get more test coverage (node can't
#                 run all the tests due to node issue 1669). v8 is currently not recommended
#                 here because of v8 issue 1822.

JS_ENGINES = [NODE_JS] # add this if you have spidermonkey installed too, SPIDERMONKEY_ENGINE]  

我似乎找不到让上面的基本 C++ 程序成功编译的方法。

最佳答案

首先,您的程序使用 emcc 编译对我来说很好。您的原始程序(使用 printf)使 emcc 假定它正在编译 C 代码,因此它将像 C 一样自动包含 stdio.h。你的第二个程序有更多的麻烦,可能是由于安装错误(对我来说,我遇到了这样的问题,因为我的 LLVM 版本与 Emscripten 所需的确切版本不一致。)

不幸的是,我的理解是这是 emscripten 和像 apt-get 这样的自动安装程序的常见问题——我在我的 Mac 上遇到了 port 和 brew 的问题。

解决方案是通过 SDK 获取 Emscripten,它将所有敏感部分捆绑在一起:https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html

仔细按照那里的说明进行操作。我遇到的两个问题是它期望 Python 2 在你的系统上被称为 python2 并且调整你的默认路径的脚本假设你正在使用 bash(如果你是,它应该工作正常。 )

关于javascript - Emstripten 可以编译 iostream 库吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31305893/

相关文章:

Javascript - 从表中删除项目名称?

javascript - KnockoutJS 删除动态绑定(bind)

c++ - FreeFileSync C++ 错误 : 'byte' is not a member of 'std'

c++ - 使用 std::deque 或 std::priority_queue 是线程安全的吗?

c++ - fscanf 与 ifstream 速度

python - 如何从Python IO流中删除最后一个字符

c++ - `ios_base` 的标志都是静态常量整型变量。为什么可以用 `ios_base::setf()` 改变它们?

javascript - 我如何使用 javascript 获取有关用户用于访问我的 asp.net webapp 的设备的信息?

javascript - Angular-App 如何引用其依赖项?

c++ - std::basic_string 是否正式具有隐式生成的 move 构造函数?