Emscripten介绍
WebAssembly是一种面向Web的二进制格式,不是一种编程语言,它是一种可移植、高性能、低级别的虚拟机。它是由W3C(万维网联盟)设计的一种新型的Web标准,旨在通过在Web浏览器中运行高性能的本机二进制代码,提供更快速、更安全的Web应用程序。
Emscripten是一个用于将C/C 代码编译为Wasm字节码的工具链。我们也可以用他来将Typescript(搭配tsc)编译成 LLVM字节码。
emsd 是一个基于Python的全平台(Windows、Mac、Linux)的开发工具,主要用于管理和使用emscripten编译器。emsdk的主要功能包括:安装、卸载emscripten以及相关工具链,切换不同版本的emscripten编译器,管理运行时模块(即.s和.js文件),支持WebAssembly生成和优化等。别外,
编译原理: Emscripten编译优化分为两个步骤
- 每个源文件编译成目标文件(.bc文件),通过LLVM优化
- 目标文件编译成js文件
中文网:emcc.zcopy.site/
安装Emscripten
安装python 3.6+
网上与Python官网的指南都很清晰明了,此处(略) .
安装git
网上与git官网的指南都很清晰明了.
安装emsdk (Emscripten安装器,工具包)
Get the emsdk source
# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git
# Enter that directory
cd emsdk
拉取最新代码并激活
git pull
# 记得一定要加 --system
./emsdk install --system latest
./emsdk activate latest
# Activate PATH and other environment variables in the current terminal
# in linux
# source ./emsdk_env.sh
更新emsdk
# Fetch the latest registry of available tools.
emsdk update
# Download and install the latest SDK tools.
# 加 --system
emsdk install --system latest
# Set up the compiler configuration to point to the "latest" SDK.
emsdk activate latest
配置emsdk和emcc环凌变量
输入
# Activate PATH and other environment variables in the current terminal
#source ./emsdk_env.sh
emsdk_env.bat
会有如下输了
Setting up EMSDK environment (suppress these messages with EMSDK_QUIET=1)
Adding directories to PATH:
PATH += D:\software\emsdk
Setting environment variables:
PATH = D:\software\emsdk;D:\tmp\emsdk;C:\Program Files\NVIDIA GPU Computing
...
EMSDK = D:/software/emsdk
Clearing existing environment variable: EMSDK_PY
根据上述我们对环境变量做如下配置: EMSDK:
PATH:
linux的话是在/etc/profile文件内
验证安装
emcc -v
到这里 Emscripten 已经成功安装完成了,配置完 PATH 后即可在全局调用此命令,接下来就可以将 C或ts(后者需要搭ts) 代码编译成 wasm 文件了。
激活其他版本
# Get list of the old versions of the tool.
./emsdk list --old
# Install the required version.
./emsdk install <name_of_tool>
# Activate required version.
./emsdk activate <name_of_tool>
更多信息:emscripten.org/docs/tools_…
用Emscripten将C/C++编译为wasm文件
配置vscode
也可以用其他工具,这时笔者主要使用vscode做该demo。
配置VS Code。如果您使用Visual Studio Code,可以按照以下步骤配置:
- 在VS Code中打开一个新窗口
- 按下F1,在命令栏中输入“C/C++: Edit Configurations”并选择它
- 在弹出的窗口中添加以下配置:
{
"name": "emscripten",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:/emsdk/emscripten/1.38.22/em++.bat",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "windows-gcc-x64"
}
准备文件
hello.cpp
#include <stdio.h>
int main() {
printf("hello, world!\n");
return 0;
}
编译成js
./emcc hello.cpp
目录下会生成a.out.js and a.out.wasm两个文件
Node测试
node a.out.js
控制台会输出hello, world
更多命令
生成html - 用于测试
emcc hello.cpp -o hello.html
在浏览器打开hello.html,可看到效果。
转成wast可读文件
wasm2wat hello.wasm -o hello.wast
先编译成js + 再指定导出的的方法
准备 index.cpp 文件
int add(int x, int y)
{
return x + y;
}
int min(int x, int y)
{
if (x>y){
return y;
} else {
return x
}
}
编译
以下命令执行完将会生成 index.index.wasm两个文件。
emcc index.cpp -o index.js -s EXPORTED_FUNCTIONS='["_add","_min"]' -O3 -s wasm=1
参数说明:
EXPORTED_FUNCTIONS
指的是导出的函数,需要和源文件里的函数名是相对应的(比原函数名多了一个"_"前缀)
O3
是编译优化等级,只有这个等级生成的wasm文件才会很小(几十字节),不加该优化选项,生成的wasm将会有几十KB。生成的时候会临时产生*.asm.js,等生成完后,会自动删掉。
编写test.js
var em_module = require('./index.js');
console.log("add:"+em_module._add(4,5));
console.log("add:"+em_module._min(5,4));
用node.js测试
Node node-test.js