在 Visual Studio Code 创建 C/C++ 的 WebAssembly 开发环境

在 Visual Studio Code 创建 C/C++ 的 WebAssembly 开发环境

  • 安装依赖
    • VSCode 扩展
  • VSCode 工作区配置
    • 配置工具链
      • cmake-kits.json
      • c\_cpp\_properties.json
    • 配置启动
      • launch.json
    • 工程结构
  • 创建 C++ 项目
    • 运行
    • 调试
  • 使用第三方库

缩写释义
WASM : WebAssembly
VSCode : Visual Studio Code

安装依赖

  • CMake
    使用 3.21 以上版本,下载解压到磁盘后,追加目录路径到环境变量 PATH

  • Ninja
    下载解压到磁盘后,追加目录路径到环境变量 PATH

  • Wasmtime 解释器
    下载解压到磁盘后,将目录路径追加到环境变量 PATH

  • WASI-SDK 编译器
    下载解压到磁盘后,将目录路径设置到环境变量 WASM_SDK_HOME

VSCode 扩展

  • CodeLLDB
  • C/C++ Extension Pack

VSCode 工作区配置

在确认所有依赖已经准备完毕后,进行工程的 VSCode 工作区配置

配置工具链

.vscode 目录中创建两个文件 cmake-kits.jsonc_cpp_properties.json 编辑为以下内容

cmake-kits.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}"
        }
    }
]

c_cpp_properties.json

配置代码自动提示。

{
   "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 文件。

launch.json

配置调试启动项,这里使用 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 替换为全路径。

工程结构

创建 C++ 项目

创建 main.cppCMakeLists.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
)

工程结构
在 Visual Studio Code 创建 C/C++ 的 WebAssembly 开发环境_第1张图片

运行

Build Variant 选择 DebugRelWithDebInfo
在这里插入图片描述

按下 F5 运行,输出

在 Visual Studio Code 创建 C/C++ 的 WebAssembly 开发环境_第2张图片

调试

wasmtime 加载 wasm 文件后,会在 JIT 模式下运行,LLDB 支持调试 JIT 后的脚本代码。我们可以直接在 C++ 源码中设置断点。

在 Visual Studio Code 创建 C/C++ 的 WebAssembly 开发环境_第3张图片

使用第三方库

使用第三方库时,与普通的 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 运行,输出

在 Visual Studio Code 创建 C/C++ 的 WebAssembly 开发环境_第4张图片

原创文章,转载或引用请注明出处

你可能感兴趣的:(WebAssembly实战指南,vscode,c++,c语言)