本文记录使用命令 OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh 构建 Zstandard (zstd) 1.5.7 的完整过程,包括环境、构建链路、关键日志、常见问题与解决方案、产物验证与重建方法,便于复现与运维。
📖 Zstd 简介
Zstandard (zstd) 是 Facebook 开发的一个快速无损压缩算法,提供了高压缩比和快速解压速度。它在压缩速度和压缩比之间取得了很好的平衡,被广泛用于各种场景,包括文件压缩、网络传输、数据库存储等。
🎯 Zstd 的作用与重要性
Zstd 是现代压缩技术的重要代表,提供了:
- 高性能压缩:在压缩速度和压缩比之间取得最佳平衡
- 多级压缩:支持从 1 到 22 的压缩级别,适应不同场景
- 字典压缩:支持训练字典,提高小文件的压缩比
- 流式压缩:支持流式压缩和解压,适合大文件处理
- 命令行工具 :提供完整的命令行工具集,包括
zstd、zstdcat、zstdmt、zstdgrep等 - 开发库 :提供
libzstd库供应用程序使用
🔧 Zstd 核心特性
1. 压缩性能
- 压缩速度:比 gzip 快 3-5 倍
- 解压速度:比 gzip 快 2-3 倍
- 压缩比:在相同压缩级别下,压缩比通常优于 gzip
- 多线程支持:支持多线程压缩,充分利用多核 CPU
2. 压缩级别
- 级别 1-3:快速压缩,适合实时场景
- 级别 4-9:平衡压缩速度和压缩比(默认级别 3)
- 级别 10-19:高压缩比,适合存储场景
- 级别 20-22:极高压缩比,压缩速度较慢
3. 字典压缩
- 支持训练字典,提高小文件的压缩比
- 字典可以预先训练,适合批量压缩相似文件
- 字典大小可配置,平衡压缩比和内存使用
4. 命令行工具
zstd- 主要压缩工具zstdcat- 解压并输出到标准输出(类似zcat)zstdmt- 多线程压缩工具zstdgrep- 在压缩文件中搜索(类似zgrep)zstdless- 查看压缩文件(类似zless)unzstd- 解压工具(类似gunzip)
🚀 构建入口与环境
- 📝 执行命令 :
OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh - 🔧 入口脚本 :
create-hnp.sh- 检查必需的环境变量
OHOS_ARCH和OHOS_ABI - 导出
LC_CTYPE、TOOL_HOME、OHOS_SDK_HOME - 执行
make -C build-hnp
- 检查必需的环境变量
- 📦 顶层构建 :
build-hnp/MakefilePKGS变量定义需要构建的包列表(包含zstd)- 通过
check-pkgs机制自动检测PKGS变化并触发重新构建 - 自动合并
external-hnp目录下的外部 HNP 包 base.hnp依赖所有包的.stamp和外部 HNP 包- 总目标
all: copy,打包base.hnp并拷贝到entry/hnp/$(OHOS_ABI)
⚙️ Zstd 包的构建配置
- 📁 包目录 :
build-hnp/zstd/Makefile- 继承通用规则:
include ../utils/Makefrag - 源地址:
https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz - 版本:
1.5.7
- 继承通用规则:
- 🔧 补丁应用 :
0001-qsort.diff- 修复 qsort 回调签名问题,简化平台特定代码路径
- ⚙️ CMake 配置参数 :
CMAKE_INSTALL_PREFIX=$(PREFIX)- 安装前缀(/data/app/base.org/base_1.0)CMAKE_SYSTEM_NAME=Linux- 目标系统CMAKE_SYSTEM_PROCESSOR=$(OHOS_ARCH)- 目标架构ZSTD_BUILD_STATIC=ON- 构建静态库ZSTD_BUILD_SHARED=ON- 构建共享库CMAKE_BUILD_TYPE=RelWithDebInfo- 构建类型
- 🔨 构建流程 :
- 下载源码包(支持多镜像回退)
- 解包并应用补丁
- 运行 CMake 配置构建系统
- 使用
make -j $(nproc)并行编译 - 使用
make install安装 - 执行 ELF strip 减小体积
- 复制到
../sysroot
- 🔧 通用工具链与路径 :
build-hnp/utils/MakefragCC/CXX/LD/AR/RANLIB/...均指向 OHOS SDK 的 LLVM 工具链- 下载支持多镜像回退:
wget→curl,主镜像失败时自动尝试备用镜像
📋 关键日志与过程节点
- 📥 下载与解包 :
- 从 GitHub Releases 下载
zstd-1.5.7.tar.gz - 完成解包并进入
temp/zstd-1.5.7目录
- 从 GitHub Releases 下载
- 🔧 补丁应用 :
- 应用
0001-qsort.diff修复 qsort 回调签名问题 - 简化平台特定代码路径,统一使用标准 qsort
- 应用
- ⚙️ 配置阶段 :
- 运行 CMake 配置:
cmake -DCMAKE_INSTALL_PREFIX=... -DCMAKE_SYSTEM_NAME=Linux ... - 配置成功,生成
Makefile和构建配置
- 运行 CMake 配置:
- 🔨 编译与安装 :
- 使用
make -j $(nproc)并行编译 - 成功编译生成
libzstd.so.1.5.7、libzstd.a和zstd命令行工具 - 使用
make install安装到临时前缀 - 执行
llvm-strip剥离共享库和二进制符号 - 复制到
../sysroot
- 使用
- 📦 打包 :
- 完成
base.hnp重打包,拷贝产物到entry/hnp/arm64-v8a/ - Zstd 库和工具已成功打包到
base.hnp中
- 完成
✅ 产物验证
📦 检查打包文件
bash
ls build-hnp/base.hnp # 应存在
ls entry/hnp/arm64-v8a/*.hnp # 应包含 base.hnp 与 base-public.hnp
🔍 检查二进制和库文件
bash
# 检查 zstd 命令行工具
ls -lh build-hnp/sysroot/bin/zstd*
file build-hnp/sysroot/bin/zstd
# 检查库文件
ls -lh build-hnp/sysroot/lib/libzstd.so* build-hnp/sysroot/lib/libzstd.a
file build-hnp/sysroot/lib/libzstd.so.1.5.7
# 检查头文件
ls -lh build-hnp/sysroot/include/zstd*.h
✅ 构建验证结果:
- ✅ zstd 命令行工具已成功安装:
zstd(718K) - 主压缩工具zstdcat- 解压并输出到标准输出(符号链接)zstdmt- 多线程压缩工具(符号链接)zstdgrep(3.8K) - 在压缩文件中搜索zstdless(197 bytes) - 查看压缩文件unzstd(718K) - 解压工具
- ✅ Zstd 库已安装:
libzstd.so.1.5.7(708K) - 主库文件libzstd.so.1- 版本符号链接libzstd.so- 通用符号链接libzstd.a(4.2M) - 静态库
- ✅ 文件类型:ELF 64-bit LSB shared object/executable, ARM aarch64
- ✅ 头文件已安装:
zstd.h(178K)、zstd_errors.h(4.2K) - ✅ pkg-config 文件已安装:
libzstd.pc - ✅ CMake 配置文件已安装:
zstdConfig.cmake、zstdTargets.cmake等 - ✅ 版本信息:1.5.7
💻 终端中执行的示例命令
📦 Zstd 基本使用
1. 基本压缩和解压
bash
# 压缩文件(默认级别 3)
zstd file.txt
# 压缩文件并指定输出文件名
zstd file.txt -o file.txt.zst
# 解压文件
zstd -d file.txt.zst
# 解压文件并指定输出文件名
zstd -d file.txt.zst -o file.txt
# 解压到标准输出
zstdcat file.txt.zst
# 保留原文件压缩
zstd -k file.txt
# 删除原文件压缩
zstd --rm file.txt

2. 压缩级别设置
bash
# 快速压缩(级别 1)
zstd -1 file.txt
# 默认压缩(级别 3)
zstd file.txt
# 高压缩比(级别 19)
zstd -19 file.txt
# 最高压缩比(级别 22,速度较慢)
zstd -22 file.txt
# 最快压缩(级别 1)
zstd --fast file.txt
# 最快压缩(级别 1,等价于 -1)
zstd --fast=1 file.txt
3. 多线程压缩
bash
# 使用多线程压缩(自动检测 CPU 核心数)
zstdmt file.txt
# 指定线程数
zstd -T4 file.txt
# 使用所有可用线程
zstd -T0 file.txt
# 多线程压缩大文件
zstdmt -19 largefile.tar
4. 压缩目录和批量文件
bash
# 压缩目录(递归)
tar cf - directory/ | zstd > directory.tar.zst
# 解压目录
zstdcat directory.tar.zst | tar xf -
# 批量压缩文件
zstd *.txt
# 批量解压文件
zstd -d *.zst
# 压缩多个文件到一个归档
tar cf - file1.txt file2.txt | zstd > archive.tar.zst
5. 压缩测试和基准
bash
# 测试压缩文件完整性
zstd -t file.txt.zst
# 显示压缩文件信息
zstd -l file.txt.zst
# 显示详细压缩信息
zstd -l -v file.txt.zst
# 基准测试(压缩和解压速度)
zstd -b1 file.txt
# 基准测试多个级别
zstd -b1,3,9,19 file.txt
# 显示压缩统计信息
zstd --verbose file.txt
6. 字典压缩
bash
# 训练字典(从样本文件)
zstd --train sample1.txt sample2.txt sample3.txt -o dictionary.zstdict
# 使用字典压缩
zstd -D dictionary.zstdict file.txt
# 使用字典解压
zstd -d -D dictionary.zstdict file.txt.zst
# 训练字典并指定字典大小
zstd --train -s 100000 sample*.txt -o dictionary.zstdict
7. 流式压缩
bash
# 从标准输入压缩到标准输出
cat file.txt | zstd > file.txt.zst
# 从标准输入解压到标准输出
zstdcat file.txt.zst
# 压缩管道数据
tar cf - directory/ | zstd | ssh remote "zstdcat | tar xf -"
# 实时压缩日志文件
tail -f app.log | zstd > app.log.zst
8. 压缩文件操作
bash
# 在压缩文件中搜索(类似 zgrep)
zstdgrep "pattern" file.txt.zst
# 查看压缩文件(类似 zless)
zstdless file.txt.zst
# 解压文件(类似 gunzip)
unzstd file.txt.zst
# 解压到标准输出
unzstd -c file.txt.zst
# 保留原文件解压
unzstd -k file.txt.zst
9. 高级选项
bash
# 设置压缩块大小
zstd -B1M file.txt # 1MB 块
# 长距离匹配(提高压缩比)
zstd --long file.txt
# 长距离匹配并指定窗口大小
zstd --long=27 file.txt
# 覆盖输出文件
zstd -f file.txt
# 显示进度
zstd --progress file.txt
# 压缩时显示详细信息
zstd -v file.txt
# 静默模式
zstd -q file.txt

10. 实际应用示例
bash
# 压缩日志文件(快速压缩)
zstd -1 app.log
# 压缩备份文件(高压缩比)
zstd -19 backup.tar
# 压缩数据库转储(多线程)
zstdmt -19 database.sql
# 压缩并传输
tar cf - data/ | zstd | ssh remote "zstdcat | tar xf -"
# 压缩多个文件到一个归档
tar cf - file1.txt file2.txt file3.txt | zstd -19 > archive.tar.zst
# 解压并提取
zstdcat archive.tar.zst | tar xf -
# 压缩时显示进度
zstd --progress -19 largefile.tar
# 测试压缩文件完整性
zstd -t archive.tar.zst && echo "压缩文件完整"
# 压缩并删除原文件
zstd --rm -19 important_file.txt
# 使用字典压缩相似文件
zstd --train sample*.txt -o dict.zstdict
zstd -D dict.zstdict file1.txt file2.txt file3.txt
🧪 功能验证脚本
bash
#!/bin/bash
# Zstd 工具验证脚本
ZSTD_BIN="build-hnp/sysroot/bin"
ZSTD_LIB="build-hnp/sysroot/lib"
echo "=== Zstd 工具验证 ==="
# 检查命令行工具
if [ -f "$ZSTD_BIN/zstd" ]; then
echo "✓ zstd: 存在"
file "$ZSTD_BIN/zstd"
echo "文件大小: $(ls -lh "$ZSTD_BIN/zstd" | awk '{print $5}')"
echo ""
echo "注意:这是交叉编译的二进制文件,需要在目标设备上运行"
echo "版本信息(如果支持):"
# "$ZSTD_BIN/zstd" --version 2>&1 || echo "无法在 macOS 上运行"
else
echo "✗ zstd: 缺失"
fi
# 检查其他工具
for tool in zstdcat zstdmt zstdgrep zstdless unzstd; do
if [ -f "$ZSTD_BIN/$tool" ] || [ -L "$ZSTD_BIN/$tool" ]; then
echo "✓ $tool: 存在"
else
echo "✗ $tool: 缺失"
fi
done
# 检查库文件
echo ""
echo "=== 库文件验证 ==="
for lib in libzstd.so.1.5.7 libzstd.a; do
if [ -f "$ZSTD_LIB/$lib" ]; then
echo "✓ $lib: 存在"
file "$ZSTD_LIB/$lib"
echo "文件大小: $(ls -lh "$ZSTD_LIB/$lib" | awk '{print $5}')"
else
echo "✗ $lib: 缺失"
fi
done
# 检查符号链接
for link in libzstd.so libzstd.so.1; do
if [ -L "$ZSTD_LIB/$link" ]; then
echo "✓ $link: 符号链接 -> $(readlink "$ZSTD_LIB/$link")"
else
echo "✗ $link: 缺失"
fi
done
# 检查头文件
echo ""
echo "=== 头文件验证 ==="
if [ -d "build-hnp/sysroot/include" ]; then
for header in zstd.h zstd_errors.h; do
if [ -f "build-hnp/sysroot/include/$header" ]; then
echo "✓ $header: 存在"
echo " 文件大小: $(ls -lh "build-hnp/sysroot/include/$header" | awk '{print $5}')"
else
echo "✗ $header: 缺失"
fi
done
else
echo "✗ include 目录: 缺失"
fi
# 检查 pkg-config 文件
echo ""
echo "=== pkg-config 验证 ==="
if [ -f "build-hnp/sysroot/lib/pkgconfig/libzstd.pc" ]; then
echo "✓ libzstd.pc: 存在"
cat build-hnp/sysroot/lib/pkgconfig/libzstd.pc
else
echo "✗ libzstd.pc: 缺失"
fi
🐛 常见问题与处理
❌ 问题 1:qsort 回调签名问题
- 🔍 症状:编译时出现 qsort 回调函数签名不匹配的错误
- 🔎 原因 :zstd 的字典构建代码使用了平台特定的 qsort 变体(如
qsort_r),但标准 qsort 只接受两个参数的比较函数 - ✅ 解决方法 :
- 应用补丁
0001-qsort.diff,简化平台特定代码路径 - 统一使用标准 qsort,通过全局变量传递上下文
- 位置:
build-hnp/zstd/0001-qsort.diff
- 应用补丁
❌ 问题 2:CMake 工具链问题
- 🔍 症状:CMake 配置失败,提示找不到编译器或工具
- 🔎 原因:环境变量未正确设置或工具链路径不正确
- ✅ 解决方法 :
- 确保
OHOS_SDK_HOME环境变量正确设置 - 确保使用
create-hnp.sh脚本执行构建(自动设置环境变量) - CMake 通过
CMAKE_SYSTEM_NAME和CMAKE_SYSTEM_PROCESSOR识别目标平台 - 位置:
build-hnp/zstd/Makefile:10
- 确保
❌ 问题 3:命令行工具未安装
- 🔍 症状 :构建后只有库文件,没有
zstd命令行工具 - 🔎 原因:CMake 默认会构建命令行工具,但可能被某些选项禁用
- ✅ 解决方法 :
- 确保
ZSTD_BUILD_PROGRAMS=ON(默认启用) - 检查
make install是否正确执行 - 位置:
build-hnp/zstd/Makefile(使用define_cmake_package宏)
- 确保
❌ 问题 4:静态库体积过大
- 🔍 症状 :静态库
libzstd.a体积较大(4.2M) - 🔎 原因:静态库包含所有符号,未进行优化
- ✅ 解决方法 :
- 如果不需要静态库,可以设置
ZSTD_BUILD_STATIC=OFF - 或者删除静态库文件以减小 HNP 包体积
- 位置:
build-hnp/zstd/Makefile:10
- 如果不需要静态库,可以设置
❌ 问题 5:多线程压缩问题
- 🔍 症状 :
zstdmt无法正常工作或性能不佳 - 🔎 原因:多线程支持需要正确的线程库链接
- ✅ 解决方法 :
- 确保链接了 pthread 库
- 检查 CMake 是否正确检测到多线程支持
- 使用
zstd -T选项指定线程数
🔄 重建与扩展
-
🔧 重建单包:
bashmake -C build-hnp rebuild-zstd # 触发子包重新编译并刷新 .stamp -
🧹 清理:
bashmake -C build-hnp clean # 清理 sysroot、所有 .stamp 和 PKGS_MARKER -
📦 扩展:Zstd 是许多压缩和归档工具的基础依赖
-
🔄 自动重建机制:
- 修改
PKGS后,check-pkgs会自动检测变化并触发重新构建 - 新增外部 HNP 包到
external-hnp目录后,会自动合并到base.hnp
- 修改
💡 实践建议
- 🔧 压缩级别选择 :根据场景选择合适的压缩级别
- 实时场景:级别 1-3(快速压缩)
- 存储场景:级别 19-22(高压缩比)
- 默认场景:级别 3(平衡)
- 🚀 多线程使用 :对于大文件,使用
zstdmt或多线程选项可以显著提高压缩速度 - 📦 字典压缩:对于批量压缩相似文件,使用字典可以显著提高压缩比
- 🔗 依赖管理:Zstd 是许多包的基础依赖,确保正确构建和安装
- 🌐 压缩栈建设 :建议与
zlib/lz4/xz和libarchive共同构建完整的压缩栈
📝 结论与建议
- ✅ 本次已在 aarch64 环境下完成 Zstd 1.5.7 的交叉编译与打包,zstd 命令行工具和库已安装到
sysroot并纳入 HNP 包。 - 💡 为保证构建稳定 :
- 固定可靠的上游镜像,避免下载阶段随机失败(已实现自动回退机制)
- 应用补丁修复平台特定问题(qsort 回调签名)
- 使用 CMake 构建系统,支持静态库和共享库
- 命令行工具已默认构建和安装
- 利用
check-pkgs机制自动检测包列表变化,无需手动清理 - 结合
zlib/lz4/xz与libarchive完成压缩与归档栈建设,支撑上层归档与传输工具的稳定运行
📚 以上为 Zstd 构建的深度解读与实践记录。