从免费的c++online编译到跨平台WASM机制的学习
使用cplusplus.com的时候,你会发现demo 代码可以点击运行。
其运行的后端是https://cpp.sh/about.html
一个叫做cpp.sh的服务。
看描述,其是把c++代码上传到服务端执行编译,并生成web assmebly code 返回给浏览器。
然后我们的浏览器在本地帮我们运行这个代码,并把结果输出到了我们的浏览器ui上面。
C++ Shell v2, free online compiler, proudly uses emscripten to compile your code.
emscripten is a clang-based compiler toochain that produces WebAssembly code, which can run directly in most modern browsers.
Using cpp.sh, your code is compiled on the server, and its wasm-code equivalent is produced. This code is then safely run locally in a Web Worker on your own browser.
Please, note that due to the limitations of the target platform, certain system calls may fail.
Comments and error reports to: admin@cppshell.com
是不是玩的很6.
于是看了下wasm的生成例子,看看他多了些什么步骤。
https://emscripten.org/docs/getting_started/Tutorial.html。
发现其描述可以一个代码,生成wasm code后可以运行到浏览器,服务器,边缘设备,
而且cpu指令无感,可以是x86, arm,risc-v等。还是能节约不少效率。
继而咨询元宝-Deepseek-r1, 其反馈运行的时候有一个wasm解析器帮忙把wsm code最终翻译成运行时环境的机器吗。
哪这里有点意思了,因为我们知道这种类似的实现较多,但为什么还要搞出这个呢。
我们看看python javascript 这些都是跨平台的, 需要虚拟机支持。但是其效率会很差。
据wasm code反馈其效率接近c的代码效率。而且支持c c++ rust代码生成wasm code。
wasmcode支持沙箱隔离,可以限制宿主机的文件系统和网络的访问, 不过编译当然也可以打开。避免多线程应用的内存问题。内存隔离。
咨询AI后给了一个实际例子
其可以利用x86 c++代码的能力完成移植到arm risc-v
分步解释
是的,通过以下流程可以实现跨平台部署,但需满足运行时环境要求:
1. 跨平台编译流程
- 步骤 1:在 CentOS x86 上编写 C++ 代码,通过 Emscripten 或 Clang/LLVM 编译为 .wasm 文件。
- 示例命令(使用 Emscripten):
- bash
- emcc main.cpp -o output.wasm
- 关键点:此时生成的 .wasm 文件是平台无关的,不绑定 x86 或 ARM。
- 步骤 2:将 output.wasm 文件部署到 CentOS ARM 服务器,无需重新编译。
2. ARM 服务器上的执行工具
要在 ARM 平台上运行 Wasm 代码,需安装 Wasm 运行时环境,常见选项包括:
选项 1:WasmEdge(推荐)
- 安装方法(CentOS ARM):
- bash
- curl -sSL https://github.com/WasmEdge/WasmEdge/releases/latest/download/WasmEdge-<version>-manylinux2014_aarch64.rpm -o wasmedge.rpm sudo rpm -i wasmedge.rpm
- 运行命令:
- bash
- wasmedge output.wasm
选项 2:Node.js(内置 Wasm 支持)
- 安装 Node.js:
- bash
- curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt-get install -y nodejs
- 运行代码:
- javascript
- // 创建 test.js 文件 const fs = require('fs'); const wasmBuffer = fs.readFileSync('output.wasm'); WebAssembly.instantiate(wasmBuffer).then(module => { module.instance.exports._start(); // 调用入口函数 });
- bash
- node test.js
选项 3:Wasmtime
- 安装方法:
- bash
- curl -sSf https://wasmtime.dev/install.sh | bash
- 运行命令:
- bash
- wasmtime output.wasm
3. 跨平台验证
- 验证原理:
Wasm 的虚拟指令集(如 i32.add)在 ARM 服务器上由运行时动态编译为本机指令(ARM 机器码),无需开发者手动适配。 - 示例场景:
在 x86 上编译的数学计算 Wasm 模块,可直接在 ARM 服务器上通过 WasmEdge 运行,结果一致。
4. 潜在限制与解决方案
限制 1:系统调用依赖
- 问题:若 C++ 代码调用了 Linux 系统函数(如 open()、write()),需通过 WASI 接口实现跨平台。
- 解决方案:
编译时启用 WASI 支持: - bash
- emcc main.cpp -o output.wasm -s WASI=1
- 运行时通过 --dir 等参数授权文件访问:
- bash
- wasmedge --dir=. output.wasm
限制 2:线程支持
- 问题:Wasm 的线程模型依赖宿主环境实现。
- 解决方案:
使用支持线程的运行时(如 WasmEdge 0.12+),编译时启用线程选项: - bash
- emcc main.cpp -o output.wasm -pthread -s PROXY_TO_PTHREAD
总结
- 跨平台能力:同一 Wasm 文件可在 x86/ARM 上运行,无需重新编译。
- 依赖工具:目标平台需安装 Wasm 运行时(如 WasmEdge、Node.js)。
- 系统交互:若涉及文件、网络等操作,需通过 WASI 标准化接口。
- 工具链建议:优先使用 Emscripten + WasmEdge 组合,覆盖大部分 C++ 场景。