介绍一个容器化的鸿蒙环境

前言

最近一年多以来,我折腾了很多鸿蒙相关的东西,比如做了 Node.js 的鸿蒙移植。

在开发活动中,我搞出了一些自认为用得还算顺手的工具,其中一个就是容器化的鸿蒙环境。

现在我把这个自用的工具开源了:github.com/hqzing/dock...

这个鸿蒙容器使我们能够使用 Linux 服务器来运行和测试我们的命令行程序,而不用依赖 OpenHarmony 物理设备。

基础用法

要使用这个鸿蒙容器,你首先要有一个 arm64 服务器(各大云厂商都有卖),然后服务器上要装好 Docker。

买服务器的时候建议选香港或国外的区域,因为容器托管在 GitHub 上,我下面提到的那一批工具也在 GitHub 上,中国大陆的服务器访问 GitHub 可能会网速慢或者访问不通。

环境就绪之后,只需要一条命令就能把容器拉起来:

sh 复制代码
docker run -itd --name=ohos ghcr.io/hqzing/docker-mini-openharmony:latest

(Docker 检测到本地没有这个镜像它会自动去拉取,所以 docker pull 的过程可以做,也可以不做)

然后再一条命令,就能进入容器中操作:

sh 复制代码
docker exec -it ohos sh

工具获取

这个容器里面只是一个最小系统,除了 toybox 提供的少量命令和我内置进去的 curl 以外,里面什么工具都没有。这是无法支撑开发工作的,所以我们要根据自己的实际需求,往里面装一些工具。

至于工具从哪来?你可以根据 README 文档的操作去 Alpine Linux 的软件仓库获取;也可以用我移植好的工具;或者去找别人移植好的工具。

这是我移植好的一批工具,使用方式已经写在各项目的 README 文档里面了

工具类别 名称 项目地址
实用工具 busybox github.com/Harmonybrew...
实用工具 grep github.com/Harmonybrew...
编译工具链 llvm github.com/Harmonybrew...
编译工具链 make github.com/Harmonybrew...
编译工具链 ninja github.com/Harmonybrew...
编译工具链 cmake github.com/Harmonybrew...
编译工具链 m4 github.com/Harmonybrew...
编译工具链 autoconf github.com/Harmonybrew...
文本编辑器 neovim github.com/Harmonybrew...
命令行解释器 zsh github.com/Harmonybrew...
版本控制工具 git github.com/Harmonybrew...
运行时环境 perl github.com/Harmonybrew...
运行时环境 ruby github.com/Harmonybrew...
运行时环境 node github.com/hqzing/ohos...

实践案例

这个鸿蒙容器,搭配上面给出的这些工具一起使用,就可以胜任很多开发工作了。

比如这几个项目就是基于鸿蒙容器完成的构建:

你也可以尝试模仿里面的做法,去编你想编的软件。

另外我再介绍个比较黑科技的做法:你甚至可以把 llvm 软链接成 gcc 和 binutils,这样就不用每次编东西还要配一堆 CC、CXX 之类的环境变量了。

比如这样

sh 复制代码
tar -zxf llvm-21.1.5-ohos-arm64.tar.gz -C /opt

cd /opt/llvm-21.1.5-ohos-arm64/bin
ln -s clang cc
ln -s clang gcc
ln -s clang++ c++
ln -s clang++ g++
ln -s ld.lld ld
ln -s llvm-ar ar
ln -s llvm-nm nm
ln -s llvm-objcopy objcopy
ln -s llvm-objdump objdump
ln -s llvm-ranlib ranlib
ln -s llvm-size size
ln -s llvm-strings strings
ln -s llvm-strip strip
cd -

export PATH=$PATH:/opt/llvm-21.1.5-ohos-arm64/bin

这个做法你也可以在 MacOS 里面看到。你可以去 MacOS 上看 gcc、ld、ar 等命令的实际路径在什么地方,你会看到实际上是软连接到 llvm 里面去了。

迭代过程

这个鸿蒙容器截止到现在已经经历了 3 个版本迭代,现在开源出来的是最后一个最成熟的版本。

第 1 个版本:早期最简版本

最开始做的时候,OpenHarmony 还是 4.0 版本。当时只要编一份 arm64 架构的 rk3568 镜像,把里面的 ramdisk.img 解压、打成 tar 包、导入到 Docker 中就能直接用。

因为当时我找到的官方 rk3568 镜像只有 32 位的,而我编的软件要在 64 位系统上进行测试,所以需要自己编 64 位的系统。

第 2 个版本:事情逐渐变得复杂

到了 OpenHarmony 5.1 版本的时候,我对环境进行了一次升级。这时候发现 OpenHarmony 官方社区的日构建流水线里面就有提供 dayu200-arm64_5.1.0-Release 的产物,不用我自己去编 64 位系统了。

但是这个新版本带来了一个新问题:单把 ramdisk.img 里面的内容导到 Docker 里面是跑不起来的,因为这里面的 toybox 被改造了,它依赖了一个 system.img 里面的 so。我不得不分别从两个镜像各取一部分内容,放在一起,导入到 Docker 中。

第 3 个版本:需要改造系统源码

升级完版本之后,发现它时不时会在各进程的 stderr 里面输出一些类似于 HiLogAdapter: Can't connect to server. 这样的报错。

定位之后发现是 OpenHarmony 社区把 musl libc 进行了改造,做了很多日志输出,而且日志是对接到 HiLog 里面的。我在容器里面没有启动 init 进程,也没把 HiLog 相关的东西带进来,容器中自然就不会有 HiLog 服务,于是 musl libc 没法通过 socket 跟 HiLog 服务进行通信,因此就时不时会有错误日志从各个进程的 stderr 里面冒出来,这会在一些情况下会导致业务异常。

为了处理这个问题,我只好放弃使用 OpenHarmony 官方编好的包,又换回了自己编包的方案。只有这样做,我才能通过改源码的方式去处理这个 musl libc 对 HiLog 的依赖问题。

演进计划

这个鸿蒙容器和 Harmonybrew 组织下面的那些 ohos-xxx 项目,它们以后都会变成 Harmonybrew 项目的基建的一部分。Harmonybrew 项目是一个把 Homebrew 移植到 OpenHarmony 平台的项目,我正在为了实现这个目标而开展一些工作。

优先挑选出这一批软件进行移植,是因为:它们要么是 Homebrew 所需的依赖(git、curl、zsh、ruby),要么是编其他软件的时候需要用到的编译工具链(llvm、make 等)。有了 git、curl、zsh、ruby,Homebrew 就能在 OpenHarmony 上运行了。在这基础上,把 llvm、make 等软件作为第一批 bottles 录入到自建的鸿蒙版 Homebrew 仓库中,用户就能基于这些工具去构建更多的 bottles。这样一路操作下去就能完成整个生态的自举。

而鸿蒙容器在 Harmonybrew 项目中主要会用于流水线业务,用来把用户贡献的 formula 构建成 bottles。毕竟 OpenHarmony 官方并没有提供云化的环境,现在也没有看到第三方厂商的解决方案,我们没法像 Windows、Linux、MacOS 那样很方便地在流水线上面进行原生编译和自动化测试。在这种情况下,除了用这个鸿蒙容器以外没有其他选择了。

Harmonybrew 相关的坑已经占好了(GitCode 链接GitHub 链接),已经"新建文件夹"了。大家敬请期待,到时候做好了欢迎大家过来贡献 formula。

相关推荐
HAPPY酷1 小时前
【ROS2】VMware + Docker 运行 Gazebo 崩溃与“假死”排查实录
qt·docker·容器
aaPIXa6221 小时前
C++ TensorRT Edge-LLM 边缘推理框架:从原理到实战
开发语言·c++·edge
nianniannnn3 小时前
c++复习自存--标准模板库STL
开发语言·c++·windows
努力努力再努力wz3 小时前
【高性能网络库与HTTP Server系列】:基于主从 Reactor 模型实现高性能 C++ 网络库与 HTTP Server
开发语言·网络·数据结构·数据库·c++·网络协议·http
Robot_Nav3 小时前
C++ 面试常问问题汇总:基础语法、面向对象、STL、多线程与设计模式
c++·设计模式·面试
盐焗鹌鹑蛋4 小时前
【C++】二叉搜索树
c++
哎呦,帅小伙哦4 小时前
C++工程实战: 预处理宏、宏重定义避坑、LOG_TAG业务实践与__COUNTER__深度解析
c++
IVVi0jToe4 小时前
高效C++线程池设计与实现
java·c++·安全
^yi4 小时前
【C++】内存管理
开发语言·c++
云栖梦泽4 小时前
从 IMX415 摄像头驱动理解 Media Controller 框架
linux·开发语言·c++·嵌入式硬件