第三章:TGZ格式详解——生成tar.gz压缩包,Linux/Unix下的标配
说到TGZ格式,其实就是tar.gz的缩写。说白了,就是把一堆文件先用tar打包成一个整体,再用gzip压缩一下。我在Linux服务器上折腾了这么多年,这玩意儿几乎天天见。
为什么会这么流行?因为Linux/Unix生态里,tar和gzip是系统自带的,不需要额外装任何东西。你想想看,要是你写了个CMake项目,想让别人在Linux上一键编译,用TGZ格式分发源码,对方直接tar -xzf就解开了,多省事。
3.1 TGZ的核心机制
TGZ其实是个组合拳。tar负责把目录结构、文件权限、时间戳这些元信息保留下来,gzip负责把体积压小。我见过不少新手直接拿zip去Linux上发,结果解出来权限全丢了,还得手动chmod,麻烦得很。
CPack生成TGZ时,内部流程是这样的:
- 先构建项目,生成二进制或源码文件
- 用tar把文件打包成一个临时归档
- 再用gzip压缩,生成最终的
.tar.gz文件
嗯,这里要注意一点:CPack生成的TGZ默认会保留文件的可执行权限。我在项目中遇到过,有些脚本打包后到客户机器上直接就能跑,就是因为权限没丢。
3.2 配置参数详解
CPack为TGZ格式提供了一些专用参数。我挑几个最常用的说说:
| 参数名 | 作用 | 我的建议 |
|---|---|---|
CPACK_TGZ_COMPRESSION |
压缩级别,可选1-9 | 默认6,兼顾速度和体积 |
CPACK_TGZ_EXTENSION |
自定义后缀名 | 保持默认.tar.gz就行 |
CPACK_INCLUDE_TOPLEVEL_DIRECTORY |
是否包含顶层目录 | 建议设为ON,方便用户管理 |
CPACK_STRIP_FILES |
是否剥离调试符号 | 发布版建议ON,能省不少空间 |
我个人习惯在CMakeLists.txt里这样配置:
set(CPACK_GENERATOR "TGZ")
set(CPACK_TGZ_COMPRESSION 9)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY ON)
set(CPACK_STRIP_FILES ON)
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${PROJECT_VERSION}-linux-x64")
压缩级别设成9,虽然打包慢一点,但用户下载快啊。我曾经给一个嵌入式设备分发固件,TGZ从6改成9后,体积小了30%,客户那边下载时间直接减半。
3.3 实战案例:发布一个C++命令行工具
假设你写了个叫logparser的小工具,用来分析日志文件。现在要打包成TGZ给Linux用户用。来看看完整的CMake配置:
cmake_minimum_required(VERSION 3.15)
project(logparser VERSION 1.2.0 LANGUAGES CXX)
add_executable(logparser main.cpp parser.cpp)
install(TARGETS logparser DESTINATION bin)
install(FILES README.md LICENSE DESTINATION share/doc/logparser)
# CPack配置
set(CPACK_GENERATOR "TGZ")
set(CPACK_PACKAGE_NAME "logparser")
set(CPACK_PACKAGE_VERSION "1.2.0")
set(CPACK_PACKAGE_VENDOR "MyCompany")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A fast log file parser")
# TGZ专用配置
set(CPACK_TGZ_COMPRESSION 9)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY ON)
set(CPACK_STRIP_FILES ON)
# 安装后执行脚本,确保权限正确
set(CPACK_INSTALL_SCRIPT "${CMAKE_SOURCE_DIR}/cmake/post_install.cmake")
include(CPack)
然后执行打包命令:
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cpack -G TGZ
你会得到一个logparser-1.2.0-linux-x64.tar.gz文件。用户拿到后,直接解压就能用:
tar -xzf logparser-1.2.0-linux-x64.tar.gz
cd logparser-1.2.0-linux-x64
./bin/logparser --help
post_install.cmake里把可执行文件路径加到PATH。我一般会在安装目录下放个env.sh脚本,用户source一下就能用。
3.4 避坑指南
我曾经在打包一个大型项目时,发现TGZ文件解压后,某些配置文件权限变成了644,导致程序启动报错。排查了半天,原来是install命令没指定权限。
解决方案很简单:
install(FILES config.ini DESTINATION etc PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
另一个坑是符号链接。如果项目里用了软链接,tar默认会保留,但gzip压缩后解压时可能出问题。我建议在打包前用readlink -f把符号链接解析成实际文件。
3.5 TGZ vs 其他格式
简单对比一下TGZ和另外两种常见格式:
| 特性 | TGZ | DEB | RPM |
|---|---|---|---|
| 跨发行版 | ✅ 通用 | ❌ Debian系 | ❌ RedHat系 |
| 依赖管理 | ❌ 无 | ✅ 自动处理 | ✅ 自动处理 |
| 安装复杂度 | 低(解压即用) | 中(需root) | 中(需root) |
| 文件权限保留 | ✅ 完整 | ✅ 完整 | ✅ 完整 |
说白了,如果你的软件是给开发者用的,或者需要跨多个Linux发行版,TGZ是最稳妥的选择。我自己的开源项目一直用TGZ分发,用户反馈从来没出过兼容性问题。
3.6 总结
TGZ格式在Linux/Unix环境下就是标配。配置简单,兼容性好,几乎零学习成本。你只要记住三点:
- 压缩级别设9,用户下载快
- 记得保留文件权限,特别是可执行位
- 包太大时考虑换格式或分卷
下一章我们会聊NSIS格式,那是Windows下的打包利器。到时候对比着看,你会发现不同平台的打包思路差异还挺大的。