7-Zip-zstd 中的 LZ4 库构建指南:分层裁剪、编译宏与多线程集成全解析
桌面应用CLI【免费下载链接】7-Zip-zstd7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard项目地址https://gitcode.com/gh_mirrors/7z/7-Zip-zstd点击查看免费下载LZ4 是一种以极致压缩/解压速度著称的块压缩算法在 7-Zip-zstd 仓库中以独立 C 库形式存放于 C/lz4 目录并作为 7-Zip 的内置编解码器codec LZ4被完整集成。本文以官方 READMEC/lz4/README.md为骨架逐一讲解 LZ4 库的分层构建模型、11 个编译宏、Makefile 变量、单文件合并Amalgamation、Windows DLL 交叉编译方法并结合仓库源码揭示 7-Zip 端的多线程LZ4MT封装与编解码器注册细节。读完本文你将掌握如何按需裁剪 LZ4 源文件以控制二进制体积并能把 LZ4 正确嵌入自己的受限环境或构建系统中。1. 概览LZ4 库在仓库中的位置与版本在本仓库中LZ4 相关的上游库文件集中在C/lz4/目录当前快照包含以下文件lz4.c/lz4.hLZ4 核心块压缩/解压算法lz4hc.c/lz4hc.h高压缩率变体High Compressionlz4frame.c/lz4frame.h/lz4frame_static.hLZ4 Frame 格式互操作层LICENSEBSD 2-Clause 许可证README.md本文依据的官方说明文档从 C/lz4/lz4.h 可以看到当前库版本为1.10.0LZ4_VERSION_MAJOR 1、LZ4_VERSION_MINOR 10、LZ4_VERSION_RELEASE 0。需要特别说明的是README 中提到的lz4file.c/lz4file.h文件级压缩辅助层、Makefile与liblz4.pc.inpkg-config 模板在本仓库快照中并未包含——前者仍是上游实验性 API后两者属于上游发行包内容。此外README 要求 Frame 层依赖的xxhash.c/xxhash.h在本仓库中位于 C/hashes/xxhash.c 与 C/hashes/xxhash.h集成时路径与上游/lib目录布局略有差异下文会详细说明。1.1 仓库内的两级使用场景库级使用任何 C 程序都可以直接 includelz4.h等头文件并编译相应.c文件7-Zip 集成级使用CPP/7zip/Compress/下的Lz4Encoder.cpp、Lz4Decoder.cpp、Lz4Register.cpp通过 C/zstdmt/lz4-mt.h 提供的 LZ4MT多线程 LZ4接口把 LZ4 包装为 7-Zip 编解码器。这一集成方式将在第 9 节展开。2. 核心骨架LZ4 库的四级构建模型LZ4 库的设计哲学是按“层级level”粒度提供能力项目需要多少功能就包含多少源文件从而最小化二进制体积与依赖。这是整份 README 的灵魂所在四种能力等级如下层级能力必须包含的源文件说明Level 1最小构建块格式lz4.clz4.h提供快速压缩与解压算法生成/解码 LZ4 块格式数据Level 2高压缩变体追加lz4hc.clz4hc.h以压缩速度为代价换取更高压缩率仍使用 LZ4 块格式依赖 Level 1 的lz4.c/lz4.hLevel 3Frame 互操作追加lz4frame.clz4frame.h以及xxhash.cxxhash.h产出与lz4命令行工具兼容的官方互操作 Frame 格式依赖 lz4、lz4hc 与 xxhashLevel 4文件压缩操作追加lz4file.clz4file.h实验性透明地按 LZ4 Frame 格式读写文件引入stdio.h依赖需包含全部*.c/*.h2.1 Level 1最小 LZ4 构建仅需两个文件lz4.c与lz4.h即可获得完整的块级压缩/解压能力。核心入口包括LZ4_compress_default()默认参数快速压缩见 C/lz4/lz4.hLZ4_compress_fast()在LZ4_compress_default()基础上允许指定加速度因子acceleration值为 1 时等价于默认压缩见 C/lz4/lz4.h。该层使用LZ4 块格式LZ4 block format即最底层的“序列 字面量 偏移量”编码适合自管分块的系统。2.2 Level 2高压缩变体 lz4hc当压缩率比压缩速度更关键时追加lz4hc.c与lz4hc.h即可启用 HC 变体。它的输出仍是 LZ4 块格式但匹配搜索更彻底典型入口为LZ4_compress_HC()。该变体依赖常规lz4.c/lz4.h因此不能脱离 Level 1 单独构建。2.3 Level 3Frame 支持实现互操作要让压缩数据能被标准lz4命令行工具识别必须使用官方互操作 Frame 格式。该格式由lz4frame库自动生成与解码其公开 API 定义在lz4frame.h中一键接口为LZ4F_compressFrame()见 C/lz4/lz4frame.h。注意lz4frame的正常工作依赖/lib中其他全部模块包括 lz4、lz4hc 以及xxhashFrame 头部的内容校验需要 XXH32/XXH64。因此在仓库集成时必须同时包含lz4.c lz4.h lz4hc.c lz4hc.h lz4frame.c lz4frame.h lz4frame_static.h xxhash.c xxhash.h 本仓库位于 C/hashes/ 下LZ4F_compressFrame()还要求调用者预留足够的目标缓冲dstCapacity必须不小于LZ4F_compressFrameBound(srcSize, preferencesPtr)的返回值后者在 C/lz4/lz4frame.h 中给出定义。2.4 Level 4文件压缩操作实验性作为文件操作的辅助层上游在 README 撰写时新增了lz4file.c/lz4file.h支持以透明 LZ4 压缩/解压的方式打开、读取、写入和关闭文件。使用lz4file会引入对stdio.h的依赖且它基于lz4frame产出符合 LZ4 Frame 规范的数据——因此必须包含/lib目录下所有*.c与*.h文件。如前所述本仓库快照未携带这两个实验文件如需使用请从上游 lz4 发行版获取。3. 高级/实验性 API静态链接专属区README 明确指出不保证在将来版本中保持稳定的定义都隐藏在宏之后最具代表性的是LZ4_STATIC_LINKING_ONLY其启用逻辑位于 C/lz4/lz4.h 的#ifdef块中。三点关键约束这类定义只应在静态链接场景下使用否则未来版本的 API/ABI 变动可能导致应用崩溃相关符号默认不导出到动态库中若确实需要从动态库导出可强制发布LZ4_PUBLISH_STATIC_FUNCTIONS发布 LZ4 静态函数LZ4F_PUBLISH_STATIC_FUNCTIONS发布 LZ4F 静态函数。4. 编译宏全解编译期行为调优README 列出了 11 个可在编译期调整源码行为的宏下面逐一结合仓库源码佐证。4.1LZ4_FAST_DEC_LOOP快速解压循环触发速度优化的解压循环在现代 CPU 上性能更强。自动启用逻辑可在 C/lz4/lz4.c 中看到在x86、x64含__x86_64__等宏与aarch64架构上自动置 1其他架构默认置 0。也可手动强制开/关# gcc 示例 -DLZ4_FAST_DEC_LOOP1 # make 示例 CPPFLAGS-DLZ4_FAST_DEC_LOOP1 make lz44.2LZ4_DISTANCE_MAX控制最大匹配距离限制压缩器允许的最大偏移量默认值65535LZ4 格式支持的上限定义见 C/lz4/lz4.h。要点减小该值会降低找到匹配的机会压缩率变差减小该值可兼容内存预算受限的特定解码器它只影响压缩器的输出与解压器行为无关同时影响LZ4_COMPRESS_INPLACE_MARGIN等原地压缩相关常量的计算见 C/lz4/lz4.h。4.3LZ4_DISABLE_DEPRECATE_WARNINGS屏蔽废弃 API 警告调用废弃函数时编译器会产生警告例如LZ4_compress被标记为 deprecated见 C/lz4/lz4.h借此提醒用户更新代码。若警告造成困扰常规手段有gcc-Wno-deprecated-declarationsVisual Studio_CRT_SECURE_NO_WARNINGS此外也可在包含 LZ4 头文件之前定义本宏C/lz4/lz4.c 中默认也会自行定义以屏蔽内部废弃调用。4.4LZ4_FORCE_SW_BITCOUNT强制软件位计数默认情况下压缩算法用 CPU 的 bitcount 指令多为单指令实现求长度。若目标 CPU 不支持、编译器内建函数失效或性能不佳则设置本宏切换到优化过的软件路径触发逻辑见 C/lz4/lz4.c。绝大多数平台无需设置仅少数非常规平台可考虑。4.5LZ4_ALIGN_TEST对齐测试开关该测试确保传入的压缩状态内存区域满足对齐要求默认开启C/lz4/lz4.c。若测试在某些环境下不稳定可置 0 关闭。4.6LZ4_USER_MEMORY_FUNCTIONS自定义内存分配把对stdlib.h的malloc()、calloc()、free()调用替换为用户自定义函数用户函数必须命名为LZ4_malloc()、LZ4_calloc()、LZ4_free()并在链接期可见。4.7LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION去除动态内存分配移除动态内存分配支持细节见lz4.c中的宏说明相关代码块位于 C/lz4/lz4.h 与 C/lz4/lz4.h 的条件编译区域。适合对分配器零依赖的嵌入式场景。4.8LZ4_STATIC_LINKING_ONLY_ENDIANNESS_INDEPENDENT_OUTPUT端序无关输出实验性目标是在不同端序平台小端/大端上产生相同的压缩输出。小端平台输出保持不变大端平台将开始产出与小端一致的结果该特性不预期影响前后兼容性。4.9LZ4_FREESTANDING去除标准库依赖置 1 时LZ4/HC 去除对 C 标准库的依赖包括分配函数以及memmove()、memcpy()、memset()。设计用于受限环境嵌入式、bootloader 等。在 C/lz4/lz4.h 中可以看到它的联动效应自动把LZ4_HEAPMODE置 0、启用LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION并要求调用方预先提供LZ4_memcpy、LZ4_memset、LZ4_memmove宏否则编译报错。4.10LZ4_HEAPMODE核心压缩哈希表的内存位置控制无状态压缩函数如LZ4_compress_default()为哈希表分配内存的位置0默认内存栈最快1内存堆需要malloc()。4.11LZ4HC_HEAPMODE与LZ4F_HEAPMODEHC/Frame 工作区分配LZ4HC_HEAPMODE控制无状态 HC 压缩函数如LZ4_compress_HC()工作区的分配方式——栈0或堆1默认。HC 工作区较大栈上不便官方推荐堆模式LZ4F_HEAPMODE控制LZ4F_compressFrame()压缩状态的分配——默认 0栈或 1堆。相关设计意图在 C/lz4/lz4frame.h 中有说明默认栈分配以减少分配器负担若栈空间紧张可改为 1代价是每次调用会触发若干次内部 alloc/free。5. Makefile 变量产出库形态构建时可通过两个变量选择生成库的类型本仓库快照未附带 lz4 上游 Makefile以下为上游发行版的构建约定变量作用默认值BUILD_SHARED生成liblz4动态库启用BUILD_STATIC生成liblz4静态库启用需要纯静态或纯动态产物时可显式设置BUILD_SHAREDno或BUILD_STATICno第 7 节的交叉编译示例即使用了BUILD_STATICno。6. 单文件合并AmalgamationLZ4 源码支持合并为单个文件。将所有源码按固定顺序拼入lz4_all.ccat lz4.c lz4hc.c lz4frame.c lz4_all.ccat的文件顺序很重要不能颠倒。随后直接编译lz4_all.c即可。注意/lib下所有*.h头文件在编译lz4_all.c时仍然是必需的。7. Windows使用 MinGWMSYS 生成 DLL在 MinGWMSYS 环境下执行make liblz4即可创建 DLL产出dll\liblz4.dll动态库dll\liblz4.lib导入库仅 Visual C 需要在 Linux 上交叉编译时可通过DLLTOOL变量覆盖dlltool命令。以 mingw-w64 64 位为例make BUILD_STATICno CCx86_64-w64-mingw32-gcc DLLTOOLx86_64-w64-mingw32-dlltool OSWindows_NT用 gcc/MinGW 编译项目时需要lz4.h、lz4hc.h、lz4frame.h三个头文件加dll\liblz4.dll动态库并把动态库加入链接选项。例如单一test-dll.c文件的链接命令$(CC) $(CFLAGS) -Iinclude/ test-dll.c -o test-dll dll\liblz4.dll生成的程序运行时需要dll\liblz4.dll存在。8. 目录中的其他文件README 明确指出上游发行目录中其余文件并非源码LICENSEBSD 2-Clause 许可证文本本仓库对应 C/lz4/LICENSEMakefilemake脚本负责编译并安装 lz4 库静态与动态liblz4.pc.in供pkg-config使用的模板make install时使用README.md即本文依据的文档本身。9. 源码纵深LZ4 在 7-Zip-zstd 中的多线程集成除库文件外本仓库还提供了 LZ4 在 7-Zip 中的完整落地实现这是 README 之外最值得研读的部分。9.1 编解码器注册CPP/7zip/Compress/Lz4Register.cpp 通过REGISTER_CODEC_E宏注册了名为LZ4的编解码器编解码器 ID 为0x4F71104压缩端为CEncoder、解压端为CDecoder。这意味着 7-Zip 命令行7z a -tLZ4等方式可以直接使用 LZ4 算法。9.2 多线程压缩层LZ4MT7-Zip 侧的压缩并非直接调用LZ4_compress_default()而是经由 C/zstdmt/lz4-mt.h 的多线程封装。从该头文件可以看到等级范围LZ4MT_LEVEL_MIN 1LZ4MT_LEVEL_MAX 12见 C/zstdmt/lz4-mt.h线程上限LZ4MT_THREAD_MAX 128C/zstdmt/lz4-mt.h核心接口LZ4MT_createCCtx(threads, level, inputsize)创建压缩上下文LZ4MT_compressCCtx(ctx, rdwr)执行流式压缩C/zstdmt/lz4-mt.h。9.3 压缩器参数处理与调用链在 CPP/7zip/Compress/Lz4Encoder.cpp 的SetCoderProperties()中7-Zip 只透传两个属性kLevel压缩等级被夹紧到LZ4MT_LEVEL_MIN..LZ4MT_LEVEL_MAX即 112与kNumThreads线程数经SetNumberOfThreads()夹紧到 1128见 Lz4Encoder.cpp。实际压缩流程分三步Lz4Encoder.cpp通过Lz4Read/Lz4Write回调把 7-Zip 的ISequentialInStream/ISequentialOutStream适配为 LZ4MT 的读写函数按需创建压缩上下文LZ4MT_createCCtx(_numThreads, _props._level, _inputSize)调用LZ4MT_compressCCtx(_ctx, rdwr)完成压缩错误码统一映射为 HRESULT取消映射为E_ABORT其余为E_FAIL。9.4 解压端适配CPP/7zip/Compress/Lz4Decoder.cpp 中的Lz4Read负责把 7-Zip 输入流读入 LZ4MT 缓冲区并将E_ABORT/E_OUTOFMEMORY等 HRESULT 错误转换为 LZ4MT 约定的错误码-2/-3其余错误返回 -1从而保证解压路径与压缩路径的对称性。10. 许可说明/lib本仓库为 C/lz4目录内的全部源码均采用BSD 2-Clause许可许可文本见 C/lz4/LICENSE每个源文件顶部亦有提醒。这意味着 LZ4 库可以相对宽松地被静态或动态集成到各类项目中配合第 2 节的分层裁剪策略非常适合从嵌入式固件到大型压缩工具链的各种资源受限场景。赞分享桌面应用CLI【免费下载链接】7-Zip-zstd7-Zip with support for Brotli, Fast-LZMA2, Lizard, LZ4, LZ5 and Zstandard项目地址https://gitcode.com/gh_mirrors/7z/7-Zip-zstd点击查看免费下载相关推荐Zstandardzstd库 lib 目录深度指南构建、模块化裁剪、多线程与在 MongoDB 中的集成Zstandardzstd库 lib 目录深度指南构建、模块化裁剪、多线程与在 MongoDB 中的集成 本篇技术指南以 src/third_party/数据库文档数据库后端7-Zip-zstd 中的 LZ5 压缩库lz5、lz5hc 与 lz5frame 分层集成与使用指南7 Zip zstd 中的 LZ5 压缩库lz5、lz5hc 与 lz5frame 分层集成与使用指南 LZ5 是 LZ4 家族中面向极高压缩/解压速度场桌面应用CLIZstandard 库构建完全指南lib 目录结构、模块化裁剪与多线程编译详解Zstandard 库构建完全指南lib 目录结构、模块化裁剪与多线程编译详解 lib/README.md 是 Zstandardzstd库的官方构建与集数据工程上一篇three.js Backend 抽象基类详解统一 WebGPU 与 WebGL2 双后端的渲染接口设计下一篇Avoriaz测试最佳实践提升Vue组件测试效率的7个技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考