Emstripten可以编译iostream库吗?

时间:2015-07-09 00:00:25

标签: 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 ++程序来成功编译。

1 个答案:

答案 0 :(得分:1)

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

不幸的是,我的理解是这是emscripten和apt-get等自动安装程序的常见问题 - 我的Mac上有端口和brew这个问题。

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

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