按照 MDN 给的教程跑一个 Hello World。
安装环境
安装 CMake:
sudo apt-get install cmake
cmake --version
CMake 可看作 C++ 项目的构建工具。
安装 GCC:
sudo apt-get install gcc
sudo apt-get install g++
也可以按照 VS Code 官网给的教程配置 C++ 开发环境。
安装 Emscripten SDK:
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit
./emsdk activate --global --build=Release sdk-incoming-64bit binaryen-master-64bit
# 如果报错 Error: No tool or SDK found by name 'sdk-incoming-64bit',就执行下面两行
./emsdk install latest
./emsdk activate latest
# 按照提示执行相应命令以配置环境变量
使用 Emscripten 时,可以先拉取 Emscripten 最新代码。如果有更新,需要重新执行 install、activate。
Hello World
hello.cpp 内容如下:
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!" << endl;
cout << "It's a WebAssembly demo." << endl;
}
如果终端重启,需要先切到 emsdk 目录下,执行:
source ./emsdk_env.sh
然后再切回 hello.cpp 所在目录,执行:
emcc hello.cpp -sWASM=1 -o hello.html
-sWASM=1
输出 Wasm。-o
-o hello.html
在当前目录下生成 HTML、JS、Wasm;-o hello.js
生成 JS、Wasm;-o hello.mjs
生成 ES6 模块和 Wasm 文件。
- MJS 文件导出一个函数,它接受的是 Wasm 模块初始化参数(HTML 模板中有初始化参数相关示例),并以 Promise 的形式将初始化完成后的模块
Module
resolve 出来,Module
上绑定了 JS 中可以调用的所有 API。
成功运行后可以在控制台看到:
从 Wasm 导出函数
fibonacci.cpp 内容如下:
#include <emscripten/emscripten.h>
// 避免 C++ name mangling
#ifdef __cplusplus
extern "C" {
#endif
// EMSCRIPTEN_KEEPALIVE 避免无用代码删除(dead code elimination)
int EMSCRIPTEN_KEEPALIVE fibonacci(int n) {
if (n <= 1) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}
#ifdef __cplusplus
}
#endif
编译 Wasm 和 JS:
emcc fibonacci.cpp -O3 -sWASM=1 -sEXPORTED_RUNTIME_METHODS=cwrap -o fibonacci.mjs
-O3
:指定优化等级。-sEXPORTED_RUNTIME_METHODS=cwrap
:在Module
上暴露cwrap
。
EXTRA_EXPORTED_RUNTIME_METHODS
已废弃。- 对于
fibonacci
,如果不开-O3
优化,可能还没 JS 快;有些计算,比如前 n 个数的立方和,开了-O3
,可能也还没 JS 快;具体原因还没搞清楚。
在 JS 中使用 cwrap
包装后即可使用:
const fibonacci = Module.cwrap("fibonacci", "number", ["number"]);
console.log(fibonacci(38));