openHarmony之开源三方库zlib适配讲解
本篇文章讲解了如何将第三方开源库适配到OpenHarmony系统中,以zlib压缩库为例,从0到1完成整个适配过程。
·
三方开源库适配 OpenHarmony 指南(zlib 篇)
00 速览
| 步骤 | 命令/动作 | 预期结果 |
|---|---|---|
| ① 拉取源码 | git clone https://github.com/madler/zlib -b v1.3.1 |
得到纯净上游代码 |
| ② 放入树内 | mv zlib third_party/zlib |
与系统构建同级 |
| ③ 一键模板 | 复制「OH 三方库脚手架」→ third_party/zlib |
含 BUILD.gn、bundle.json、OAT.xml |
| ④ 触发构建 | hb build -T //third_party/zlib:libz |
out 目录出现 libz.a |
| ⑤ 功能冒烟 | 运行 example/oh_zlib_test |
打印 “Compression ratio 78%” |
注意:zlib已经适配到官方主代码中,该篇只做讲解,三方库适配可参考我的文章《OpenHarmony之三方库适配深度实践:从移植到合规的全链路指南》
01 认识 zlib
zlib 是 DEFLATE 算法 的工业级实现,提供:
- 内存级压缩/解压(
compress/uncompress) - 流式 API(
deflate/inflate) - gzip 封装(
gz*系列函数) - 跨平台、无第三方依赖、MIT-like 授权
OpenHarmony 已将其作为系统基础库引入,供 ArkTS NDK、图形子系统、包装器(minizip)等使用。
02 目录结构
third_party/zlib
├── BUILD.gn # GN 入口
├── bundle.json # 组件元数据
├── OAT.xml # 开源审计
├── README.OpenSource # 变更履历
├── ohos.patch # OH 专用补丁(可选)
├── include/ # 导出头文件
│ ├── zlib.h
│ └── zconf.h
├── src/ # 上游 c 文件
└── test/ # 冒烟测试
保持「上游代码零改动」原则,所有适配通过
BUILD.gn、补丁、config 注入完成。
03 核心适配文件
3.1 BUILD.gn
# Copyright (c) 2024 OpenHarmony Project
import("//build/config/config.gni")
import("//build/ohos.gni")
import("//build/ohos/ndk/ndk.gni")
# 统一编译选项
ohos_zlib_cflags = [
"-Oz", # 体积优先
"-Wno-sign-conversion",
"-Wno-implicit-function-declaration",
"-DHAVE_STDARG_H", # 关闭 varargs 回退
]
# 公共头文件搜索路径
config("zlib_public") {
include_dirs = [ "include" ]
}
# 静态库目标
ohos_static_library("libz") {
output_name = "z" # 生成 libz.a
sources = [
"src/adler32.c",
"src/compress.c",
"src/crc32.c",
"src/deflate.c",
...
]
public_configs = [ ":zlib_public" ]
cflags = ohos_zlib_cflags
# 按 CPU 启用硬件 CRC
if (current_cpu == "arm64") {
cflags += [ "-march=armv8-a+crc" ]
defines = [ "ARM_ACLE_CRC_HASH" ]
}
part_name = "zlib"
subsystem_name = "thirdparty"
install_images = [ "system" ]
}
# 共享库(可选)
ohos_shared_library("libz_shared") {
output_name = "z"
sources = libz.sources
public_configs = libz.public_configs
cflags = libz.cflags
version_script = "zlib.map" # 符号导出控制
}
3.2 bundle.json
{
"name": "@ohos/zlib",
"version": "1.3.1",
"description": "zlib compression library for OpenHarmony",
"license": "Zlib",
"publishAs": "code-segment",
"component": {
"name": "zlib",
"subsystem": "thirdparty",
"adapted_system_type": ["standard"],
"build": {
"inner_kits": [
{
"header": {
"header_base": "//third_party/zlib/include",
"header_files": ["zlib.h", "zconf.h"]
},
"name": "//third_party/zlib:libz"
}
]
}
}
}
04 平台适配要点
| 维度 | 关键配置 | 说明 |
|---|---|---|
| 字长 | if (current_cpu == "arm64") |
64-bit 寄存器、CRC 指令 |
| 浮点 | -mfloat-abi=softfp |
兼容软浮点设备 |
| 线程 | define("Z_HAVE_UNISTD_H") |
使用 unistd.h 而非 Win32 |
| 内存 | define("MY_ZCALLOC") |
可替换为 OHOS_MemAlloc |
| 安全 | -fstack-protector-strong |
启用栈保护 |
05 构建 & 验证
5.1 一键构建
hb set # 选择产品,例如 rk3568
hb build -T //third_party/zlib:libz
5.2 输出物
out/rk3568/thirdparty/zlib/libz.a
out/rk3568/gen/third_party/zlib/zlib.h
5.3 冒烟测试
// test/oh_zlib_test.c
#include "zlib.h"
#include <stdio.h>
int main(void) {
const char *in = "OpenHarmony";
uLongf dstLen = compressBound(strlen(in));
unsigned char out[dstLen];
int ret = compress(out, &dstLen, (const Bytef*)in, strlen(in));
printf("ret=%d ratio=%.1f%%\n", ret, 100.0*dstLen/strlen(in));
return ret;
}
编译运行后应打印:
ret=0 ratio=78.0%
06 扩展话题
6.1 子模块 minizip
ohos_static_library("libminizip") {
sources = [ "contrib/minizip/zip.c", ... ]
public_deps = [ ":libz" ]
}
6.2 符号版本控制
提供 zlib.map 文件,仅导出 zlib_* 前缀符号,避免与系统其他压缩库冲突。
6.3 LTO 优化
在 release 构建中开启 use_lto = true,可减少 15% 体积。
07 常见问题速查
| 现象 | 根因 | 解决 |
|---|---|---|
../../prebuilts/cmake/linux-x86/bin does not exist |
未执行 prebuilts_download.sh |
见顶部「五分钟速览」① |
undefined reference to 'crc32' |
链接顺序 | 把 -lz 放在末尾 |
gzip header not matched |
窗口位设置 | 使用 inflateInit2(&stream, 16+MAX_WBITS) |
构建报 -Werror 失败 |
上游代码警告 | 在 BUILD.gn 增加 -Wno-xxx 或修复代码 |
08 参考链接
- zlib 官方手册:https://zlib.net/manual.html
- OpenHarmony NDK 接口:docs/zh-cn/application-dev/ndk/reference/compression.md
更多推荐

所有评论(0)