通用的数据压缩工具XZ Utils鸿蒙化编译构建过程与常见问题处理方法
本文详细记录了在aarch64架构下构建XZ Utils 5.8.1的过程。通过OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh命令触发构建流程,涵盖镜像获取、Autotools配置、交叉编译和产物验证等环节。XZ作为高效压缩工具,支持LZMA2算法、多线程压缩和多种校验方式。构建过程包含下载解压、配置编译、安装strip等步骤,最终生
·
本文记录在 aarch64 目标下使用命令 OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh 构建 XZ (xz-utils) 5.8.1 的完整过程,涵盖镜像获取与回退、Autotools 构建链路、产物验证与常见问题处理,便于复现与维护。
📖 XZ 简介
XZ Utils 是一个通用的数据压缩工具,使用 LZMA2 压缩算法。XZ 格式提供了非常高的压缩比,通常比 gzip 和 bzip2 提供更好的压缩率。XZ Utils 5.8.1 是最新版本,提供了更好的性能、更多的功能和更好的稳定性。
🎯 XZ 的作用与重要性
XZ 是高效压缩的核心工具,提供了:
- 高压缩比:使用 LZMA2 算法,提供非常高的压缩比
- 多格式支持:支持 .xz、.lzma、.lz 等多种压缩格式
- 流式压缩:支持流式压缩和解压缩,适合大文件处理
- 完整性校验:支持 CRC32、CRC64、SHA-256 等完整性校验
- 多线程支持:支持多线程压缩,提高压缩速度
- 库支持:提供
liblzma库,可以在应用程序中集成压缩功能 - 广泛使用:被广泛用于软件包分发、系统备份、归档等场景
🔧 XZ 核心特性
1. 压缩算法
- LZMA2:基于 LZMA 算法的改进版本,提供更高的压缩比
- LZMA1:传统的 LZMA 算法,向后兼容
- Delta 编码:支持 Delta 编码,适合压缩相似数据
- BCJ 过滤器:支持 x86、PowerPC、IA-64、ARM、ARM-Thumb、ARM64、SPARC、RISC-V 等架构的 BCJ 过滤器
2. 压缩级别
- 0-9 级别:支持 0-9 的压缩级别(0=最快,9=最高压缩比)
- 预设级别:
-0或--fast:最快压缩-6:默认级别,平衡速度和压缩比-9或--best:最高压缩比
- 极端模式:
-e或--extreme使用更多内存和时间获得更好的压缩比
3. 完整性校验
- CRC32:32 位循环冗余校验(默认)
- CRC64:64 位循环冗余校验
- SHA-256:SHA-256 哈希校验
- 无校验:
--check=none禁用完整性校验
4. 多线程支持
- 多线程压缩:
-T或--threads指定线程数 - 自动线程数:
-T0自动检测 CPU 核心数 - 单线程模式:
-T1单线程模式
5. 命令行工具
- xz:主压缩/解压工具
- xzcat:解压并输出到标准输出(类似
zcat) - unxz:解压工具(
xz -d的别名) - lzma:LZMA 格式压缩/解压工具
- xzdec:仅解压工具(不需要 liblzma)
- xzgrep:在压缩文件中搜索
- xzdiff:比较压缩文件
- xzless/xzmore:分页查看压缩文件内容
- lzmainfo:显示 LZMA 文件信息
6. 库支持
- liblzma:提供 C API,可以在应用程序中集成压缩功能
- 流式 API:支持流式压缩和解压缩
- 多线程 API:支持多线程压缩
- 过滤器 API:支持自定义过滤器
7. 应用场景
- 软件包分发:Linux 发行版软件包压缩(如 .deb、.rpm)
- 系统备份:系统备份和恢复
- 归档压缩:与 tar 结合使用(.tar.xz)
- 日志压缩:压缩日志文件
- 数据传输:压缩传输的数据
🚀 构建入口与顶层组织
- 📝 执行命令:
OHOS_ARCH=aarch64 OHOS_ABI=arm64-v8a sh ./create-hnp.sh - 🔧 入口脚本:
create-hnp.sh导出 SDK 路径并触发顶层构建 - 顶层 Makefile:
build-hnp/Makefile已将xz纳入PKGS,base.hnp依赖所有包完成标记STAMP并完成打包与拷贝到entry/hnp/$(OHOS_ABI)
⚙️ 包配置与工具链
- 包 Makefile:
build-hnp/xz/Makefile- 源地址:
- 主镜像:
https://github.com/tukaani-project/xz/releases/download/v5.8.1/xz-5.8.1.tar.xz - 备用镜像:
https://tukaani.org/xz/xz-5.8.1.tar.xz
- 主镜像:
- 下载策略:在
download/xz-5.8.1.tar.xz规则中实现wget → 备用镜像 → curl 主镜像 → curl 备用镜像的级联重试 - 配置参数:
--prefix=$(PREFIX) --disable-static --enable-shared --host aarch64-unknown-linux-musl - 使用通用 Autotools 宏构建(下载→解包→
configure→make→install→strip→复制至../sysroot)
- 源地址:
- 工具链:
aarch64-unknown-linux-ohos-clang与 LLVMar/ranlib/strip
📋 关键执行与日志
- 下载与解包:
- 从 GitHub Releases 或 tukaani.org 获取归档,解包至
temp/xz-5.8.1并创建build目录
- 从 GitHub Releases 或 tukaani.org 获取归档,解包至
- 配置与编译:
- 使用 Autotools 配置系统,配置交叉编译参数
- 编译
xz、xzdec、lzmainfo等可执行文件和liblzma库
- 安装与复制:
- 安装到临时前缀
build/data/app/base.org/base_1.0后 strip 二进制文件 - 复制到
../sysroot并记录文件列表(file.lst)
- 安装到临时前缀
✅ 产物验证
📦 检查打包文件
ls build-hnp/base.hnp # 应存在
ls entry/hnp/arm64-v8a/*.hnp # 应包含 base.hnp 与 base-public.hnp
🔍 检查 XZ 可执行文件和库
# 检查 XZ 可执行文件
ls -lh build-hnp/sysroot/bin/xz*
ls -lh build-hnp/sysroot/bin/lzma*
file build-hnp/sysroot/bin/xz
# 检查共享库
ls -lh build-hnp/sysroot/lib/liblzma*
file build-hnp/sysroot/lib/liblzma.so.5
# 检查头文件
ls -lh build-hnp/sysroot/include/lzma.h
ls -lh build-hnp/sysroot/include/lzma/
# 检查 pkg-config 文件
ls -lh build-hnp/sysroot/lib/pkgconfig/liblzma.pc
cat build-hnp/sysroot/lib/pkgconfig/liblzma.pc
✅ 构建验证结果:
- ✅ XZ 可执行文件已安装:
xz(79K) - 主压缩/解压工具xzcat- 符号链接到xzunxz- 符号链接到xzlzma- LZMA 格式工具unlzma- 符号链接到xzxzdec(12K) - 仅解压工具lzmainfo- LZMA 文件信息工具xzcmp- 符号链接到xzdiffxzdiff(7.5K) - 比较压缩文件工具xzgrep(11K) - 在压缩文件中搜索工具xzless(2.4K) - 分页查看工具xzmore(2.2K) - 分页查看工具xzegrep- 符号链接到xzgrepxzfgrep- 符号链接到xzgreplzmadec- LZMA 解压工具
- ✅ 文件类型:ELF 64-bit LSB pie executable, ARM aarch64
- ✅ 动态链接:
dynamically linked, interpreter /lib/ld-musl-aarch64.so.1
-符号链接:多个工具通过符号链接指向主xz可执行文件 - ✅ XZ 共享库已安装:
liblzma.so.5.8.1- 主共享库liblzma.so.5- 版本符号链接liblzma.so- 开发符号链接
- ✅ 头文件已安装:
lzma.h- 主头文件lzma/- 头文件目录(包含 base.h、bcj.h、block.h、check.h、container.h、delta.h、filter.h、hardware.h、index.h、index_hash.h、lzma12.h、stream_flags.h、version.h、vli.h)
- ✅ 配置文件已安装:
liblzma.pc- pkg-config 配置文件
- ✅ HNP 包产物:
entry/hnp/arm64-v8a/base.hnp与base-public.hnp - ✅ 已打包到
base.hnp中
💻 终端中执行的示例命令
🔧 XZ 基本使用
1. 检查 XZ 安装
# 检查 XZ 可执行文件
ls -lh /data/app/base.org/base_1.0/bin/xz*
ls -lh /data/app/base.org/base_1.0/bin/lzma*
file /data/app/base.org/base_1.0/bin/xz
# 检查版本(需要在目标设备上运行)
xz --version
# 检查帮助信息
xz --help

2. 基本压缩
# 压缩文件(默认级别 6)
xz file.txt
# 压缩并保留原文件
xz -k file.txt
# 压缩到指定文件
xz -c file.txt > file.txt.xz
# 压缩多个文件
xz file1.txt file2.txt file3.txt
# 压缩目录中的所有文件
xz *.txt
3. 压缩级别
# 最快压缩(级别 0)
xz -0 file.txt
# 默认级别(级别 6)
xz file.txt
# 最高压缩比(级别 9)
xz -9 file.txt
# 极端模式(更慢但压缩比更高)
xz -9e file.txt
# 指定压缩级别
xz -3 file.txt
4. 基本解压
# 解压文件
xz -d file.txt.xz
# 解压并保留原文件
xz -dk file.txt.xz
# 解压到标准输出
xz -dc file.txt.xz
# 使用 unxz 解压
unxz file.txt.xz
# 使用 xzcat 解压并输出
xzcat file.txt.xz
5. 多线程压缩
# 自动检测 CPU 核心数
xz -T0 file.txt
# 指定线程数
xz -T4 file.txt
# 单线程模式
xz -T1 file.txt
# 组合使用:最高压缩比 + 多线程
xz -9 -T0 file.txt
6. 完整性校验
# 使用 CRC32 校验(默认)
xz --check=crc32 file.txt
# 使用 CRC64 校验
xz --check=crc64 file.txt
# 使用 SHA-256 校验
xz --check=sha256 file.txt
# 禁用校验(不推荐)
xz --check=none file.txt
# 测试压缩文件完整性
xz -t file.txt.xz
7. 流式压缩
# 从标准输入压缩到标准输出
cat file.txt | xz > file.txt.xz
# 从标准输入解压到标准输出
cat file.txt.xz | xz -d > file.txt
# 压缩管道数据
tar -cf - directory/ | xz > directory.tar.xz
# 解压管道数据
cat directory.tar.xz | xz -d | tar -xf -
8. LZMA 格式
# 压缩为 LZMA 格式
xz --format=lzma file.txt
# 解压 LZMA 格式
xz -d --format=lzma file.txt.lzma
# 使用 lzma 命令
lzma file.txt
# 使用 unlzma 解压
unlzma file.txt.lzma
# 查看 LZMA 文件信息
lzmainfo file.txt.lzma
9. 文件信息
# 列出压缩文件信息
xz -l file.txt.xz
# 详细列表
xz -lv file.txt.xz
# 显示压缩文件信息
xz -l *.xz
# 查看 LZMA 文件信息
lzmainfo file.txt.lzma
10. 搜索和比较
# 在压缩文件中搜索
xzgrep "pattern" file.txt.xz
# 使用正则表达式搜索
xzgrep -E "pattern1|pattern2" file.txt.xz
# 比较两个压缩文件
xzdiff file1.txt.xz file2.txt.xz
# 分页查看压缩文件
xzless file.txt.xz
xzmore file.txt.xz
11. 与 tar 结合使用
# 创建 tar.xz 归档
tar -cJf archive.tar.xz directory/
# 或者分步执行
tar -cf - directory/ | xz > archive.tar.xz
# 解压 tar.xz
cat archive.tar.xz | xz -d | tar -xf -
# 或者使用 tar 直接解压
tar -xJf archive.tar.xz
# 列出 tar.xz 内容
tar -tJf archive.tar.xz
12. 内存限制
# 设置内存使用限制
xz --memlimit-compress=100M file.txt
# 设置解压内存限制
xz --memlimit-decompress=50M file.txt.xz
# 设置总体内存限制
xz --memlimit=200M file.txt
13. 压缩预设
# 快速压缩预设
xz --fast file.txt
# 最佳压缩预设
xz --best file.txt
# 极端模式
xz --extreme file.txt
14. 批量处理
# 压缩目录中的所有文件
find /path/to/files -type f -exec xz {} \;
# 压缩目录中的所有 .txt 文件
find /path/to/files -name "*.txt" -exec xz {} \;
# 解压目录中的所有 .xz 文件
find /path/to/files -name "*.xz" -exec xz -d {} \;
# 批量压缩并保留原文件
find /path/to/files -type f -exec xz -k {} \;
15. 使用 liblzma 库
# 创建简单的压缩程序
cat > compress_file.c << 'EOF'
#include <stdio.h>
#include <lzma.h>
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <input> <output.xz>\n", argv[0]);
return 1;
}
FILE *infile = fopen(argv[1], "rb");
FILE *outfile = fopen(argv[2], "wb");
if (!infile || !outfile) {
perror("fopen");
return 1;
}
lzma_stream strm = LZMA_STREAM_INIT;
lzma_ret ret = lzma_easy_encoder(&strm, 6, LZMA_CHECK_CRC32);
if (ret != LZMA_OK) {
fprintf(stderr, "Encoder initialization failed\n");
return 1;
}
// 压缩逻辑...
lzma_end(&strm);
fclose(infile);
fclose(outfile);
return 0;
}
EOF
# 编译程序
gcc compress_file.c -o compress_file \
-I/data/app/base.org/base_1.0/include \
-L/data/app/base.org/base_1.0/lib \
-llzma
16. 功能验证脚本
#!/bin/bash
# XZ 工具验证脚本
XZ_BIN="/data/app/base.org/base_1.0/bin"
XZ_LIB="/data/app/base.org/base_1.0/lib"
XZ_INC="/data/app/base.org/base_1.0/include"
echo "=== XZ 工具验证 ==="
# 检查可执行文件
echo ""
echo "=== 可执行文件验证 ==="
if [ -f "$XZ_BIN/xz" ]; then
echo "✓ xz: 存在"
file "$XZ_BIN/xz"
echo " 文件大小: $(ls -lh "$XZ_BIN/xz" | awk '{print $5}')"
echo " 架构信息: $(file "$XZ_BIN/xz" | grep -o "ARM aarch64")"
# 检查版本(需要在目标设备上运行)
echo ""
echo "=== 版本信息(需要在目标设备上运行)==="
echo "$XZ_BIN/xz --version"
echo "$XZ_BIN/xz --help | head -20"
else
echo "✗ xz: 缺失"
fi
# 检查其他工具
for tool in xzcat unxz lzma unlzma xzdec lzmainfo xzdiff xzgrep xzless xzmore; do
if [ -f "$XZ_BIN/$tool" ] || [ -L "$XZ_BIN/$tool" ]; then
echo "✓ $tool: 存在"
else
echo "✗ $tool: 缺失"
fi
done
# 检查共享库
echo ""
echo "=== 共享库验证 ==="
if [ -f "$XZ_LIB/liblzma.so.5.8.1" ]; then
echo "✓ liblzma.so.5.8.1: 存在"
file "$XZ_LIB/liblzma.so.5"
echo " 文件大小: $(ls -lh "$XZ_LIB/liblzma.so.5.8.1" | awk '{print $5}')"
echo " 架构信息: $(file "$XZ_LIB/liblzma.so.5" | grep -o "ARM aarch64")"
# 检查符号链接
if [ -L "$XZ_LIB/liblzma.so.5" ]; then
echo "✓ liblzma.so.5: 符号链接存在"
echo " 指向: $(readlink "$XZ_LIB/liblzma.so.5")"
fi
if [ -L "$XZ_LIB/liblzma.so" ]; then
echo "✓ liblzma.so: 符号链接存在"
echo " 指向: $(readlink "$XZ_LIB/liblzma.so")"
fi
else
echo "✗ liblzma.so.5.8.1: 缺失"
fi
# 检查头文件
echo ""
echo "=== 头文件验证 ==="
if [ -f "$XZ_INC/lzma.h" ]; then
echo "✓ lzma.h: 存在"
echo " 文件大小: $(ls -lh "$XZ_INC/lzma.h" | awk '{print $5}')"
fi
if [ -d "$XZ_INC/lzma" ]; then
echo "✓ lzma/ 目录: 存在"
echo " 头文件数量: $(ls -1 "$XZ_INC/lzma" | wc -l)"
echo " 主要头文件:"
ls -lh "$XZ_INC/lzma" | head -10
fi
# 检查 pkg-config 文件
echo ""
echo "=== pkg-config 验证 ==="
PKG_CONFIG_PATH="$XZ_LIB/pkgconfig:$PKG_CONFIG_PATH"
if pkg-config --exists liblzma; then
echo "✓ liblzma.pc: 存在"
echo " 版本: $(pkg-config --modversion liblzma)"
echo " 编译标志: $(pkg-config --cflags liblzma)"
echo " 链接标志: $(pkg-config --libs liblzma)"
else
echo "✗ liblzma.pc: 缺失或无效"
fi
# 测试基本功能(需要在目标设备上运行)
echo ""
echo "=== 基本功能测试(需要在目标设备上运行)==="
echo "压缩测试文件:"
echo " echo 'Hello, XZ!' > /tmp/test.txt"
echo " $XZ_BIN/xz /tmp/test.txt"
echo "解压测试:"
echo " $XZ_BIN/xz -d /tmp/test.txt.xz"
echo "流式压缩:"
echo " echo 'Hello, XZ!' | $XZ_BIN/xz > /tmp/test.txt.xz"
echo "多线程压缩:"
echo " $XZ_BIN/xz -T0 -9 /tmp/test.txt"
🐛 常见问题与处理
❌ 问题 1:GitHub 下载超时
- 🔍 症状:连接
github.com超时或读取失败 - 🔎 原因:GitHub 访问不稳定或网络问题
- ✅ 解决方法:
- 增加备用源(
tukaani.org)、延长超时时间 - 在
Makefile的下载规则中加入镜像回退 - 清理坏归档后重试
- 位置:
build-hnp/xz/Makefile:11-13
- 增加备用源(
❌ 问题 2:交叉工具链问题
- 🔍 症状:configure 或编译时出现工具链错误
- 🔎 原因:交叉工具链配置不正确或环境变量未设置
- ✅ 解决方法:
- 使用 OHOS SDK 的 LLVM,确保
--host与三元组一致(aarch64-unknown-linux-musl) - 确保通过
create-hnp.sh触发构建以获得完整环境变量 - 如需静态库可调整
CONFIG_ARGS为--enable-static - 位置:
build-hnp/xz/Makefile:9
- 使用 OHOS SDK 的 LLVM,确保
❌ 问题 3:Makefile 规则冲突
- 🔍 症状:Makefile 警告 “overriding recipe for target”
- 🔎 原因:自定义的
download/$(SOURCE_FILE)规则与通用规则冲突 - ✅ 解决方法:
- 将自定义下载规则放在
$(eval $(call define_autotools_package))之后 - 这样可以覆盖通用规则,同时不影响构建流程
- 位置:
build-hnp/xz/Makefile:11-13
- 将自定义下载规则放在
❌ 问题 4:压缩文件损坏
- 🔍 症状:解压时提示文件损坏或校验失败
- 🔎 原因:文件传输错误或存储问题
- ✅ 解决方法:
- 使用
xz -t测试文件完整性 - 重新下载或传输文件
- 使用
--check=sha256进行更严格的校验
- 使用
❌ 问题 5:内存不足
- 🔍 症状:压缩大文件时内存不足
- 🔎 原因:压缩级别过高或文件过大
- ✅ 解决方法:
- 使用
--memlimit-compress限制内存使用 - 降低压缩级别(使用
-6或更低) - 使用多线程压缩(
-T0)提高效率
- 使用
❌ 问题 6:符号链接问题
- 🔍 症状:某些工具(如
xzcat、unxz)无法使用 - 🔎 原因:符号链接未正确创建或指向错误
- ✅ 解决方法:
- 检查符号链接:
ls -l /data/app/base.org/base_1.0/bin/xzcat - 确保主
xz可执行文件存在 - 重新创建符号链接:
ln -sf xz /data/app/base.org/base_1.0/bin/xzcat
- 检查符号链接:
❌ 问题 7:库链接问题
- 🔍 症状:使用 liblzma 的程序无法运行
- 🔎 原因:库路径未正确设置
- ✅ 解决方法:
- 设置
LD_LIBRARY_PATH=/data/app/base.org/base_1.0/lib - 使用 pkg-config 获取正确的链接标志
- 检查库文件是否存在且可读
- 设置
❌ 问题 8:性能问题
- 🔍 症状:压缩速度慢
- 🔎 原因:压缩级别过高或未使用多线程
- ✅ 解决方法:
- 使用多线程压缩:
-T0或-T4 - 降低压缩级别:使用
-6而不是-9 - 使用快速预设:
--fast
- 使用多线程压缩:
🔄 重建与清理
-
🔧 重建单包:
make -C build-hnp rebuild-xz # 触发子包重新编译并刷新 .stamp -
🧹 清理:
make -C build-hnp clean # 清理 sysroot、所有 .stamp 和 PKGS_MARKER -
📦 扩展:XZ 是高效压缩的核心工具,适合用于软件包分发、系统备份、归档压缩等场景
-
🔄 自动重建机制:
- 修改
PKGS后,check-pkgs会自动检测变化并触发重新构建 - 新增外部 HNP 包到
external-hnp目录后,会自动合并到base.hnp
- 修改
💡 实践建议
- 🔧 构建配置:使用 Autotools 构建系统,配置清晰,依赖明确
- 🚀 使用场景:XZ 适合用于软件包分发、系统备份、归档压缩、日志压缩等场景
- 📦 依赖管理:XZ 是独立的压缩工具,无特殊依赖
- 🔗 压缩建议:使用默认级别(6)平衡速度和压缩比,大文件使用多线程(
-T0) - 🌐 格式建议:与 tar 结合使用创建 .tar.xz 归档,提供高压缩比
- 🔒 安全建议:使用完整性校验(默认 CRC32),重要文件使用 SHA-256
📝 结论与建议
- ✅ XZ 5.8.1 在 aarch64 目标下完成交叉构建,工具与库安装到
sysroot并纳入 HNP 打包。 - 💡 为保证构建稳定:
- 使用 Autotools 构建系统,配置清晰
- 无特殊依赖,构建过程简单
- 使用多镜像回退策略确保下载成功
- 确保通过
create-hnp.sh触发构建以获得完整环境变量 - 利用
check-pkgs机制自动检测包列表变化,无需手动清理 - XZ 为高效压缩提供了强大的 LZMA2 压缩能力
- 常见陷阱包括 GitHub 下载超时、交叉工具链问题、Makefile 规则冲突;当前已通过构建配置处理
- 建议与
zlib/zstd/lz4和libarchive一同使用,完善压缩与归档生态 - 构建过程简洁,Autotools 交叉参数清晰,产物安装路径明确
- 产物开箱即用,适合在设备上进行高效压缩和解压缩操作
📚 以上为 XZ 构建的深度解读与实践记录。XZ 是高效压缩的核心工具,被广泛用于软件包分发、系统备份、归档压缩等场景,为高压缩比需求提供了强大的 LZMA2 压缩解决方案。
更多推荐




所有评论(0)