首页
/ OpenCV 内置 zlib-ng:特性、构建选项全解与 WITH_ZLIB_NG 切换实践

OpenCV 内置 zlib-ng:特性、构建选项全解与 WITH_ZLIB_NG 切换实践

2026-09-05 16:17:41作者:管翌锬

本文以 OpenCV 仓库中内置的 zlib-ng 压缩库文档(3rdparty/zlib-ng/README.md)为主体,完整梳理 zlib-ng 的核心特性、CMake 与 configure 两套构建流程、全部构建选项,并结合 OpenCV 集成侧的实际 CMake 逻辑与源码布局,说明如何通过 WITH_ZLIB_NG 选项将 OpenCV 的图像编解码底层压缩实现切换到 zlib-ng,以及其 SIMD 加速代码在仓库中的具体位置。

一、zlib-ng 是什么:特性总览

zlib-ng 定位是 "zlib data compression library for the next generation systems",即面向新一代系统的 zlib 数据压缩库。根据 README,其核心特性包括:

  • 兼容 zlib 的 API,并支持双链接(dual-linking):应用可以按原有 zlib 头文件与函数签名使用;
  • 基于 zlib API 现代化的原生 API:便于从 zlib 平滑移植;
  • 现代 C11 语法与整洁的代码布局:清理了大量 zlib 为兼容极老编译器、16 位环境而保留的 workaround 代码;
  • 来自 Intel 分支的 deflate medium / quick 新压缩策略
  • CPU 指令集(intrinsics)支持,这是 zlib-ng 性能优势的主要来源,README 中列出的加速实现包括:
    • Adler32:SSSE3、AVX2、AVX512、AVX512-VNNI、Neon、VMX(AltiVec)、VSX;
    • CRC32-B:PCLMULQDQ、VPCLMULQDQ、ACLE、IBM Z;
    • slide_hash(滑窗哈希):SSE2、AVX2、ARMv6、Neon、VMX、VSX;
    • compare256(匹配比较):SSE2、AVX2、Neon、POWER9、RVV;
    • inflate 块拷贝:SSE2、SSSE3、AVX、Neon、VSX;
    • IBM Z DFLTCC 硬件加速 deflate;
  • 非对齐内存读写与大容量位缓冲改进
  • 合并了 Cloudflare 与 Intel 分支的改进
  • 同时支持 configure、CMake、NMake 构建系统,配套完整的 CMake 单元测试、代码 sanitizer、fuzzing、覆盖率与多平台(含 qemu 模拟的 ARM、PPC、RISC-V、SPARC64、S390x 等)CI。

关于项目缘起,README 的 History 部分说明:fork 的动机是看到许多新的第三方优化(主要来自 Intel 分支)难以进入官方 zlib 仓库,而 zlib 中大量面向远古编译器和受限系统的 workaround 已成为维护负担。zlib-ng 的目标不是取代 zlib,而是作为"低门槛改动的 drop-in replacement"与其共存。

本仓库内置的 zlib-ng 版本可通过 3rdparty/zlib-ng/zlib.h.in 确认:

#define ZLIBNG_VERSION "2.2.1"
#define ZLIB_VERSION "1.3.1.zlib-ng"

即 zlib-ng 2.2.1,对外保持与 zlib 1.3.1 的兼容版本号(1.3.1.zlib-ng)。

二、两套构建方式

README 给出两种构建路径,二者等价,任选其一。

CMake 构建

cmake .
cmake --build . --config Release
ctest --verbose -C Release

也可以用图形化配置工具:

ccmake .

configure 脚本构建(Unix 类系统)

./configure
make
make test

在 OpenCV 中实际启用 zlib-ng

OpenCV 并不默认使用 zlib-ng,而是默认优先查找系统 zlib,找不到时才回落到内置的传统 zlib(3rdparty/readme.txt 明确指出"WITH_ZLIB_NG CMake option must be ON to use zlib-ng as the zlib implementation")。

CMakeLists.txt 中定义了对应开关:

OCV_OPTION(WITH_ZLIB_NG "Use zlib-ng instead of zlib" OFF
  VISIBLE_IF TRUE
  VERIFY HAVE_ZLIB_NG)

配置阶段只需添加 -DWITH_ZLIB_NG=ON。其生效逻辑在 cmake/OpenCVFindLibsGrfmt.cmake

if(WITH_ZLIB_NG)
  ocv_clear_vars(ZLIB_LIBRARY ZLIB_LIBRARIES ZLIB_INCLUDE_DIR)
  set(ZLIB_LIBRARY zlib CACHE INTERNAL "")
  add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/zlib-ng")
  ...
  set(HAVE_ZLIB_NG YES)
else()
  # 先 find_package(ZLIB),找不到再 add_subdirectory(3rdparty/zlib)

也就是说开启 WITH_ZLIB_NG 后,OpenCV 会直接以子目录方式构建 3rdparty/zlib-ng,并把 ZLIB_LIBRARY/ZLIB_INCLUDE_DIR 等变量指向该构建产物,供后续 imgcodecs 等模块链接使用。

三、构建选项(Build Options)完整清单

以下表格完整继承自 README 的 Build Options 一节(CMake 选项 / configure 选项 / 说明 / 默认值):

CMake configure 说明 默认值
ZLIB_COMPAT --zlib-compat 编译 zlib 兼容 API OFF
ZLIB_ENABLE_TESTS 构建测试二进制 ON
WITH_GZFILEOP --without-gzfileops 编译 gzFile 相关函数支持 ON
WITH_OPTIM --without-optimizations 带优化构建 ON
WITH_NEW_STRATEGIES --without-new-strategies 使用新的 deflate 策略(medium/quick) ON
WITH_NATIVE_INSTRUCTIONS 使用本机构支持的全部指令集编译(gcc/clang -march=native OFF
WITH_RUNTIME_CPU_DETECTION 带运行时 CPU 检测编译 ON
WITH_SANITIZER 带 sanitizer(memory、address、undefined)构建 OFF
WITH_GTEST 构建 gtest_zlib ON
WITH_FUZZERS 构建 test/fuzz OFF
WITH_BENCHMARKS 构建 test/benchmarks OFF
WITH_MAINTAINER_WARNINGS 启用项目维护者级别的编译告警 OFF
WITH_CODE_COVERAGE 启用代码覆盖率报告 OFF

注意:OpenCV 内置副本的实际默认值与上表不同

OpenCV 通过补丁(见 3rdparty/zlib-ng/patches/zlib-ng-2.2.1-detect-intrinsics.patch)调整了内置 3rdparty/zlib-ng/CMakeLists.txt 的默认值,使其适合作为 OpenCV 的依赖库而非独立发行版。对照上表,实际差异包括:

  • ZLIB_COMPAT 在 OpenCV 副本中默认为 ON(独立发行版默认 OFF):option(ZLIB_COMPAT "Compile with zlib compatible API" ON),因为 OpenCV 各模块按标准 zlib API 调用,需要兼容层;
  • ZLIB_ENABLE_TESTSZLIBNG_ENABLE_TESTSWITH_GTEST 均为 OFF:构建 OpenCV 时不需要 zlib-ng 自身的测试二进制;
  • ZLIB_BUILD_SHARED_LIBS OFFSKIP_INSTALL_ALL ON:由 OpenCV 顶层统一决定静态/共享与安装行为(见 CMakeLists.txt 与末尾的 ocv_install_target);
  • 大量高级指令集选项被 mark_as_advanced(FORCE ...) 隐藏,避免在 OpenCV 的 ccmake 界面中暴露。

开启 ZLIB_COMPAT 后,产物导出名为 ZLIB、目标属性 SOVERSION 1VERSION1.3.1.zlib-ng(见 3rdparty/zlib-ng/CMakeLists.txtSOVERSION 设置),这正是"drop-in replacement"在构建层面的体现。

四、高级构建选项(Advanced Build Options)完整清单

README 的 Advanced Build Options 表格完整如下:

CMake configure 说明 默认值
FORCE_SSE2 --force-sse2 跳过 SSE2 运行时检测(x86_64 上恒为开启) OFF(x86 32 位)
WITH_AVX2 构建 AVX2 intrinsics ON
WITH_AVX512 构建 AVX512 intrinsics ON
WITH_AVX512VNNI 构建 AVX512VNNI intrinsics ON
WITH_SSE2 构建 SSE2 intrinsics ON
WITH_SSSE3 构建 SSSE3 intrinsics ON
WITH_SSE42 构建 SSE42 intrinsics ON
WITH_PCLMULQDQ 构建 PCLMULQDQ intrinsics ON
WITH_VPCLMULQDQ --without-vpclmulqdq 构建 VPCLMULQDQ intrinsics ON
WITH_ACLE --without-acle 构建 ACLE intrinsics ON
WITH_NEON --without-neon 构建 NEON intrinsics ON
WITH_ARMV6 --without-armv6 构建 ARMv6 intrinsics ON
WITH_ALTIVEC --without-altivec 构建 AltiVec (VMX) intrinsics ON
WITH_POWER8 --without-power8 构建 POWER8 优化 ON
WITH_RVV 构建 RVV intrinsics ON
WITH_CRC32_VX --without-crc32-vx IBM Z 上构建向量化 CRC32 ON
WITH_DFLTCC_DEFLATE --with-dfltcc-deflate IBM Z 上使用 DFLTCC 硬件压缩 OFF
WITH_DFLTCC_INFLATE --with-dfltcc-inflate IBM Z 上使用 DFLTCC 硬件解压 OFF
WITH_UNALIGNED --without-unaligned 当前架构安全时允许非对齐读优化 ON
WITH_INFLATE_STRICT 严格校验 inflate 距离 OFF
WITH_INFLATE_ALLOW_INVALID_DIST 对非法 inflate 距离零填充 OFF
INSTALL_UTILS 安装时附带 minigzip 与 minideflate OFF
ZLIBNG_ENABLE_TESTS 测试 zlib-ng 特有 API ON

其中几个选项在 3rdparty/zlib-ng/CMakeLists.txt 中有明确的架构门控逻辑,值得注意:

  • 各 SIMD 选项按目标架构条件创建:ARM 平台才有 WITH_ACLE/WITH_NEON/WITH_ARMV6,PowerPC 才有 WITH_ALTIVEC/WITH_POWER8/WITH_POWER9,RISC-V 才有 WITH_RVV,s390 才有 WITH_DFLTCC_*WITH_CRC32_VX,x86 才有 WITH_SSE2WITH_VPCLMULQDQ
  • x86 上的选项构成依赖链:WITH_SSSE3 依赖 WITH_SSE2WITH_SSE42 依赖 WITH_SSSE3WITH_PCLMULQDQ/WITH_AVX2 依赖 WITH_SSE42WITH_AVX512 依赖 WITH_AVX2WITH_VPCLMULQDQ 依赖 WITH_PCLMULQDQ;WITH_AVX512,任一环节检测失败则后续项自动关闭;
  • WITH_NEW_STRATEGIES=OFF 时定义 NO_QUICK_STRATEGY/NO_MEDIUM_STRATEGY 宏,对应关闭 deflate 第 1 级的 quick 策略与第 4–6 级的 medium 策略(见 CMakeLists.txt 注释),可回退到经典 deflate 行为;
  • WITH_UNALIGNED=OFF 时定义 NO_UNALIGNED,放弃非对齐读优化(CMakeLists.txt)。

五、加速实现落位:从 CMake 选项到 arch/ 源码

README 声称的各指令集实现,在本仓库中都有对应的源文件与编译规则,可以逐一对应:

x863rdparty/zlib-ng/arch/x86/):

  • SSE2:chunkset_sse2.ccompare256_sse2.cslide_hash_sse2.c
  • SSSE3:adler32_ssse3.cchunkset_ssse3.c
  • SSE42:adler32_sse42.c
  • PCLMULQDQ / VPCLMULQDQ:crc32_pclmulqdq.ccrc32_vpclmulqdq.c
  • AVX2:slide_hash_avx2.cchunkset_avx2.ccompare256_avx2.cadler32_avx2.c
  • AVX512 / AVX512-VNNI:adler32_avx512.cadler32_avx512_vnni.c

这些源文件按选项逐个加入编译列表,并单独附加 -mavx2 等目标指令集编译标志(见 CMakeLists.txt),运行时再由 CPU 特性检测模块决定是否启用,实现"一次构建、多代 CPU 通用"。

ARM3rdparty/zlib-ng/arch/arm/):adler32_neon.cchunkset_neon.ccompare256_neon.cslide_hash_neon.c(NEON),crc32_acle.c(ACLE),slide_hash_armv6.c(ARMv6);Linux 下还会探测 sys/auxv.hHWCAP_CRC32/HWCAP2_CRC32 与 NEON hwcap 以支持运行时检测(CMakeLists.txt)。

PowerPC3rdparty/zlib-ng/arch/power/):adler32_vmx.cslide_hash_vmx.c(AltiVec),adler32_power8.cchunkset_power8.ccrc32_power8.cslide_hash_power8.c(POWER8/VSX,powerpc64le 额外启用 CRC32),compare256_power9.c(POWER9)。

RISC-V3rdparty/zlib-ng/arch/riscv/):RVV 向量实现 adler32_rvv.cchunkset_rvv.ccompare256_rvv.cslide_hash_rvv.c

IBM Z3rdparty/zlib-ng/arch/s390/):DFLTC C 硬件加解压缩 dfltcc_deflate.cdfltcc_inflate.c,向量化 CRC32 crc32-vx.c

通用回退3rdparty/zlib-ng/arch/generic/):所有平台都会编译的纯 C 实现 adler32_c.cchunkset_c.ccompare256_c.ccrc32_braid_c.cslide_hash_c.c 等,当 CPU 不具备某指令集时运行时分派(dispatch)会落到这里。

运行时 CPU 检测由 WITH_RUNTIME_CPU_DETECTION(默认 ON)控制,对应 3rdparty/zlib-ng/cpu_features.c 与各架构的 *_features.c;函数指针表在 3rdparty/zlib-ng/functable.c/functable.h。关闭该选项(或启用 WITH_NATIVE_INSTRUCTIONS)后,编译期即按固定架构生成,不再引入检测代码(见 CMakeLists.txt)。

六、安装与分发注意事项

README 的 Install 章节包含一段重要警告与若干安装途径,完整保留如下要点:

警告:官方不推荐手动全局安装,因为它可能覆盖系统默认 zlib 库;任何不兼容或错误配置都可能导致整个系统不可用,需要恢复甚至重装。如坚持手动安装,建议安装到 /opt/ 前缀下。

LD_PRELOAD 替代方案(Linux 发行版):如果以 zlib-compat 模式编译,可用 LD_PRELOAD 让某个动态链接了 zlib 的程序临时改走 zlib-ng,而不承担系统级风险:

LD_PRELOAD=/opt/zlib-ng/libz.so.1.2.13.zlib-ng /usr/bin/program

CMake 安装

cmake --build . --target install

configure 安装

make install

CPack 打包:CMake 构建后可用 cpack 生成安装包,默认生成 tgz,可用 -G <format> 追加 TGZ、ZIP、RPM、DEB 等格式(RPM 用 -G RPM,DEB 用 -G DEB):

cd build
cpack --config CPackConfig.cmake
cpack --config CPackSourceConfig.cmake

vcpkg:也可用 vcpkg 依赖管理器构建安装 zlib-ng(./vcpkg integrate install 后执行 ./vcpkg install zlib-ng),README 提示其 port 由 vcpkg 团队与社区维护者更新。

对 OpenCV 用户而言,这些安装流程通常用不上:开启 -DWITH_ZLIB_NG=ON 后 zlib-ng 作为 OpenCV 构建的子项目被静态或动态地并入 OpenCV 库,安装动作由 OpenCV 顶层 ocv_install_target 统一完成(见 3rdparty/zlib-ng/CMakeLists.txt),不存在覆盖系统 zlib 的风险。

七、小结

  • zlib-ng 是 zlib 1.3.1 兼容的高性能分支(本仓库内置 2.2.1),核心价值在于多架构 SIMD 加速、deflate medium/quick 新策略与运行时 CPU 检测;
  • 独立构建时支持 CMake 与 configure 两套流程,全部构建选项与高级选项见上文两张完整表格;
  • OpenCV 中启用它的唯一入口是 -DWITH_ZLIB_NG=ON(默认 OFF),此后 cmake/OpenCVFindLibsGrfmt.cmake 会跳过系统 zlib 查找,直接构建 3rdparty/zlib-ng
  • OpenCV 对内置副本的默认值做了针对性调整(ZLIB_COMPAT=ON、测试默认关闭、安装交由 OpenCV 管理),与上游 README 中的默认值存在差异,阅读文档时应以仓库内实际 CMake 代码为准;
  • 各指令集加速的具体源文件均落在 3rdparty/zlib-ng/arch/ 下按架构分目录组织,配合 3rdparty/zlib-ng/functable.c3rdparty/zlib-ng/cpu_features.c 完成运行时分派。
登录后查看全文
热门项目推荐
相关项目推荐