缩写释义
WASM : WebAssembly
VSCode : Visual Studio Code
CMake
使用 3.21 以上版本,下载解压到磁盘后,追加目录路径到环境变量 PATH
Ninja
下载解压到磁盘后,追加目录路径到环境变量 PATH
Wasmtime 解释器
下载解压到磁盘后,将目录路径追加到环境变量 PATH
WASI-SDK 编译器
下载解压到磁盘后,将目录路径设置到环境变量 WASM_SDK_HOME
在确认所有依赖已经准备完毕后,进行工程的 VSCode 工作区配置
在 .vscode
目录中创建两个文件 cmake-kits.json
和 c_cpp_properties.json
编辑为以下内容
配置 WASM 编译器工具链,指定使用 wasi-sdk
。
[
{
"name":"wasi-sdk",
"toolchainFile": "${env:WASI_SDK_HOME}/share/cmake/wasi-sdk.cmake",
"cmakeSettings": {
"WASI_SDK_PREFIX":"${env:WASI_SDK_HOME}"
}
}
]
配置代码自动提示。
{
"configurations": [
{
"name":"WASM",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "${env:WASI_SDK_HOME}/bin/clang++",
"cStandard": "c11",
"cppStandard": "c++20",
"intelliSenseMode": "clang-arm",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version":4
}
注意: 如果使用 VSCode 进行远程开发,发现工作不正常,可以尝试将 ${env:WASI_SDK_HOME}
替换为全路径。
由于编译的结果是 wasm 文件,无法直接执行,我们需要使用 wasmtime
加载和启动编译后的 wasm 文件。
配置调试启动项,这里使用 CodeLLDB
调试启动 wasmtime
。
.vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Launch",
"program": "wasmtime",
"args": ["-g","${command:cmake.launchTargetPath}"],
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "PATH",
"value": "${env:PATH}:${command:cmake.getLaunchTargetDirectory}"
}
],
"initCommands": [
"settings set plugin.jit-loader.gdb.enable on"
]
}
]
}
注意: 如果使用 VSCode 进行远程开发,发现工作不正常,可以尝试将 wasmtime
替换为全路径。
创建 main.cpp
和 CMakeLists.txt
由于 wasi-sdk
不支持 C++ 异常,这里关闭异常功能
// main.cpp
#include
#include
int fib(int n)
{
if (n == 1 || n == 2)
return 1;
return fib(n - 1) + fib(n - 2);
}
int main(int argc, char *argv[])
{
std::vector nums{4, 8, 16, 20, 24, 28, 32, 36, 40};
for (int n : nums)
{
int res = fib(n);
printf("fib(%d) -> %d \n", n, res);
}
return 0;
}
# CMakeLists.txt
cmake_minimum_required (VERSION 3.16)
project(main CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -fno-exceptions")
add_executable(
main.wasm
main.cpp
)
Build Variant
选择 Debug
或 RelWithDebInfo
按下 F5 运行,输出
wasmtime
加载 wasm 文件后,会在 JIT 模式下运行,LLDB 支持调试 JIT 后的脚本代码。我们可以直接在 C++ 源码中设置断点。
使用第三方库时,与普通的 CMake 工程一致。
这里使用 zlib-ng 进行演示
修改 CMakeLists.txt
文件,修改为
cmake_minimum_required (VERSION 3.16)
project(main CXX)
include(FetchContent)
FetchContent_Declare(zlib
URL https://gitee.com/HangedFish/zlib-ng/repository/archive/2.0.6-patched-wasm32?format=tar.gz
)
set(ZLIB_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
set(ZLIB_COMPAT ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(zlib)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -fno-exceptions")
add_executable(
main.wasm
main.cpp
)
target_link_libraries(
main.wasm
zlibstatic
)
修改 main.cpp
#include
#include
#include
#include
int main(int argc, char *argv[])
{
using namespace std;
int a = 128;
uint8_t dest[4096]{};
string str{
"11111111122222222222333333333333"
"44444444455555555666677777777777"
"88888888889999999990000000000000"};
cout << "str='" << str << "'" << endl;
size_t dest_size = 4096;
int ok = compress(dest, &dest_size, (uint8_t *)str.data(), str.size());
cout << "string_size=" << str.size() << endl;
cout << "compressed_size=" << dest_size << endl;
uint32_t sum = crc32(0, (uint8_t *)str.data(), str.size());
cout << "crc32sum(str)=" << sum << endl;
return 0;
}
按 F5 运行,输出
原创文章,转载或引用请注明出处