CPack配置基础:核心变量设置

CPack 的配置,说白了就是告诉打包工具三件事:打什么包、叫什么名字、版本是多少。这三个核心变量搞定了,打包流程就稳了一半。我刚开始用 CPack 时,以为随便设几个变量就能跑,结果打出来的包名不伦不类,版本号还写错了——嗯,那次被测试同事追着问了一整天。

CPACK_GENERATOR:选择打包格式

这个变量决定了 CPack 会生成什么类型的安装包。你可以指定一个,也可以给多个——CPack 会依次生成每种格式。

常用生成器一览:
生成器名称 适用平台 输出格式
ZIP 跨平台 .zip 压缩包
TGZ 跨平台 .tar.gz 压缩包
DEB Linux (Debian/Ubuntu) .deb 安装包
RPM Linux (RedHat/Fedora) .rpm 安装包
NSIS Windows .exe 安装程序
DragNDrop macOS .dmg 磁盘映像

我个人习惯在开发阶段只设 ZIP 或 TGZ,这样打包快,调试方便。等到要发布正式版本时,再根据目标平台加上 DEB、RPM 或 NSIS。

# 只生成一个格式
set(CPACK_GENERATOR "ZIP")

# 生成多个格式
set(CPACK_GENERATOR "ZIP;TGZ;DEB")
小技巧: 多个生成器用分号分隔,不要用空格。我见过有人写成 "ZIP TGZ DEB",结果 CPack 只认了第一个。

CPACK_PACKAGE_NAME:给包起个好名字

这个变量就是安装包的名字。它会被用在包文件名、安装路径、甚至软件菜单里。起名字时要注意:不要带空格和特殊字符,否则某些平台会报错。

set(CPACK_PACKAGE_NAME "MyApp")
# 或者用项目名
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")

我曾经接手过一个项目,包名叫 "My Super App v2.0 (beta)"——结果在 Linux 上打 DEB 包时直接崩溃,因为 DEB 包名不允许空格和括号。后来我统一改成小写加连字符:my-super-app,世界清净了。

CPACK_PACKAGE_VERSION:版本号管理

版本号是安装包的核心标识。CPack 提供了三个子变量来分别控制主版本、次版本和补丁版本:

set(CPACK_PACKAGE_VERSION_MAJOR "2")
set(CPACK_PACKAGE_VERSION_MINOR "1")
set(CPACK_PACKAGE_VERSION_PATCH "0")

# 或者直接设完整版本号
set(CPACK_PACKAGE_VERSION "2.1.0")

如果你设了完整版本号,那三个子变量可以省略。但反过来,如果你只设了子变量,CPack 会自动拼接成完整版本号。我个人建议两者都设,这样 CMake 和 CPack 都能拿到版本信息。

注意: 版本号必须是数字加点号,不能有字母。比如 "2.1.0-beta" 在 DEB 包中会报错。如果你需要预发布标识,可以用 CPACK_PACKAGE_VERSION 加后缀,但不同生成器的支持程度不一样。

其他核心变量

除了上面三个,还有几个变量我几乎每次都会用到:

  • CPACK_PACKAGE_VENDOR:发布者名称,比如 "MyCompany Inc."
  • CPACK_PACKAGE_DESCRIPTION_SUMMARY:一句话描述,会显示在包管理器的简介里
  • CPACK_PACKAGE_CONTACT:维护者邮箱,方便用户反馈问题
  • CPACK_PACKAGE_FILE_NAME:自定义输出文件名模板
set(CPACK_PACKAGE_VENDOR "蓝海科技")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "一个高效的跨平台工具")
set(CPACK_PACKAGE_CONTACT "support@deep3321.com")

# 自定义文件名:MyApp-2.1.0-linux-x64.zip
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
经验之谈: 文件名里带上平台和架构信息,能避免用户下载错包。我见过有人把所有平台的包都叫 "MyApp.zip",结果用户解压后才发现是给 Windows 的——那场面,尴尬。

知识体系总览

下面这张图把 CPack 核心配置的脉络梳理清楚了。你配置时,按这个顺序来就行:

CPack 核心配置流程 CMakeLists.txt 配置 CPACK_GENERATOR CPACK_PACKAGE_NAME CPACK_PACKAGE_VERSION ZIP / TGZ / DEB RPM / NSIS / DragNDrop MyApp ${PROJECT_NAME} MAJOR.MINOR.PATCH 例如:2.1.0 生成安装包文件 配置顺序:先定生成器 → 再定包名 → 最后定版本号

完整配置示例

把上面这些变量拼起来,就是一个可用的 CPack 配置块。我通常把它放在 CMakeLists.txt 的末尾,紧挨着 install() 命令之后:

# 项目信息
project(MyApp VERSION 2.1.0)

# ... 构建和安装规则 ...

# CPack 配置
set(CPACK_GENERATOR "ZIP;TGZ")
set(CPACK_PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_PACKAGE_VENDOR "蓝海科技")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "一个高效的跨平台工具")
set(CPACK_PACKAGE_CONTACT "support@deep3321.com")

# 必须包含 CPack 模块
include(CPack)
重要提醒: include(CPack) 这一行必须写在所有 CPack 变量设置之后。如果你写在了前面,那些变量就不会生效。我刚开始时踩过这个坑,查了半天才发现是顺序问题。

配置完成后,运行 cpack 命令就能生成安装包了。如果你设了多个生成器,CPack 会依次打出所有格式的包——省心省力。

说白了,CPack 的核心配置就是这几个变量。你只要把生成器、包名、版本号这三样搞定,剩下的都是锦上添花。我在实际项目中,通常先配一个 ZIP 生成器快速验证,确认安装路径和文件都正确后,再补上 DEB 或 NSIS 的配置。这样迭代快,不容易出错。


公众号:蓝海资料掘金营,微信 deep3321