Emscripten如何将cc++代码编译成为WebAssembly?
网友回复
c语言编译
首先,我们来编译一个 C 语言的 Hello World,创建一个 hello.c 文件:
#include <stdio.h> int main() { printf("Hello World!\n"); return 0; } 编译成可执行文件 代码就是输出了一句 Hello World! ,使用 clang 或 gcc 或很多工具都可以把这段代码编译成可执行的二进制,找不到命令的话,可以在网上找教程配置一下。以 clang 为例:clang hello.c -O3 -o out/hello
-O3 表示了优化级别, 生成的可执行文件是 hello ,但是这个文件只能在特定平台上执行,在 windows 上编译出来的文件没办法跑在 mac 上(不绝对),在 32 位系统编译出来的文件无法跑在 64 位系统上。 然而如果把它编译成 wasm 就可以跨平台分发了,这也是 wasm 的一大优势。只需要编译一次,同一个 wasm 包,可以运行在浏览器中、Node.js 中、各种独立的 runtime 里,但是要求目标平台具备执行 wasm 包的能力,而且符合规范。 c编译成WebAssembly 程序WebAssembly 的编译和运行流程
在编译 WebAssembly 之前先了解一下它基本的编译和运行流程,想要以何种方式运行 wasm 的包,决定了以何种方式来编译它。 目前来看,大部分使用 WebAssembly 的例子都是运行在浏览器中的,有一部分运行在 Node.js 里,和 JS 的渊源很深,因为在标准里定义了一套 JS API 来编译、实例化 wasm 文件,这部分 API 已经被 JS 引擎实现了,功能已经稳定可用。因此,wasm 最常见的是搭配 js 一起使用,这种场景下用 Emscripten⑤可以搞定,它在编译 wasm 包的同时也会生成一份 js "glue" 代码,把 wasm 包的初始化接口导入导出都封装在 js 里了,使用时引入这个 js 文件即可。 Emscripten 也支持编译成独立的 wasm 包(不含 JS),但是想要运行这个 wasm 包需要宿主环境给它注入很多基础的 API,而且这些 API 是非标准的。如果想在 JS 环境里运行独立 wasm 包的话,要用 JS 实现这些 API。 其实 WebAssembly 本质上和 JS 无关,完全可以运行在独立的沙箱环境里,通过标准化的 API (wasi ⑥) 来调用系统能力。现在已经有不少 wasm 的独立运行时了,如 Wasmtime⑦ 和 wasm-micro-runtime ⑧,它们都可以加载并独立执行 wasm 文件,并且实现了一致的 wasi 接口。关于 wasi,推荐阅读《Standardizing WASI: A system interface to run WebAssembly outside the web》 https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
使用 Emscripten 编译
首先安装官方文档安装 Emscripten (https://emscripten.org/) ,安装完成后命令行环境里会有 emcc 命令,使用方式和 gcc 差不多,执行如下代码就可以生成 wasm 的包:emcc hello.c -O3 -o out/hello-emcc.wasm
但是,上面这个命令隐含了 -s STANDALONE_WASM 的配置 ,实际上触发的是 WebAssembly Standalone build ⑩,只生成了一个 wasm 的包,需要自己写 loader 加载和执行。如果不想费这个劲,就可以使用如下命令直接生...点击查看剩余70%