本文记录在 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 纳入 PKGSbase.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 宏构建(下载→解包→configuremakeinstall→strip→复制至 ../sysroot
  • 工具链:aarch64-unknown-linux-ohos-clang 与 LLVM ar/ranlib/strip

📋 关键执行与日志

  • 下载与解包:
    • 从 GitHub Releases 或 tukaani.org 获取归档,解包至 temp/xz-5.8.1 并创建 build 目录
  • 配置与编译:
    • 使用 Autotools 配置系统,配置交叉编译参数
    • 编译 xzxzdeclzmainfo 等可执行文件和 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 - 符号链接到 xz
    • unxz - 符号链接到 xz
    • lzma - LZMA 格式工具
    • unlzma - 符号链接到 xz
    • xzdec (12K) - 仅解压工具
    • lzmainfo - LZMA 文件信息工具
    • xzcmp - 符号链接到 xzdiff
    • xzdiff (7.5K) - 比较压缩文件工具
    • xzgrep (11K) - 在压缩文件中搜索工具
    • xzless (2.4K) - 分页查看工具
    • xzmore (2.2K) - 分页查看工具
    • xzegrep - 符号链接到 xzgrep
    • xzfgrep - 符号链接到 xzgrep
    • lzmadec - 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.hnpbase-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

image-20251128143129599

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

❌ 问题 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:符号链接问题

  • 🔍 症状:某些工具(如 xzcatunxz)无法使用
  • 🔎 原因:符号链接未正确创建或指向错误
  • ✅ 解决方法
    • 检查符号链接: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/lz4libarchive 一同使用,完善压缩与归档生态
    • 构建过程简洁,Autotools 交叉参数清晰,产物安装路径明确
    • 产物开箱即用,适合在设备上进行高效压缩和解压缩操作

📚 以上为 XZ 构建的深度解读与实践记录。XZ 是高效压缩的核心工具,被广泛用于软件包分发、系统备份、归档压缩等场景,为高压缩比需求提供了强大的 LZMA2 压缩解决方案。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐