MySQL Server 鸿蒙 PC 适配全记录:以混合工具链完成 C++23 交叉编译与 HNP 交付
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
欢迎在 PC 社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_mysql-server
一、为什么要适配 MySQL Server
MySQL 是使用最广泛的开源关系型数据库之一。从本地开发环境、教学实验到企业业务系统,大量应用都依赖它的 SQL 语义、InnoDB 事务、客户端工具和数据文件体系。对 HarmonyOS PC 来说,数据库的价值也不只是一款可启动的应用:如果能够提供可复用的原生服务端和命令行工具,开发者就能在设备本地完成建库、调试、数据验证与离线演示,其他需要关系型存储的移植项目也多了一项基础能力。
选择 MySQL Server 作为适配对象,还有一层工程上的考虑。它不是带有现成跨平台界面的桌面应用,也不能依靠 Web 容器换一个运行入口;它是一套规模庞大的 C++ 服务端工程,构建过程会生成并执行自己的代码生成工具,同时依赖 OpenSSL、ncurses、ICU、protobuf 等组件。这个项目能够较完整地检验 HarmonyOS PC 原生软件生态中的几项关键能力:C++23 工程交叉编译、musl 兼容、复杂依赖打包、HNP 系统级命令注册,以及真机上的后台服务与客户端协同。
本次适配基于 MySQL Server 9.7.0,目标设备为 HarmonyOS PC 2in1,目标架构为 arm64-v8a,应用 BundleName 为 com.example.mysqlserver。最终交付形态是“介绍页 HAP + MySQL HNP”:HAP 负责安装、签名和使用引导,HNP 提供 mysqld、mysql、mysqladmin、mysqldump、mysql-init 与 mysqld-start 六个终端命令。
二、先确定适配路线:MySQL 不能按普通应用打包
MySQL 上游源码默认面向服务器和桌面操作系统。即使把若干源文件编译通过,也不代表数据库可以在鸿蒙 PC 上运行。完整链路至少包含四个相互关联的层次:
| 层次 | 上游工程的默认假设 | 鸿蒙侧处理方式 |
|---|---|---|
| 构建期 | 构建机可以直接执行刚生成的工具 | 先在 macOS 构建代码生成工具,再将交叉阶段调用转发到本机版本 |
| 编译期 | glibc 与较新的 C++ 标准库能力齐备 | 使用 clang 22 前端、OHOS musl sysroot 与 SDK libc++/lld 的混合工具链 |
| 交付期 | 二进制、动态库与数据文件由系统包管理器部署 | 将服务端、客户端、依赖库、字符集和脚本统一打成 HNP |
| 运行期 | 数据目录、动态库、字符集和终端能力位于传统 Linux 路径 | 启动脚本解析 HNP 软链,设置运行环境,并选择全小写可写数据目录 |
这里最重要的判断是:HAP 不是 MySQL 的运行时本体。真正提供数据库能力的是 HNP 中的 aarch64 原生 ELF;HAP 则是符合 HarmonyOS 安装、签名和应用管理要求的载体。这样既保留了 MySQL 熟悉的命令行使用方式,也避免把数据库进程硬塞进 ArkUI 页面生命周期。
三、鸿蒙版本的整体结构
仓库仍然保持 MySQL 上游源码树的基本形态,鸿蒙适配新增内容主要集中在 ohos_port/、ohos/ 和构建脚本中:
ohos_mysql-server/
├── build_mysql_hnp.sh # 两阶段构建、依赖交叉编译与 HNP 打包
├── OHOS_PORT.md # 源码兼容改动说明
├── ohos_port/
│ ├── mysql-ohos.toolchain.cmake # clang 22 + OHOS SDK 混合工具链
│ ├── ohos-tool-runner.sh # 构建期工具转发
│ ├── hnp.json # HNP 元数据与六个公开命令
│ ├── mysql-init # 数据目录初始化
│ ├── mysqld-start # 服务启动与运行状态检查
│ ├── mysql-client-wrapper # 客户端路径和 terminfo 处理
│ └── terminfo/ # 随包提供的终端能力数据库
└── ohos/
├── AppScope/ # 应用包名、版本和图标
├── hnp/arm64-v8a/mysql.hnp # 约 46 MB 的 MySQL 原生包
├── hnp-inject-plugin.ts # 在打包与签名之间注入 HNP
└── entry/
├── src/main/module.json5 # 2in1、INTERNET 权限与 HNP 声明
└── src/main/ets/pages/Index.ets
构建完成后的数据流如下:
MySQL C/C++ 源码
├── Stage A:macOS 本机构建 9 个代码生成工具
└── Stage B:aarch64-unknown-linux-ohos 交叉编译
├── mysqld / mysql / mysqladmin / mysqldump
├── bundled 动态库与 ICU 数据
└── 初始化、启动、客户端包装脚本
└── mysql.hnp
└── 注入、签名为 entry-default-signed.hap
四、从原生安装到 SQL 事务的真机验证
1. 用 HAP 提供安装入口和使用说明
应用页面只承担必要的交付说明:显示 MySQL Server 版本、列出随 HNP 注册的命令,并给出初始化、启动和连接顺序。数据库本身不依赖页面保持前台,用户可以关闭介绍页后继续在系统终端中使用服务。
以下五张图片均采集自已连接的 HarmonyOS PC 2in1 真机,设备截图分辨率为 3120×2080。测试使用仓库当前生成并安装的 arm64-v8a 签名 HAP;终端中的 SQL 均由设备内 HNP 提供的 mysql 客户端实际执行。

这种交付方式也让操作边界更清晰:mysql-init 只负责首次初始化,mysqld-start 负责以固定参数启动服务,mysql 和管理工具则保持上游熟悉的参数形式。对第一次接触 HNP 的用户来说,不需要手工寻找安装目录,也不需要把二进制复制到应用沙箱。
2. 确认运行的确实是鸿蒙设备上的 aarch64 产物
HNP 安装后会根据 hnp.json 在公共命令目录创建软链。mysql-client-wrapper 逐级解析软链,定位 HNP 中真实的 mysql.bin,再补充包内 terminfo 路径。这样既能从系统终端直接执行 mysql,方向键、历史命令等交互能力也不依赖设备预装 ncurses 数据文件。
真机执行 mysql --version 返回 HNP 内部真实路径,并明确给出 Ver 9.7.0 for Linux on aarch64;随后通过本地 socket 连接服务执行 SELECT VERSION(),返回 9.7.0。

这个验证比“应用页面显示了版本号”更有意义:页面文本来自资源配置,而终端输出来自实际运行的客户端 ELF,并且 SQL 查询已经穿过客户端、socket、服务器和执行引擎的完整链路。
3. 建库、建表、插入与查询形成最小数据闭环
验证数据库不能停在服务进程存在。测试在真机上创建 harmony_demo 数据库和带自增主键、字符串、DECIMAL 字段的 products 表,插入两条记录后再使用 SELECT 读取。截图中的 HarmonyOS PC、MySQL 9.7 和价格均来自 InnoDB 表中的真实数据。

这里同时覆盖了几项容易被忽略的基础能力:系统表已经正确初始化,InnoDB 可以创建表空间,自增列工作正常,字符串与定点数能够写入并按列格式返回。它们共同证明当前产物不是只能响应版本查询的裁剪壳。
4. 更新和删除必须能反映到后续查询
在同一数据库中继续执行 UPDATE,把第一条记录价格从 6999 调整为 6499;再执行 DELETE 移除第二条记录。紧接着的查询只返回更新后的第一行,说明修改和删除均已经落入存储引擎,而不是终端侧的静态演示结果。

将变更语句和最终查询放在同一次真机验证里,可以直接观察条件匹配、行更新与删除结果。对数据库移植来说,这比单独展示“Query OK”更容易判断行为是否符合预期。
5. 用回滚验证 InnoDB 事务语义
最后一项核心验证是事务回滚。测试开启事务后将商品价格临时改为 1.00,事务内查询能够看到新值;执行 ROLLBACK 后再次查询,价格恢复为 6499.00。

这张图验证的是 InnoDB 的事务隔离与撤销链路,而不只是 SQL 解析器接受了 ROLLBACK 关键字。从真机结果看,当前适配已经覆盖本地单机数据库最核心的建库、建表、增删改查和事务回滚闭环。
五、适配过程中最棘手的几个问题
难点一:SDK clang 15 无法完成 MySQL 9.7 的 C++23 编译
MySQL 9.7 使用了较新的 concepts、ranges、GTID 模板和标准库接口。OpenHarmony SDK 自带 clang 15 在部分代码上缺少所需语言能力,甚至会触发编译器内部错误;但如果完全换成桌面端工具链,又会失去目标设备所需的 musl ABI、系统头文件和运行库约束。
最终方案是混合工具链:Homebrew clang 22 负责 C/C++ 前端,OHOS SDK 提供 aarch64-unknown-linux-ohos sysroot、libc++ 15、ld.lld 和 compiler-rt builtins。针对 SDK libc++ 版本较旧的问题,再用最小兼容修改替换 stringstream::view()、views::keys、string_view 三路比较等缺失接口。所有平台相关修改都通过 musl 或 libc++ 版本条件保护,避免影响上游其他平台构建。
难点二:交叉编译阶段会尝试执行目标架构程序
MySQL 构建过程中需要运行 comp_err、gen_lex_hash、protoc 等代码生成工具。如果在交叉阶段直接使用刚生成的目标程序,macOS 构建机会因为 aarch64 OHOS ELF 无法执行而中断。
项目采用两阶段构建:Stage A 先在 macOS 上生成 9 个构建期工具;Stage B 交叉编译时,通过 CMAKE_CROSSCOMPILING_EMULATOR 和 ohos-tool-runner.sh 按命令名转发到 Stage A 产物。代码生成结果是平台无关的源码或数据,因此既满足构建流程,也不会把宿主机二进制混入 HNP。
难点三:glibc 假设要逐项映射到 musl
OHOS musl 与常见 Linux glibc 环境并不完全等价。适配中处理了线程取消接口缺失、DNS SRV 查询 API 差异、qsort_r 行为分支、宽字符检查、zlib/libedit 隐式声明等问题;CMake 层还需要允许禁用 SASL、LDAP、Kerberos 等当前单机场景不需要的认证依赖。
这些改动不能简单地用空宏覆盖所有错误。每一处都要判断它是否会改变数据库正确性。例如线程取消兼容只用于当前工具链缺失的取消接口,而存储引擎、SQL 执行和客户端网络能力仍然保留;DNS 与排序接口则选择已有的可移植分支,尽量复用上游经过验证的实现。
难点四:InnoDB 对数据目录大小写的判断会在真机上失效
真机首次初始化能够完成,但后续启动曾出现 undo 表空间已存在并中止的问题。根因不是文件损坏,而是 /storage/Users/currentUser 含有大写字母,同时挂载文件系统又报告大小写不敏感。InnoDB 会把绝对路径转成小写后扫描,上层路径实际区分大小写,最终扫描失败并误判为全新实例。
适配没有修改 InnoDB 的通用路径逻辑,而是在 mysql-init 与 mysqld-start 中统一选择 /data/storage/el2/base/mysql-data 这类全小写、可写目录。脚本先检查父目录和写权限,再用于初始化、socket、PID 与日志文件,避免同一套路径规则在多处重复实现。
难点五:HNP 必须进入签名前的 HAP 打包流程
仅在 module.json5 声明 hnpPackages 并不足以保证 HNP 被放进最终 HAP。当前 hvigor 插件的默认打包任务没有向 app_packing_tool 传入 HNP 路径,设备安装时会因找不到 Native Package 而失败。
项目新增 hnp-inject-plugin.ts,让注入任务依赖 PackageHap 并先于 SignHap 执行。插件使用 app_packing_tool.jar --hnp-path 重打未签名 HAP,再交给 hvigor 原有签名任务处理。这样 HNP 内容与 HAP 签名保持一致,证书和密码仍由构建系统内部管理。
六、构建、安装与启动
本项目不是 Electron 或 Qt 应用,因此使用 CMake、Ninja、OpenHarmony Native SDK 与 hvigor 完成构建。开发机需要准备 DevEco Studio/OpenHarmony SDK,以及 Homebrew 的 LLVM、lld、bison 和 GNU make:
brew install llvm lld bison make
交叉编译和 HNP 打包使用仓库根目录脚本:
./build_mysql_hnp.sh
脚本依次完成本机构建期工具、OpenSSL 3.0.17、ncurses 6.4、目标端 MySQL 二进制和 HNP 打包。完整构建中间目录约需要 15 GB 磁盘空间。生成的 Native Package 位于:
ohos/hnp/arm64-v8a/mysql.hnp
随后构建并签名 HAP:
cd ohos
export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
export JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home
hvigorw assembleHap
签名产物位于:
ohos/entry/build/default/outputs/default/entry-default-signed.hap
连接 HarmonyOS PC 后安装并启动介绍页:
hdc list targets
hdc install -r ohos/entry/build/default/outputs/default/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.example.mysqlserver -m entry
在系统终端中完成首次初始化、服务启动和连接:
mysql-init
mysqld-start
mysql -u root --skip-password \
-S /data/storage/el2/base/mysql-data/mysql.sock
当前签名 HAP 约 47 MB,其中 mysql.hnp 约 46 MB。HNP 除四个主要二进制和两个辅助脚本外,还包含 bundled 动态库、ICU 数据、错误消息、字符集和 terminfo;这些运行时资产缺一不可,不能只分发 mysqld 单个文件。
七、当前功能边界
当前版本已在 HarmonyOS PC 真机上验证以下核心能力:
- HAP 签名安装、HNP 解包与六个公共终端命令注册;
- 全小写数据目录的首次初始化与重复初始化保护;
mysqld本地服务启动、InnoDB 初始化与 Unix socket 连接;mysql客户端版本查询与 aarch64 运行架构确认;- 数据库和 InnoDB 表创建;
- 自增主键、字符串与
DECIMAL数据的插入和查询; - 条件更新、条件删除与结果复查;
START TRANSACTION、修改与ROLLBACK回滚;mysqladmin、mysqldump客户端随 HNP 交付。
适配范围也有明确边界。当前构建关闭了 MySQL Router、NDB、X 协议、LDAP/Kerberos/SASL 认证、组复制相关组件和单元测试目标,重点面向 HarmonyOS PC 本地单机开发与数据处理场景。OHOS 缺少 Linux 原生 AIO,InnoDB 使用模拟 AIO,功能正确性不受影响,但高并发磁盘负载下的性能不能直接等同于服务器 Linux 环境。
另外,当前真机验证集中在本地 socket、核心 SQL 和事务闭环,没有将多节点复制、企业认证、外部插件生态和长期压力测试描述为已经完成。对这类服务端软件,功能可用与生产级部署是两个层次;现阶段更准确的定位是“可在 HarmonyOS PC 真机本地运行的 MySQL Server 9.7.0 开发与实验版本”。
八、总结
MySQL Server 的鸿蒙 PC 适配表明,大型 C++ 服务端项目进入新平台时,真正困难的部分往往不在某一个编译错误,而在构建期程序、目标 ABI、依赖部署、系统包格式和运行路径之间的连续约束。
本项目用两阶段构建解决了交叉编译期间执行目标程序的问题,用 clang 22 与 OHOS SDK 组成混合工具链补齐 C++23 能力,用小范围条件补丁处理 musl 和旧版 libc++ 差异,再通过 HNP 把服务端、客户端和运行时数据作为一个整体交付。最后,真机上的版本查询、建库建表、增删改查与事务回滚证明这条链路已经从“能够产出文件”走到了“能够处理真实数据”。
这套方法也适用于其他没有图形界面、但依赖复杂原生构建系统的开源基础软件:先厘清构建期与运行期边界,再保证 ABI 和依赖闭环,最后用目标设备上的真实业务操作验收,而不是把编译成功当作适配完成。
更多推荐




所有评论(0)