1. 背景
WebAssembly是一种运行在现代网络浏览器中的新型代码并且提供新的性能特性和效果。
它设计的目的不是为了手写代码而是为诸如C、C++和Rust等低级源语言提供一个高效的编译目标。
WebAssembly是一门低级的类汇编语言。
它有一种紧凑的二进制格式,使其能够以接近原生性能的速度运行并且为诸如C++和Rust等拥有低级的内存模型语言提供了一个编译目标以便它们能够在网络上运行。
2. 准备工作
(1)安装homebrew
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
(2)安装cmake
$ brew install cmake
(3)编译Emscripten
$ git clone https://github.com/juj/emsdk.git
$ cd emsdk
$ ./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit # 大概需要1个小时
$ ./emsdk activate --global --build=Release sdk-incoming-64bit binaryen-master-64bit
$ source ./emsdk_env.sh
注:
(1)--global
标识会让PATH
变量在全局被设置,所以接下来所打开的终端或者命令行窗口都会被设置。
如果仅仅想让Emscripten在当前窗口生效,就删掉这个标识。
(2)每当想要使用Emscripten时,尝试从远程更新最新的Emscripten代码是个很好的习惯(运行 git pull
)。
如果有更新,重新执行 install
和 activate
命令。
这样就可以确保您使用的Emscripten一直保持最新。
3. 例子
当使用Emscripten来编译的时候有很多种不同的选择,我们介绍其中主要的2种:
(1)编译到 wasm 并且生成一个用来运行我们代码的HTML,将所有 wasm 在web环境下运行所需要的 “胶水” JavaScript代码都添加进去。
(2)编译到 wasm 然后仅仅生成 JavaScript。
3.1 生成HTML
新建hello.c
文件,
#include <stdio.h>
int main(int argc, char ** argv) {
printf("Hello World\n");
}
使用Emscripten编译,
$ emcc hello.c -s WASM=1 -o hello.html
其中,
(1)-s WASM=1
指定了我们想要的wasm输出形式。
如果我们不指定这个选项,Emscripten默认将只会生成asm.js。
(2)-o hello.html
指定这个选项将会生成HTML页面来运行我们的代码,
并且会生成wasm模块以及编译和实例化wasm模块所需要的“胶水”js代码,这样我们就可以直接在web环境中使用了。
编译生成的目录结构为,
.
├── hello.c
├── hello.html
├── hello.js
└── hello.wasm
注:
在浏览器中不能直接打开hello.html
,而是要在本地启动一个静态资源服务器,
$ http-server
Starting up http-server, serving ./
Available on:
http://127.0.0.1:8080
http://30.37.60.47:8080
Hit CTRL-C to stop the server
然后,通过以下url访问,http://127.0.0.1:8080/hello.html
。
其中,http-server是一个由node启动的http服务器。
3.2 生成JavaScript
通过用.js
取代.htm(l)
作为文件后缀名,你就可以得到只有JavaScript的输出文件,而不再是完整的HTML文件。
$ emcc hello.c -s WASM=1 -o hello.js
目录结构如下,
.
├── hello.c
├── hello.js
└── hello.wasm
尽管如此,不推荐这样做。
因为Emscripten需要大量的JavaScript“胶水”代码从而能够处理内存分配、内存泄漏以及大量的其他问题。
这些问题都已经在提供的模板中得到了处理,使用模板要比自己编写模板要容易得多。
4. 自定义HTML模板
我们可以使用--shell-file xxx.html
编译参数来指定自定义的HTML模板,
例如,可以在./emsdk
文件夹中搜索一个叫做shell_minimal.html
的文件,然后复制出来,
位置在这里,./emsdk/emscripten/incoming/src/shell_minimal.html
。
进行如下编译,
$ emcc hello.c -s WASM=1 -o hello.html --shell-file shell_minimal.html
参考
MDN: WebAssembly概念
MDN: 编译 C/C++ 为 WebAssembly
github: http-server