三方开源库适配 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 参考链接

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐