前言

WebAssembly,简称wasm,是用于浏览器内客户端脚本的低级、可移植的字节码格式,是一种运行在现代网络浏览器中的新型代码、并且提供新的性能特性和效果,对于浏览器下载和加载是有效的。

  它是为诸如C、C++和Rust等低级源语言提供一个高效的编译目标而设计的。使用C/C++等语言开发的功能,在编译为wasm后可以在浏览器中运行,并可以得到与本地应用程序接近的运行效率。

  现在最常用的wasm编译套件是Emscripten SDK (emsdk),它除了提供把C/C++编译为wasm的编译器,还提供了一组运行库,使用C/C++可以方便地调用JavaScript/浏览器的功能。比如下载文件、管理文件缓存、使用woker模拟多线程支持、把C/C++代码中的OpenGL调用映射到WebGL等。

1 下载emsdk(安装程序)的最新版本

   git clone https://github.com/emscripten-core/emsdk.git

   cd emsdk

#第一次下载代码,可以不执行该操作,以后更新版本,需要执行

   git pull


2 开始安装

install后面可以指定版本号

./emsdk install latest

emsdk list --old 查看emsdk历史版本号列表


3 激活

./emsdk activate latest

#配置环境变量,每次需要编译的时候配置一次


source ./emsdk_env.sh

#校验编译成功,看到输出使用帮助信息代表安装成功


emcc --help

4在龙芯LoongArch上配置WebAssembly开发环境

 在Emscripten SDK (emsdk)的安装包中,编译器是以二进制程序的方式存在。龙芯LoongArch架构还没有得到emsdk的官方支持,在安装emsdk时会报告loongarch64是未知的架构,虽然也可以自己下载源码编译,但确实非常麻烦。 但是,在安装了LATX的龙芯电脑上,现在也可以安装并运行x86版本的emsdk。与在x86/Linux下的安装过程相比,仅仅增加了一个步骤,就是修改安装程序所调用的emsdk.py。


修改emsdk文件夹下的emsdk.py:

   用编辑工具打开emsdk.py,搜索“ARCH = 'x86_64'”,到达下图中的位置,然后添加对loongarch64的支持。

   在合适的位置增加下面两行内容:

   elif machine.endswith('loongarch64'):

    ARCH = 'x86_64'

然后

安装emsdk,latest表示最新版本,也可以使用版本号指定要安装的版本。

   ./emsdk install latest

   ./emsdk activate latest

   source ./emsdk_env.sh

emsdk 运行CentOS Linux release 7.9.2009 (AltArch)_wasm


安装问题总结

logger.debug(f'(not saving intermediate {name} because not generating JS)')

[root@taishan-atlas emsdk]# emcc --help
  File "/home/dong/emsdk/emsdk/upstream/emscripten/emcc.py", line 185
    logger.debug(f'(not saving intermediate {name} because not generating JS)')
                                                                             ^
SyntaxError: invalid syntax

原因

Python 3.6 or greater is required by Emscripten. You may need to update your python.

解决 

升级Python3版本

yum -y install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel xz xz-devel libffi-devel

# 创建目录
mkdir -p /usr/local/python3

# 下载安装包
wget https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz

# 解压安装包
 tar -xvf Python-3.7.6.tgz

# 编译安装Python
cd Python-3.7.6 && ./configure --prefix=/usr/local/python3 && make && make install

直接创建Python3软链

在/usr/bin路径下创建python3软链,指向已安装的python3

ln -s /usr/local/python3/bin/python3 /usr/bin/python3

在/usr/bin路径下创建pip3软链,指向已安装的pip3

ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3

配置完成之后,此时系统中存在两个python版本:命令python对应的仍是默认2.7版本;命令python3则对应新安装的3.6版本

虽然存在两个版本的python,但是emcc会自动调用合适的python,就不覆盖已有的python2.7,避免影响yum等依赖指令


clang: /lib64/libm.so.6: version `GLIBC_2.27' not found

需要升级GCC库到8.0,或许采用更低版本的emcc会是一个合适的选择

[root@taishan-atlas test]# strings /lib64/libc.so.6 | grep GLIBC

GLIBC_2.17

GLIBC_2.18

GLIBC_PRIVATE

目前单纯采用SCL的方式升级GCC依旧报错

[root@taishan-atlas emsdk]# emcc ../test/hello.c  -o test.js
/home/dong/emsdk/emsdk/upstream/bin/clang: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /home/dong/emsdk/emsdk/upstream/bin/clang)
/home/dong/emsdk/emsdk/upstream/bin/clang: /lib64/libm.so.6: version `GLIBC_2.29' not found (required by /home/dong/emsdk/emsdk/upstream/bin/clang)
/home/dong/emsdk/emsdk/upstream/bin/clang: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /home/dong/emsdk/emsdk/upstream/bin/clang)
/home/dong/emsdk/emsdk/upstream/bin/clang: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /home/dong/emsdk/emsdk/upstream/bin/clang)
/home/dong/emsdk/emsdk/upstream/bin/clang: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by /home/dong/emsdk/emsdk/upstream/bin/clang)
/home/dong/emsdk/emsdk/upstream/bin/clang: /lib64/libstdc++.so.6: version `CXXABI_1.3.11' not found (required by /home/dong/emsdk/emsdk/upstream/bin/clang)
emcc: error: '/home/dong/emsdk/emsdk/upstream/bin/clang --version' failed (returned 1)

原因

当前clang版本是18.0.0,依赖glibc-2.29和gcc9.5(gcc8.5测试失败)

解决方案

通过单独编译glibc-2.29和gcc9.5,然后强制加载编译生成的libm.so.6文件和libstdc++.so.6

export LD_PRELOAD="/home/glibc/glibcout/lib/libm.so.6"

export LD_PRELOAD="/home/gcc/gcc9.5/gccout/lib64/libstdc++.so.6":$LD_PRELOAD

然后就执行执行emcc指令了

[root@taishan-atlas emsdk]# emcc -v
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.47 (431685f05c67f0424c11473cc16798b9587bb536)
clang version 18.0.0 (https://github.com/llvm/llvm-project 21030b9ab4487d845e29792063f5666d8c4b8e09)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /home/dong/emsdk/emsdk/upstream/bin

error: installation failed!

目前无法安装其他的版本

[root@taishan-atlas emsdk]# ./emsdk install 2.0.30
Resolving SDK version '2.0.30' to 'sdk-releases-c69458f1bbf3ef5b8da4e934de210659cc9bca04-64bit'
WARNING: arm64-linux binaries are not available for all releases.
See https://github.com/emscripten-core/emsdk/issues/547
Installing SDK 'sdk-releases-c69458f1bbf3ef5b8da4e934de210659cc9bca04-64bit'..
Skipped installing node-16.20.0-64bit, already installed.
Installing tool 'releases-c69458f1bbf3ef5b8da4e934de210659cc9bca04-64bit'..
Error: Downloading URL 'https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/c69458f1bbf3ef5b8da4e934de210659cc9bca04/wasm-binaries-arm64.tar.xz': HTTP Error 404: Not Found
error: installation failed!

学习参考

javascript - WebAssembly介绍 - Emscripten-WebAssembly - SegmentFault 思否