添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
之前介绍了[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,更多章节内容可以访问云栖社区“华章社区”公众号查看