2、CPack安装与配置:从零开始搭建打包环境

说实话,很多人一上来就急着写CPack配置文件,结果环境都没配好,折腾半天发现是版本不兼容。我刚开始用CPack时就吃过这个亏——明明照着文档写的,就是报错,最后发现是CMake版本太老。所以这一节,咱们先把地基打牢。

2.1 CPack的安装方式

CPack是CMake自带的工具,不需要单独安装。你装好CMake,CPack就在那了。我个人习惯用包管理器来装,省心。

Linux 用户:

# Ubuntu/Debian
sudo apt-get install cmake

# CentOS/RHEL
sudo yum install cmake

# 验证安装
cmake --version
cpack --version

macOS 用户:

# 用Homebrew
brew install cmake

# 或者用MacPorts
sudo port install cmake

Windows 用户:

去官网下载安装包,或者用choco:

choco install cmake --installargs 'ADD_CMAKE_TO_PATH=User'
我的小建议:Windows上记得勾选「Add CMake to the system PATH」,不然每次都要手动找cpack.exe,烦得很。

2.2 CMake版本与CPack兼容性

这里有个坑,我得重点说说。CPack的功能和CMake版本是绑定的。你想想看,CMake 3.10和CMake 3.20的CPack,能力差了一大截。

CMake版本 CPack特性 我的评价
< 3.0 基础打包,仅支持TGZ/DEB/RPM 太老了,别用了
3.0 - 3.10 支持NSIS、组件打包 勉强能用
3.11 - 3.18 支持IFW、依赖处理增强 推荐使用
3.19+ 支持CPACK_INSTALL_SCRIPT、多架构 强烈推荐

我曾经在一个项目里用了CMake 3.5,结果想用CPACK_DEBIAN_PACKAGE_SHLIBDEPS这个功能,发现根本不支持。最后只能手动写依赖列表,折腾了两天。所以我的建议是:至少用CMake 3.16以上版本。

注意:如果你用Ubuntu 18.04自带的cmake(3.10),很多新特性用不了。建议从Kitware的APT源装最新版。

2.3 CPack配置文件基础结构

CPack的配置文件叫CPackConfig.cmake,或者你可以在CMakeLists.txt里直接写。我个人更喜欢后者,因为所有配置都在一个地方,维护起来方便。

来看一个最基础的配置:

# CMakeLists.txt 底部添加
include(CPack)

set(CPACK_PACKAGE_NAME "MyApp")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_VENDOR "MyCompany")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "一个示例应用")

# 打包生成器
set(CPACK_GENERATOR "TGZ;DEB")

# 输出目录
set(CPACK_OUTPUT_FILE_PREFIX "${CMAKE_BINARY_DIR}/packages")

嗯,这里要注意:include(CPack)必须放在所有设置之后。为什么?因为CPack模块在include的时候会读取你之前设置的那些变量。顺序错了,变量就白设了。

配置文件的完整结构大概是这样的:

  1. 基本信息:包名、版本、厂商
  2. 生成器选择:你要打什么格式的包
  3. 安装规则:哪些文件要打包进去
  4. 平台特定配置:比如DEB的依赖、NSIS的安装路径
  5. 组件配置:如果你想把包拆成多个组件

核心原则:CPack的配置变量都是以CPACK_开头的。你记不住没关系,用cmake --help-variable-list | grep CPACK就能看到所有支持的变量。

2.4 常用生成器概览

生成器就是CPack用来打不同格式包的工具。说白了,你选TGZ,它就给你打个tar.gz;你选DEB,它就给你打个deb包。

我整理了一张表,把常用的生成器列出来了:

生成器 适用平台 输出格式 我的使用频率
TGZ 跨平台 .tar.gz ⭐⭐⭐⭐⭐
DEB Debian/Ubuntu .deb ⭐⭐⭐⭐
RPM RedHat/CentOS .rpm ⭐⭐⭐
NSIS Windows .exe安装包 ⭐⭐⭐⭐
IFW 跨平台 Qt安装框架 ⭐⭐
DragNDrop macOS .dmg ⭐⭐⭐
ZIP 跨平台 .zip ⭐⭐⭐

你可能会问:这么多生成器,我该选哪个?我的经验是:

  • 开发测试阶段:用TGZ或ZIP,快,不用管依赖
  • 发布Linux版本:DEB和RPM都打上,用户各取所需
  • 发布Windows版本:NSIS是主流,IFW适合Qt应用
  • 发布macOS版本:DragNDrop生成.dmg,用户体验好

举个例子,我最近一个项目是跨平台桌面应用,我的CPack配置是这样的:

if(WIN32)
    set(CPACK_GENERATOR "NSIS")
elseif(APPLE)
    set(CPACK_GENERATOR "DragNDrop")
else()
    set(CPACK_GENERATOR "TGZ;DEB;RPM")
endif()

这样一套配置,三个平台都能打出合适的包。省事吧?

避坑指南:我曾经在Windows上只用ZIP生成器,结果用户反馈说不会解压、不会配置环境变量。后来换成NSIS,一键安装,问题全解决了。所以,给最终用户的包,尽量用安装包格式。

好了,这一节的内容就到这。配置环境这件事,看起来简单,但版本不对真的能卡你半天。下一节咱们开始写真正的CPack配置,到时候你会感谢现在把环境配好的自己。