Hello WebAsm:第一个WebAssembly例子
Posted 车斗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hello WebAsm:第一个WebAssembly例子相关的知识,希望对你有一定的参考价值。
Hello WebAsm:第一个WebAssembly例子
概述
让浏览器能运行C语言程序,这个想法新奇而大胆。这就是 WebAssembly。它具有以下优点:
- 高效
WebAssembly 有一套完整的语义,实际上 wasm 是体积小且加载快的二进制格式, 其目标就是充分发挥硬件能力以达到原生执行效率。 - 安全
WebAssembly 运行在一个沙箱化的执行环境中,甚至可以在现有的 javascript 虚拟机中实现。在web环境中,WebAssembly将会严格遵守同源策略以及浏览器安全策略。 - 开放
WebAssembly 设计了一个非常规整的文本格式用来、调试、测试、实验、优化、学习、教学或者编写程序。可以以这种文本格式在web页面上查看wasm模块的源码。 - 标准
WebAssembly 在 web 中被设计成无版本、特性可测试、向后兼容的。WebAssembly 可以被 JavaScript 调用,进入 JavaScript 上下文,也可以像 Web API 一样调用浏览器的功能。当然,WebAssembly 不仅可以运行在浏览器上,也可以运行在非web环境下。 - 版权保护
这条是我加的。有些业务逻辑还是隐藏起来比较好。
环境准备
首先就是开发环境的准备工作。我是用 win10 上 virtualbox 上跑的 centos7 虚拟机。下面开始准备(用root账号)(一些 gcc, g++, cmake … 已经安装好了):
下面的过程仅仅第一次需要准备
$ yum -y install bzip2
$ yum -y install python3
查看GLIBC版本。这个要求 GLIBC_2.18 以上。
$ strings /lib64/libc.so.6 | grep ^GLIBC
如果版本低则下载 glibc-2.18.tar.gz:
$ wget https://mirrors.tuna.tsinghua.edu.cn/gnu/glibc/glibc-2.18.tar.gz
然后升级GLIBC。
glibc是gnu发布的libc库,即c运行库,glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。
很多linux的基本命令,比如cp, rm, ll, ln等,都得依赖于它,如果操作错误或者升级失败会导致系统命令不能使用,严重的造成系统退出后无法重新进入,所以操作时候需要慎重。
$ tar -zxvf glibc-2.18.tar.gz
$ cd glibc-2.18/
$ mkdir build
$ cd build/
$ ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
$ make -j 8
$ make install
安装 Emscripten
2012年,Mozilla 的工程师 Alon Zakai 在研究 LLVM 编译器时突发奇想:许多 3D 游戏都是用 C / C++ 语言写的,如果能将 C / C++ 语言编译成JavaScript 代码,它们不就能在浏览器里运行了吗?众所周知,JavaScript 的基本语法与 C 语言高度相似。
于是,他开始研究怎么才能实现这个目标,为此专门做了一个编译器项目 Emscripten。这个编译器可以将 C / C++ 代码编译成 JS 代码,但不是普通的 JS,而是一种叫做 asm.js 的 JavaScript 变体。
Emscripten 的底层是 LLVM 编译器,理论上任何可以生成 LLVM IR(Intermediate Representation)的语言,都可以编译生成 asm.js。 但是实际上,Emscripten 几乎只用于将 C / C++ 代码编译生成 asm.js。
C/C++ ⇒ LLVM ⇒ LLVM IR ⇒ Emscripten ⇒ asm.js
# Get the emsdk repo
$ git clone https://github.com/emscripten-core/emsdk.git
# Enter that directory
$ cd emsdk
# Fetch the latest registry of available tools.
$ ./emsdk update
# Download and install the latest SDK tools. (lastest 也可以用特定的版本代替,如1.38.45)
$ ./emsdk install latest
# Set up the compiler configuration to point to the "latest" SDK.
$ ./emsdk activate latest
# Activate PATH and other environment variables in the current terminal
$ source ./emsdk_env.sh
如果你的 emsdk 目录/path/to/emsdk/迁移到另外的位置/another-path/to/emsdk/,要重新运行:
$ cd /another-path/to/emsdk/
$ ./emsdk activate latest
$ source ./emsdk_env.sh
Hello WebAsm 第一例子
执行上面的从操作没有任何错误的话,就可以开始 WebAsm 之旅了。创建一个目录(名称随意) webasm,目录下面放入 hello.c 文件:
#include <stdio.h>
int main(int argc, char *argv[])
printf("Hello, WebAsm!\\n");
return 0;
在使用 emcc 命令时,要带着 -s WASM=1 参数(不然,默认将会编译成asm.js)。
如果我们想让 Emscripten 生成一个我们所写程序的html页面,并带有 wasm 和 JavaScript 文件,我们需要给输出的文件名加 .html 后缀名。
最后,当我们运行程序的时候,我们不能直接在浏览器中打开 HTML 文件,因为跨域请求是不支持 file 协议的。我们需要将我们的输出文件运行在HTTP协议上。
然后运行 emcc 编译命令(带着 -s WASM=1 参数,不然,默认将会编译成asm.js),将hello.c编译成webasm:
$ emcc hello.c -s WASM=1 -o hello.html
成功执行生成了3个文件:
hello.html
hello.js
hello.wasm
用 node 执行:
$ node hello.js
Hello, WebAsm!
然后我们可以使用 emrun 命令来创建一个 http 协议的 web server 来展示我们编译后的文件。
$ emrun --no_browser --port 8080 .
HTTP 服务开启后,您可以在浏览器中打开。如果你看到了“Hello, WebAsm!” 输出到了 Emscripten 的 控制面板,恭喜你!你的 WebAssembly 程序编译成功了!
参考链接
- http://webassembly.org.cn/getting-started/developers-guide/
- https://webassembly.org/
- http://webassembly.org.cn/
- WebAssembly 小 Demo
C/C++ 与 Javascript 互操作详见:
开始你的webasm开发之旅吧!
我在Win10 PC电脑上运行了VirtualBox centos7 虚拟机。当我在虚拟机里使用命令
$ emrun --no_browser --port 8080 .
就可以开启一个测试用的web服务。当服务启动之后,我就可以在我的Win10 PC笔记本上打开浏览器(firefox,chrome,edge),输入虚拟机ip地址(192.168.56.111)访问这个网址:
http://192.168.56.111:8080/hello.html
可见webasm可以工作了。
如果我想测试一下其他人的机器(如android手机)是否可以访问这个http://192.168.56.111:8080/hello.html 呢?接下来就演示这个过程。
1)Win10 PC上开启共享wifi热点,然后手机接入PC电脑。使用cmd-> ipconfig 命令查看手机进入的wifi以太网适配器, 我的是:以太网 3:
IPv4 地址 . . . . . . . . . . . . : 192.168.94.34
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.94.1
这样在手机上的浏览器里输入 http://192.168.94.34 就可以访问Win10 PC 上的Web服务,当然前提是这个服务的确存在。我们需要安装 nginx,把服务地址 http://192.168.94.34 转发到虚拟机提供的 http://192.168.56.111:8080。即用户访问 http://192.168.94.34 的时候实际是访问 http://192.168.56.111:8080。
2)安装 nginx for windows。参考:
nginx for windows
首先下载并解压到一个目录如 C:\\DEVPACK\\nginx-1.20.1
然后修改配置文件:C:\\DEVPACK\\nginx-1.20.1\\conf\\nginx.conf
如下(仅修改 a, b 两处,其他不变):
http
# a. 增加下面的 upstream 段
# https://www.cnblogs.com/muhy/p/10528449.html
upstream wasmserver
server 192.168.56.111:8080;
server
location /
#root html;
#index index.html index.htm;
# b. 增加下面的行
proxy_pass http://wasmserver;
然后启动 nginx (打开 mingw64.exe 命令行窗口):
$ cd /C/DEVPACK/nginx-1.20.1/
$ ./nginx.exe
可以使用另一个 mingw64 命令行窗口查看进程:
$ tasklist -fi "imagename eq nginx.exe"
显示:
Image Name PID Session Name Session# Mem Usage
===============================================================
nginx.exe 7740 Console 1 8,600 K
nginx.exe 11576 Console 1 9,052 K
3) 在接入PC共享wifi网络的手机上打开浏览器app输入地址:http://192.168.94.34/ 就可以访问虚拟机192.168.56.111上的web服务了(http://192.168.56.111:8080/)。验证 web asm 在手机上也的确可用。我测试的是华为安卓 mate10 (火狐浏览器app, BaiDuApp)。以上是关于Hello WebAsm:第一个WebAssembly例子的主要内容,如果未能解决你的问题,请参考以下文章