搭建webassembly开发环境

概要

介绍emscripten工具链、emsdk在mac系统下的安装。然后emsdk的常用使用方法,包括简单的命令行以及搭配cmake的使用。

emscripten简介

Emscripten是一个开源工具链,用于将C、C++等语言编译成高性能的WebAssembly(Wasm)代码,从而使这些语言可以在浏览器中运行。它基于LLVM编译器框架,允许开发者将现有的C和C++代码转换为在Web浏览器中运行的JavaScript代码。

Emscripten的工作原理是将C/C++代码编译成LLVM的中间表示(IR),然后利用LLVM将IR编译成Wasm代码。最终,Emscripten会生成JavaScript代码,充当Wasm模块的加载器,并提供API来与Wasm模块进行交互。

这种工具链的使用场景非常广泛,特别是对于需要在浏览器环境中运行高性能代码的应用程序。通过Emscripten,开发者可以将现有的C/C++项目移植到Web平台,实现跨平台的运行,同时也能够利用Wasm的优势,例如更高的性能和更好的安全性。

Emscripten也提供了一些工具和库,帮助开发者处理文件、网络、图形等方面的任务,并为Wasm模块提供了与JavaScript交互的能力,使得在浏览器中运行的应用程序能够与Web页面进行有效的交互。

emsdk安装

Emscripten Software Development Kit(简称emSDK或emscripten SDK)是一个用于安装、管理和使用Emscripten工具链的工具集合。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 下载emsdk仓库
git clone https://github.com/emscripten-core/emsdk.git

# 进入仓库目录
cd emsdk

# 下载和安装最新版本的sdk
./emsdk install latest

# 激活当前安装最新的sdk
./emsdk activate latest

# 在当前的终端中活环境变量
source ./emsdk_env.sh

安装完成后,查看工具版本,有以下提示,说明安装成功

1
2
3
4
5
6
➜  emsdk git:(main) emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.34 (57b21b8fdcbe3ebb523178b79465254668eab408)
clang version 17.0.0 (https://github.com/llvm/llvm-project a031f72187ce495b9faa4ccf99b1e901a3872f4b)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /path_to_emsdk/emsdk/upstream/bin

emsdk使用

命令行指令

emcc 是 Emscripten 工具链中用于编译 C 和 C++ 代码到 WebAssembly 的主要命令。它提供了许多选项和参数,用于配置编译器和生成的输出。以下是一些 emcc 命令的常用选项和用法:

  1. 基本用法:

    • emcc source.c -o output.js: 编译 source.c 文件为 output.js,生成的 JavaScript 文件包含 WebAssembly 模块和加载器。
    • emcc source.cpp -o output.html: 将 C++ 文件编译成 output.html 文件,自动生成一个包含模块和加载器的 HTML 文件。
  2. 编译到 WebAssembly:

    • -O<level>: 设置优化级别,如 -O1, -O2, -O3,默认是 -Oz,最小化输出文件大小。
    • --llvm-lto <level>: 开启 LLVM 的链接时优化。
    • -s WASM=1: 明确指定输出 WebAssembly 模块。
    • -s SIDE_MODULE=1: 生成一个 WebAssembly 侧模块,用于和其他模块链接。
  3. 生成 JavaScript 模块:

    • -s EXPORTED_FUNCTIONS='["_functionName"]': 导出 C 函数,使其可在 JavaScript 中调用。
    • -s EXTRA_EXPORTED_RUNTIME_METHODS='["functionName"]': 导出 Emscripten 运行时 API。
  4. 与 JavaScript 交互:

    • -s MODULARIZE=1: 将输出模块化,以便在其他 JavaScript 文件中导入。
    • -s ALLOW_MEMORY_GROWTH=1: 允许内存动态增长。
  5. 其他选项:

    • -I<path>: 添加包含文件路径。
    • -L<path>: 添加库文件路径。
    • --pre-js <file.js>: 在输出文件前插入 JavaScript 代码。
    • --post-js <file.js>: 在输出文件后插入 JavaScript 代码。

emcc 提供了大量的选项和参数,允许开发者根据需要进行灵活的配置和定制。这些选项可以帮助控制编译器行为、优化输出、管理内存等,使得开发者能够更好地控制生成的 WebAssembly 模块和 JavaScript 代码的行为和性能。

搭配cmake

新建一个main.cpp文件,写上测试程序,然后基于以下的CMakeLists构建

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
cmake_minimum_required(VERSION 3.10)
project(MyWasmProject)

# 设置编译器为 Emscripten
set(CMAKE_C_COMPILER emcc)
set(CMAKE_CXX_COMPILER em++)

# 添加源文件
add_executable(my_wasm_project main.cpp)

# 指定生成的输出类型为 WebAssembly
set_target_properties(my_wasm_project PROPERTIES
    SUFFIX ".html"
    LINK_FLAGS "--bind -s WASM=1"
)

然后新建build目录

1
2
3
cd build/
emcmake cmake ..
cmake --build .

这里使用了 emcmake 命令来调用 CMake,它会设置 Emscripten 的工具链并确保正确的构建过程。完成构建后,在浏览器中打开生成的 HTML 文件,通常这个文件会在构建目录中生成。如

1
2
3
4
5
6
7
├── CMakeCache.txt
├── CMakeFiles
├── Makefile
├── cmake_install.cmake
├── my_wasm_project.html
├── my_wasm_project.js
└── my_wasm_project.wasm

参考文献

1-about_emscripten


微信公众号