您现在的位置是:亿华云 > 系统运维
在 OpenHarmony 开发板上运行 WasmEdge
亿华云2025-10-03 02:24:13【系统运维】6人已围观
简介想了解更多内容,请访问:和华为官方合作共建的鸿蒙技术社区https://harmonyos.51cto.comWhy移动与 IoT 设备的特点是资源受限,软硬件不统一,用户体验却要求很高。设备要能安全
想了解更多内容,发板请访问:
和华为官方合作共建的上运鸿蒙技术社区
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 的交叉编译过程。
# 获取到 docker 镜像后 $ docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5 $ ./build.sh --product-name Hi3516DV300获取 WasmEdge 源码
OpenHarmony 将第三方库项目放在了 third_party 文件夹下,因此我们需要在 third_party 文件夹下获取 WasmEdge 源码。
这之后,用户可以根据需要更改路径并修改相关配置文件中的路径。
$ docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5 $ cd third_party $ git clone https://github.com/WasmEdge/WasmEdge.git $ cd WasmEdge修改 OpenHarmony 标准系统配置文件
添加 WasmEdge 子系统配置
修改 OpenHarmony 的 build 目录下的 subsystem_config.json 文件,如下添加 wasmedge 子系统。
{ ... "wasmedge": { "path": "third_party/WasmEdge", "name": "wasmedge" }, ... }将组件添加到产品配置中
修改 OpenHarmony 产品配置文件,标准系统对应的配置文件为:productdefine/common/products/Hi3516DV300.json。
在该配置文件中添加 "wasmedge:wasmedge":{ },表示该产品会编译并打包 wasmedge 子系统下的 wasmedge 模块到版本中。
{ ... "parts":{ ... "wasmedge:wasmedge":{ } } }构建 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;
$ docker run -it -v $(pwd):/home/openharmony openharmony-docker-standard:0.0.5 $ cd third_party/WasmEdge/utils/ohos $ ./build_for_ohos.sh /home/openharmony当 terminal 显示以下信息时,表明编译完成。
... post_process =====build Hi3516DV300 successful. 2021-12-15 03:18:50 ++++++++++++++++++++++++++++++++++++++++检查 wasmedge 是否编译打包进 OpenHarmony OS。
$ cd /home/openharmony/out/ohos-arm-release/packages/phone/system/bin $ ls当输出的文件名中存在 wasmedge 时,就表明 WasmEdge 已经成功导入到 OpenHarmony OS。
测试
烧录镜像
将重新编译后的 OpenHarmony 标准系统镜像烧录进开发板,具体见 OpenHarmony 提供的文档 Hi3516DV300 开发板烧录。
运行应用
WasmEdge 在 tools/wasmedge/examples/ 文件夹提供了测试样例。在 OpenHarmony 标准系统中,这些样例写入了 system 镜像中,依然可以进行测试。通过串口工具连接上开发板并启动OpenHarmony 标准系统后,我们就可以进行以下的测试。
# cd /system/usr/wasmedge_example # wasmedge hello.wasm 1 2 3 hello 1 2 3 # wasmedge --reactor add.wasm add 2 2 4 # wasmedge --reactor fibonacci.wasm fib 8 34 # wasmedge --reactor factorial.wasm fac 12 479001600 # # cd js # wasmedge --dir .:. qjs.wasm hello.js 1 2 3 Hello 1 2 3下一步
接下来,你可以参考 WasmEdge Book 在 OpenHarmony 标准系统中使用 WasmEdge Runtime 来运行你自己的 WebAssembly 应用。
移植过程踩过的坑
最后和大家分享一下,在移植 WasmEdge 到 OpenHarmony OS 过程出现的一些问题与值得注意的地方。
交叉编译
cmake 项目进行交叉编译需要配置工具链,官方的交叉编译配置给出了参考,但需要在此基础上细化,如指明 Clang 及 Clang++ 的位置。此外,标准版 sysroot 的路径也有所不同,具体可以参考 WasmEdge 中的配置:
set(TOOLSCHAIN_PATH "${ OHOS_DIR_PATH}/prebuilts/clang/ohos/linux-x86_64/llvm") set(TOOLCHAIN_HOST "${ TOOLSCHAIN_PATH}/bin") set(OHOS_SYSROOT_PATH "${ OHOS_DIR_PATH}/out/ohos-arm-release/obj/third_party/musl") set(CMAKE_SYSROOT ${ OHOS_SYSROOT_PATH}) set(CMAKE_CROSSCOMPILING TRUE) set(CMAKE_SYSTEM_NAME "Generic") set(CMAKE_CXX_COMPILER_ID Clang) set(CMAKE_TOOLCHAIN_PREFIX llvm-) set(LLVM_PATH "${ OHOS_DIR_PATH}/prebuilts/clang/ohos/linux-x86_64/llvm") include_directories(${ LLVM_PATH}/include/c++/v1) include_directories(${ OHOS_SYSROOT_PATH}/usr/include/arm-linux-ohosmusl) link_directories(${ OHOS_SYSROOT_PATH}/usr/lib/arm-linux-ohosmusl) set(TOOLCHAIN_CC "${ TOOLCHAIN_HOST}/clang") set(TOOLCHAIN_CXX "${ TOOLCHAIN_HOST}/clang++") set(CMAKE_C_COMPILER ${ TOOLCHAIN_CC}) 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}") set(CMAKE_CXX_COMPILER ${ TOOLCHAIN_CXX}) 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}") set(MY_LINK_FLAGS "--target=arm-linux-ohosmusl --sysroot=${ OHOS_SYSROOT_PATH}") set(CMAKE_LINKER clang) set(CMAKE_CXX_LINKER clang++) set(CMAKE_C_LINKER clang) set(CMAKE_C_LINK_EXECUTABLE "${ CMAKE_C_LINKER} ${ MY_LINK_FLAGS} <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>") 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 静态库的描述如下:
ohos_copy("spdlog"){ sources = [ "$WASMEDGE_ROOT_DIR/build/_deps/spdlog-build/libspdlog.a", ] outputs = [ target_out_dir + "/lib/libspdlog.a" ] module_install_name = "" }标准 C 库
平时我们常用的标准 C 库是 GNU 发布的 libc 库,而 OpenHarmony 中使用的是 Musl-libc,因此如果需要移植的项目代码中使用了 glibc 的宏变量的代码,那么需要进行修改或者在开头重新定义为 Musl-libc 中的宏变量。
链接项
../../third_party/WasmEdge/lib/system/allocator.cpp:64:40: error: unused variable k4G [-Werror,-Wunused-const-variable] static inline constexpr const uint64_t k4G = UINT64_C(0x100000000); ^ ../../third_party/WasmEdge/lib/system/allocator.cpp:65:40: error: unused variable k12G [-Werror,-Wunused-const-variable] static inline constexpr const uint64_t k12G = UINT64_C(0x300000000); ^ 1 warning and 2 errors generated.诸如这类报错,在 BUILD.gn 中使用到该源码的模块中添加 cflags.例如,对上面的报错,可以添加如下的 cflags :
cflags = [ ... "-Wno-unused-const-variable", ... ]如果出现下面的 C++ 的链接编译报错,
../../third_party/WasmEdge/lib/host/wasi/inode-linux.cpp:745:3: error: cannot use try with exceptions disabled try { ^则添加 cflags_cc:
# BUILD.gn 使用到该源码的相应模块 { ... cflags_cc = [ ... "-fexceptions", ... ] }移植过程中还有许多诸如此类的编译报错,在此不进行一一列举。
想了解更多内容,请访问:
和华为官方合作共建的鸿蒙技术社区
https://harmonyos.51cto.com
很赞哦!(491)
上一篇: 创建绿色数据中心的三个关键战略