之前介绍了[WASM在生产环境中的部署方案](https://www.atatech.org/articles/109271),编译的过程留了个坑,由于后来LLVM和Emscripten都有了很多更新,这里讲一下最新的发展状况,以及手把手环境搭建指南。
## 标准发展
多数proposal仍然在开发中...... 这篇文章有详细介绍 [《WebAssembly’s post-MVP f
之前介绍了
WASM在生产环境中的部署方案
,编译的过程留了个坑,由于后来LLVM和Emscripten都有了很多更新,这里讲一下最新的发展状况,以及手把手环境搭建指南。
多数proposal仍然在开发中...... 这篇文章有详细介绍
《WebAssembly’s post-MVP future: A cartoon skill tree》
。
总的来说,post-mvp时代还没有到来。
不过有一项post-mvp功能已经可以提前体验了,chrome70之后的版本已经默认开启了SharedArrayBuffer的支持(之前由于meltdown漏洞被默认关闭),并提供了
WebAssembly threads support
的实验性功能,相关工具并没有跟进,比可能需要自己动手体验这个接口 :)
工具栈发展
Emscripten
将完整的c/cpp桌面端项目编译成Web版本,并提供wasm版本的支持。
WASM社区目前最活跃的项目,虽然不是为WASM而设计的,也不是为模块化设计的,但是提供了目前最完整的toolchain,收到广泛支持。今年的更新中,着重优化了编译结果中胶水代码体积(之前饱受诟病的一点),可用性进一步提升。如果该项目今后能够更多的考虑到函数级以及模块级编译的需求,将大大提升WASM的易用性和普及速度。
Shrinking WebAssembly and JavaScript code sizes in Emscripten
WebAssembly Standalone
AssemblyScript
快速发展的新兴项目,从之前的Binaryen/TypeScript编译器中发展出来。在TypeScript基础上进一步规范类型得到的一个语言子集。相关的工具栈已经非常成熟(相对于C/CPP工具栈),有可能成为接下来WASM的发展动力。
熟悉TypeScript的同学不妨尝试一下。在MVP阶段,C/CPP的很多底层性能优化特性起始用不上力,所以AssemblyScript的性能不见得比C差,而且不需要考虑标准库等麻烦的问题,与打包系统配合起来也很方便。
出于某种不明原因,RUST对WASM的支持可能是所有高级语言中最完整的(Mozilla血缘关系?)。toolchain完整,webpack支持良好,标准库也有成熟方案。观望。
LLVM/Clang
决定你能否在浏览器中跑C++的关键所在。
对WASM的支持在稳定发展,一部分功能已经加入正式版,新版本中安装和使用过程已经非常流畅,目前的遗留问题是标准库。如果你不介意
不使用标准库
或者跟着社区一起折腾
标准库替代方案
,该工具链目前已经可用。接下来会介绍如何搭建环境。
本地构建LLVM-WASM编译环境
由于LLVM对WASM的支持已经逐步稳定,社区中介绍的很多hack方案已经过时,例如:
"wasm32-unknown-unknown-wasm"这个triple已经不再需要,直接target=wasm即可
lld这个工具不再适用于wasm,应该使用专用的wasm-ld
llc不再需要,因为clang已经支持了wasm
现在的编译过程已经非常简化:
按照官网标准过程编译LLVM,但要加入lld并开启其WASM实验性功能
用clang编译成
.o
用wasm-ld连接成
.wasm
你可以直接跑这个脚本来安装编译环境。
测试环境osx,编译过程需要至少
25G硬盘
下载源码可能需要较长时间(10min),如果svn下载失败可以从git上的llvm-mirror下载
make过程可能需要较长时间(10-30min),具体要看你的电脑性能以及核心数,注意修改make -j8这一行,使用你的核心数来并行编译,不然要等几个小时
# 建个项目目录
mkdir llvm-wasm
cd llvm-wasm
# src dir
# llvm 必选
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
# clang 必选
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ../..
# extra 必选
cd llvm/tools/clang/tools
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra
cd ../../../..
# RT 必选
cd llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
cd ../..
# libcxx ?必选?
cd llvm/projects
# 似乎会搞挂官网然后网络失败,反正这部分标准库连接不进去......
svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
cd ../..
# lld 必选,编译wasm-ld
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/lld/trunk lld
cd ../..
# build dir
mkdir build
cd build
# cmake
cmake -G "Unix Makefiles" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=WebAssembly ../llvm
# make 线程数写逻辑核数(如:4核8线程 -j8)
make -j8
加入稳定支持后,使用方案就很简单了。
# 加入PATH
export PATH=当前目录/llvm/build/bin:$PATH
clang -c -O3 --target=wasm32 test.cpp
wasm-ld --no-entry --strip-all --allow-undefined --export-all test.o -o test.wasm
float max(float a, float b) {
return a > b ? a : b;
输出(wasm转换成可读的wat):
(module
(type $t0 (func))
(type $t1 (func (param f32 f32) (result f32)))
(func $__wasm_call_ctors (type $t0))
(func $_Z3maxff (type $t1) (param $p0 f32) (param $p1 f32) (result f32)
get_local $p0
get_local $p1
get_local $p0
get_local $p1
f32.gt
select)
(table $T0 1 1 anyfunc)
(memory $memory 2)
(global $g0 (mut i32) (i32.const 66560))
(global $__heap_base i32 (i32.const 66560))
(global $__data_end i32 (i32.const 1024))
(global $__dso_handle i32 (i32.const 1024))
(export "memory" (memory 0))
(export "__wasm_call_ctors" (func $__wasm_call_ctors))
(export "__heap_base" (global 1))
(export "__data_end" (global 2))
(export "__dso_handle" (global 3))
(export "_Z3maxff" (func $_Z3maxff)))
注意由于使用了-O3优化,最后暴露出的函数名被加上了前后缀,代表其传入传出参数类型,调用的时候要注意加上。
如何通过Makefile优化加速编译过程提高开发效率
在软件开发中,编译是一个必不可少的过程。但是,当代码规模变得越来越大时,编译时间也会变得越来越长,这会严重影响开发效率。在这种情况下,优化Makefile可以帮助我们加速编译过程,以下是一些Makefile优化的建议
Rhino ceros 7.25:3D设计软件的全新进化!+Rhino ceros 全版本安装包
Rhino ceros 7.25:3D设计软件的全新进化!+Rhino ceros 全版本安装包
带你读《LLVM编译器实战教程》之一:构建和安装LLVM
本书的前半部分将向您介绍怎么样去配置、构建、和安装LLVM的不同软件库、工具和外部项目。接下来,本书的后半部分将向您介绍LLVM的各种设计细节,并逐步地讲解LLVM的各个编译步骤:前段、中间表示(IR)、后端、即时编译(JIT)引擎、跨平台编译和插件接口。本书包含有大量翔实的示例和代码片段,以帮助读者平稳顺利的掌握LLVM的编译器开发环境。
17967
带你读《LLVM编译器实战教程》之二:外部项目
本书的前半部分将向您介绍怎么样去配置、构建、和安装LLVM的不同软件库、工具和外部项目。接下来,本书的后半部分将向您介绍LLVM的各种设计细节,并逐步地讲解LLVM的各个编译步骤:前段、中间表示(IR)、后端、即时编译(JIT)引擎、跨平台编译和插件接口。本书包含有大量翔实的示例和代码片段,以帮助读者平稳顺利的掌握LLVM的编译器开发环境。
Fun: Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个模板文件(template.yml),协助您进行开发、构建、部署操作。
《测试驱动的嵌入式C语言开发》——2.5节 “四阶段”模式
本节书摘来自华章社区《测试驱动的嵌入式C语言开发》一书中的第2章,第2.5节 “四阶段”模式,作者:(美)James W. Grenning,更多章节内容可以访问云栖社区“华章社区”公众号查看
《测试驱动的嵌入式C语言开发》——第2章测试驱动开发的工具和约定
本节书摘来自华章社区《测试驱动的嵌入式C语言开发》一书中的第2章测试驱动开发的工具和约定,作者:(美)James W. Grenning,更多章节内容可以访问云栖社区“华章社区”公众号查看