在 OpenHarmony 开发板上运行 WasmEdge

开发 前端
WasmEdge 目前已经支持了 Linux、macOS、Windows 与 实时操作系统 seL4。添加 OpenHarmony 的支持,将丰富 WasmEdge 的生态。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

Why

移动与 IoT 设备的特点是资源受限,软硬件不统一,用户体验却要求很高。设备要能安全,跨平台地运行第三方开发者提供的软件应用(例如,应用商店),因而直接原生编译的软件应用(Native Client, or NaCl)并不主流。鸿蒙与安卓这样的主流操作系统一般提供基于 Java 或者 JavaScript 的软件执行沙盒,来支持第三方应用。但是这样的软件执行沙盒有几个大问题:

  • 支持的编程语言很有限
  • 支持的语言有 IP 与法律风险
  • 性能一般
  • 资源开销大
  • 无法支持实时系统
  • 安全性一般(所以应用商店需要审查制)

而 WebAssembly 作为一个多语言,跨平台,高性能,轻量级,安全的软件执行环境,能让开发者兼得性能,可移植性,与安全性。WebAssembly 是移动与 IoT 设备上系统中间件的最佳选择。

WasmEdge 是由 CNCF 托管的轻量级、高性能和可扩展的 WebAssembly runtime,适用于云原生、边缘和去中心化应用程序。WasmEdge 可以运行 C/C++、Rust、Swift、AssemblyScript 或 Kotlin 等语言编译的标准 WebAssembly 字节码程序。

OpenHarmony 是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目,目标是面向全场景、全连接、全智能时代,基于开源的方式,搭建一个智能终端设备操作系统的框架和平台,促进万物互联产业的繁荣发展。

WasmEdge 为 OpenHarmony 提供了一个与 JVM 与 JS engine 同级的 runtime,但是比 JVM、JS engine 更安全、更快、更小、更易于管理。通过 WasmEdge,可以在设备上安全地运行第三方开发者用 C、C++、Rust 等语言编写的 Wasm 程序,扩大 OpenHarmony 的开发者群体。 WasmEdge 相当于 OpenHarmony 的一个完全开源的开发执行环境。社区开发者可以方便地运行编译好的 WebAssembly 程序,降低门槛。

WasmEdge 目前已经支持了 Linux、macOS、Windows 与 实时操作系统 seL4。添加 OpenHarmony 的支持,将丰富 WasmEdge 的生态。

介绍完毕 ,下面进入编程时间。请参考下面的教程从源码在 OpenHarmony 开发板中构建和测试 WasmEdge。

1. 全量编译 OpenHarmony OS

2. 获取 WasmEdge 源码

3. 修改 OpenHarmony 标准系统配置文件

4. 构建 WasmEdge 与 OpenHarmony

5. 烧录到开发板

6. 运行 WasmEdge 提供的测试用例

配合视频观看,效果更佳。

环境准备

OpenHarmony 标准系统

OpenHarmony 标准系统为开发者提供的 Docker 环境封装了对应的编译工具链,本文档主要介绍在 Docker 环境下构建 WasmEdge 的步骤。

OpenHarmony 源码的获取与编译可以参考 Open Harmony 提供的文档 搭建Ubuntu环境-Docker方式。

请注意,在构建 WasmEdge 前需要将 Openharmony 进行一次全量编译以便后续 WasmEdge 的交叉编译过程。

  1. # 获取到 docker 镜像后 
  2. $ docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5 
  3. $ ./build.sh --product-name Hi3516DV300 

获取 WasmEdge 源码

OpenHarmony 将第三方库项目放在了 third_party 文件夹下,因此我们需要在 third_party 文件夹下获取 WasmEdge 源码。

这之后,用户可以根据需要更改路径并修改相关配置文件中的路径。

  1. $ docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5 
  2. $ cd third_party 
  3. $ git clone https://github.com/WasmEdge/WasmEdge.git 
  4. $ cd WasmEdge 

 修改 OpenHarmony 标准系统配置文件

添加 WasmEdge 子系统配置

修改 OpenHarmony 的 build 目录下的 subsystem_config.json 文件,如下添加 wasmedge 子系统。

  1.   ... 
  2.    
  3.   "wasmedge": { 
  4.     "path""third_party/WasmEdge"
  5.     "name""wasmedge" 
  6.   }, 
  7.    
  8.   ... 

 将组件添加到产品配置中

修改 OpenHarmony 产品配置文件,标准系统对应的配置文件为:productdefine/common/products/Hi3516DV300.json。

在该配置文件中添加 "wasmedge:wasmedge":{},表示该产品会编译并打包 wasmedge 子系统下的 wasmedge 模块到版本中。

  1.   ... 
  2.   "parts":{ 
  3.     ... 
  4.     "wasmedge:wasmedge":{} 
  5.   } 

构建 WasmEdge 与 OpenHarmony

说明

在 OpenHarmony 中构建的 WasmEdge 目前仅支持 wasmedge,即 wasm 的通用运行时。

wasmedge 可以在解释器模式下执行一个 WASM 文件, 也可以执行从 WASM 文件 AOT 预编译产生的机器码二进制格式文件。但目前还不支持在 OpenHarmony 中对 WASM 文件进行 AOT 预编译 。

执行构建脚本

执行 WasmEdge 源码下的 utils/build_for_ohos.sh 命令行脚本,将自动执行以下工作:

将 .gn 等 OpenHarmony 需要的构建配置文件移动到 WasmEdge 项目根目录;

使用 OpenHarmony 的编译工具链进行交叉编译构建 WasmEdge;

运行 OpenHarmony 的构建脚本 build.sh 进行全量编译,该步骤将 wasmedge 添加进 OpenHarmony OS;

  1. $ docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5 
  2. $ cd third_party/WasmEdge/utils/ohos 
  3. $ ./build_for_ohos.sh /home/openharmony 

 当 terminal 显示以下信息时,表明编译完成。

  1. ... 
  2.  
  3. post_process 
  4. =====build Hi3516DV300 successful. 
  5. 2021-12-15 03:18:50 
  6. ++++++++++++++++++++++++++++++++++++++++ 

 检查 wasmedge 是否编译打包进 OpenHarmony OS。

  1. $ cd /home/openharmony/out/ohos-arm-release/packages/phone/system/bin 
  2. $ ls  

当输出的文件名中存在 wasmedge 时,就表明 WasmEdge 已经成功导入到 OpenHarmony OS。

测试

烧录镜像

将重新编译后的 OpenHarmony 标准系统镜像烧录进开发板,具体见 OpenHarmony 提供的文档 Hi3516DV300 开发板烧录。

运行应用

WasmEdge 在 tools/wasmedge/examples/ 文件夹提供了测试样例。在 OpenHarmony 标准系统中,这些样例写入了 system 镜像中,依然可以进行测试。通过串口工具连接上开发板并启动OpenHarmony 标准系统后,我们就可以进行以下的测试。

  1. # cd /system/usr/wasmedge_example 
  2. # wasmedge hello.wasm 1 2 3 
  3. hello 
  4. # wasmedge --reactor add.wasm add 2 2 
  5. # wasmedge --reactor fibonacci.wasm fib 8 
  6. 34 
  7. # wasmedge --reactor factorial.wasm fac 12 
  8. 479001600 
  9. # cd js 
  10. # wasmedge --dir .:. qjs.wasm hello.js 1 2 3 
  11. Hello 1 2 3 

下一步

接下来,你可以参考 WasmEdge Book 在 OpenHarmony 标准系统中使用 WasmEdge Runtime 来运行你自己的 WebAssembly 应用。

移植过程踩过的坑

最后和大家分享一下,在移植 WasmEdge 到 OpenHarmony OS 过程出现的一些问题与值得注意的地方。

交叉编译

cmake 项目进行交叉编译需要配置工具链,官方的交叉编译配置给出了参考,但需要在此基础上细化,如指明 Clang 及 Clang++ 的位置。此外,标准版 sysroot 的路径也有所不同,具体可以参考 WasmEdge 中的配置:

  1. set(TOOLSCHAIN_PATH "${OHOS_DIR_PATH}/prebuilts/clang/ohos/linux-x86_64/llvm"
  2. set(TOOLCHAIN_HOST "${TOOLSCHAIN_PATH}/bin"
  3. set(OHOS_SYSROOT_PATH "${OHOS_DIR_PATH}/out/ohos-arm-release/obj/third_party/musl"
  4. set(CMAKE_SYSROOT ${OHOS_SYSROOT_PATH}) 
  5. set(CMAKE_CROSSCOMPILING TRUE
  6. set(CMAKE_SYSTEM_NAME "Generic"
  7. set(CMAKE_CXX_COMPILER_ID Clang) 
  8. set(CMAKE_TOOLCHAIN_PREFIX llvm-) 
  9. set(LLVM_PATH "${OHOS_DIR_PATH}/prebuilts/clang/ohos/linux-x86_64/llvm"
  10. include_directories(${LLVM_PATH}/include/c++/v1) 
  11. include_directories(${OHOS_SYSROOT_PATH}/usr/include/arm-linux-ohosmusl) 
  12. link_directories(${OHOS_SYSROOT_PATH}/usr/lib/arm-linux-ohosmusl) 
  13. set(TOOLCHAIN_CC "${TOOLCHAIN_HOST}/clang"
  14. set(TOOLCHAIN_CXX "${TOOLCHAIN_HOST}/clang++"
  15. set(CMAKE_C_COMPILER ${TOOLCHAIN_CC}) 
  16. set(CMAKE_C_FLAGS "--target=arm-linux-ohosmusl -D__clang__ -march=armv7-a -mfloat-abi=softfp -mtune=generic-armv7-a -mfpu=neon -mthumb -w --sysroot=${OHOS_SYSROOT_PATH}"
  17. set(CMAKE_CXX_COMPILER ${TOOLCHAIN_CXX}) 
  18. set(CMAKE_CXX_FLAGS "--target=arm-linux-ohosmusl -D__clang__ -march=armv7-a -mfloat-abi=softfp -mtune=generic-armv7-a -mfpu=neon -mthumb -w --sysroot=${OHOS_SYSROOT_PATH}"
  19. set(MY_LINK_FLAGS "--target=arm-linux-ohosmusl --sysroot=${OHOS_SYSROOT_PATH}"
  20. set(CMAKE_LINKER clang) 
  21. set(CMAKE_CXX_LINKER clang++) 
  22. set(CMAKE_C_LINKER clang) 
  23. set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINKER} ${MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>"
  24. set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINKER} ${MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>"

编译工具链

OpenHarmony OS 使用 gn+ninja 进行编译。对于 cmake 组织编译的项目来说,官方提供的 cmake 项目移植文档给出的案例是基于轻量级系统的,并不完全适用于标准版系统上的移植。要想将项目写入 OpenHarmony OS 编译生成的镜像烧录到开发板上,需要编写 gn 脚本参与进 OpenHarmony OS 的编译过程。

在 WasmEdge 编译过程中,需要使用到 spqlog 项目,构建过程中存在 spdlog 项目拉取及编译生成 sqdlog 静态库的动作,这意味着只将 WasmEdge 相关库的编译过程改写为 gn 脚本是不够的,还需要对 spdlog 的编译过程进行改写,使得工作量急剧增加。

那么对于项目所依赖但并不属于 OpenHarmony OS 中的静态库模块,编译过程中要如何将这一模块引入 OpenHarmony OS 呢?

OpenHarmony OS 提供的 gn 编写模板中有 ohos_copy ,它可以将生成的静态库移至生成的目标文件夹。这样在真正编译需要链接时,就能将这一静态库视为 OpenHarmony OS 的原生模块而不是查无此库。在 WasmEdge 的移植过程中,所执行的编译脚本便是事先进行一遍交叉编译,生成需要 copy 的 spdlog 静态库,然后再执行 OpenHarmony OS 的编译脚本,从而按照项目目录下的 BUILD.gn 内的定义组织编译。

在 WasmEdge 的 BUILD.gn 中,关于 spdlog 静态库的描述如下:

  1. ohos_copy("spdlog"){ 
  2.     sources = [ 
  3.         "$WASMEDGE_ROOT_DIR/build/_deps/spdlog-build/libspdlog.a"
  4.     ] 
  5.     outputs = [ 
  6.         target_out_dir + "/lib/libspdlog.a" 
  7.     ] 
  8.     module_install_name = "" 

标准 C 库

平时我们常用的标准 C 库是 GNU 发布的 libc 库,而 OpenHarmony 中使用的是 Musl-libc,因此如果需要移植的项目代码中使用了 glibc 的宏变量的代码,那么需要进行修改或者在开头重新定义为 Musl-libc 中的宏变量。

链接项

  1. ../../third_party/WasmEdge/lib/system/allocator.cpp:64:40: error: unused variable 'k4G' [-Werror,-Wunused-const-variable] 
  2. static inline constexpr const uint64_t k4G = UINT64_C(0x100000000); 
  3.                                        ^ 
  4. ../../third_party/WasmEdge/lib/system/allocator.cpp:65:40: error: unused variable 'k12G' [-Werror,-Wunused-const-variable] 
  5. static inline constexpr const uint64_t k12G = UINT64_C(0x300000000); 
  6.                                        ^ 
  7. 1 warning and 2 errors generated. 

 诸如这类报错,在 BUILD.gn 中使用到该源码的模块中添加 cflags.例如,对上面的报错,可以添加如下的 cflags :

  1. cflags = [ 
  2.   ... 
  3.   "-Wno-unused-const-variable"
  4.   ... 

 如果出现下面的 C++ 的链接编译报错,

  1. ../../third_party/WasmEdge/lib/host/wasi/inode-linux.cpp:745:3: error: cannot use 'try' with exceptions disabled 
  2.   try { 
  3.   ^ 

 则添加 cflags_cc:

  1. # BUILD.gn 使用到该源码的相应模块 
  2.   ... 
  3.   cflags_cc = [  
  4.     ... 
  5.     "-fexceptions"
  6.     ... 
  7.   ] 

 移植过程中还有许多诸如此类的编译报错,在此不进行一一列举。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-04-01 15:54:01

DHCP网络协议开发板

2022-10-14 15:55:24

环境搭建鸿蒙

2020-11-24 11:41:30

websocket

2021-10-11 14:14:42

鸿蒙HarmonyOS应用

2021-09-10 10:01:04

鸿蒙HarmonyOS应用

2021-12-16 15:14:54

鸿蒙HarmonyOS应用

2022-03-03 19:21:50

Harmony鸿蒙操作系统

2022-06-06 10:44:10

C++语言鸿蒙

2020-12-29 09:59:01

鸿蒙HarmonyOS智能家居

2020-10-30 09:48:03

Hi3861开发板get请求

2021-09-13 10:03:35

鸿蒙HarmonyOS应用

2022-02-24 16:39:41

OpenHarmonNiobe开发鸿蒙

2021-06-25 15:32:13

鸿蒙HarmonyOS应用

2020-12-16 10:05:48

鸿蒙开发板Onenet平台

2020-10-30 17:12:05

Hi3861

2021-09-08 15:44:56

鸿蒙HarmonyOS应用

2011-06-15 14:19:11

QT 移植

2022-04-14 11:44:25

LiteOS线程鸿蒙

2023-03-07 15:54:45

鸿蒙Mesa库
点赞
收藏

51CTO技术栈公众号