1、CPack初识:什么是CPack、CPack在CMake生态中的角色、为什么需要打包策略
1.1 什么是CPack?
CPack,说白了就是CMake官方自带的打包工具。
你写完了代码,用CMake编译好了,生成了可执行文件、动态库、头文件……然后呢?怎么发给用户?
我刚开始做C++项目时,每次发布版本都是手动压缩、写安装说明、复制文件。后来项目大了,依赖多了,手动打包简直要命。有一次我漏掉了一个动态库,用户反馈说程序启动就崩溃……嗯,从那以后我就认真研究CPack了。
CPack能帮你自动生成各种格式的安装包:
- 源码包:tar.gz、zip
- 二进制包:deb、rpm、dmg、NSIS安装包
- 跨平台包:甚至可以直接生成一个可执行的安装向导
你只需要在CMakeLists.txt里配置好打包规则,然后敲一行命令:
cpack -G DEB # 生成deb包
cpack -G RPM # 生成rpm包
cpack -G NSIS # 生成Windows安装包
cpack -G TGZ # 生成tar.gz压缩包
是不是很简单?但真正用好它,需要一些策略。
1.2 CPack在CMake生态中的角色
CMake生态里,CPack扮演的是「最后一公里」的角色。
你想想看,CMake负责三件事:
- 配置:检测系统环境、查找依赖库
- 构建:编译源代码、生成目标文件
- 打包:把构建产物整理成可分发的格式
CPack就是第三步的主角。
我习惯把CMake比作一个生产线:
- CMake是生产线上的调度员
- Make/Ninja是工人
- CPack是包装车间
没有CPack,你只能手动把产品装进纸箱。有了CPack,它能自动帮你贴标签、放说明书、甚至封箱打包。
核心关系图:
1.3 为什么需要打包策略?
你可能会问:「不就是打个包吗?有什么策略不策略的?」
我遇到过这样一个项目:一个跨平台的SDK,需要同时提供Linux的deb包、rpm包、Windows的安装包、macOS的dmg包。每个平台的依赖不同、安装路径不同、权限要求不同。
如果没有打包策略,你会遇到:
- Linux上deb包安装到了/usr/local,rpm包却装到了/opt
- Windows上忘记注册COM组件
- macOS上签名证书没配置
- 版本号不统一,用户分不清哪个是最新版
说白了,打包策略就是一套「打包的规矩」。它帮你回答几个问题:
- 打什么格式的包?——根据目标平台选择
- 包里面放什么?——哪些文件是必须的,哪些是多余的
- 安装到哪里?——不同平台有不同的约定
- 版本怎么管理?——版本号、更新日志、依赖关系
我的建议:
别等到项目快发布了才想打包的事。在项目初期就把CPack配置写好,哪怕只是生成一个简单的tar.gz。这样后期扩展起来会轻松很多。
1.4 一个简单的例子
来看一个最基础的CPack配置。假设你有一个简单的C++项目:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyApp VERSION 1.0.0)
add_executable(myapp main.cpp)
# 安装规则
install(TARGETS myapp DESTINATION bin)
install(FILES README.md DESTINATION doc)
# CPack配置
set(CPACK_GENERATOR "TGZ;DEB;RPM")
set(CPACK_PACKAGE_NAME "MyApp")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_DESCRIPTION "一个示例应用")
set(CPACK_PACKAGE_VENDOR "我的公司")
include(CPack)
然后执行:
mkdir build && cd build
cmake ..
cpack -G TGZ # 生成 MyApp-1.0.0-Linux.tar.gz
就这么简单,你已经有了一个可发布的安装包。
注意:
我曾经犯过一个错误——忘记在CMakeLists.txt里写install规则。结果cpack打出来的包是空的。记住:CPack只打包你明确告诉它要安装的文件。
1.5 本章小结
这一章我们聊了:
- CPack是CMake自带的打包工具,能生成多种格式的安装包
- 它在CMake生态中负责「最后一公里」的打包分发
- 打包策略能帮你避免平台差异、版本混乱等问题
下一章,我会带你深入了解CPack支持的打包格式,以及如何根据项目需求选择合适的格式。