3、第一个CPack项目:创建最小CMake项目、添加CPack配置、生成第一个安装包
好,咱们正式开始动手了。
前面两章聊了CPack能干什么,以及它和CMake是什么关系。说实话,光说不练假把式。这一章,我带你从零开始,亲手搭建一个最小的CPack项目。
你不需要懂复杂的C++代码,甚至不需要有现成的项目。咱们就造一个最简单的“Hello World”工程,然后给它穿上CPack的外衣,生成一个实实在在的安装包。
嗯,这个过程走通了,后面再复杂的项目,无非是在这个骨架上添砖加瓦。
3.1 创建最小CMake项目
首先,咱们得有个能被CMake管理的项目。我习惯在桌面上新建一个文件夹,就叫 cpack_demo。
在里面创建两个文件:CMakeLists.txt 和 main.cpp。
main.cpp 的内容,简单到不能再简单:
#include <iostream>
int main() {
std::cout << "Hello from CPack!" << std::endl;
return 0;
}
CMakeLists.txt 的内容,也是最小配置:
cmake_minimum_required(VERSION 3.15)
project(MyApp VERSION 1.0.0 LANGUAGES CXX)
add_executable(myapp main.cpp)
install(TARGETS myapp DESTINATION bin)
这里我重点说一下 install 这一行。很多初学者会忽略它,觉得程序能编译运行就行了。但CPack打包,打的就是“安装后的内容”。
如果你不告诉CMake“安装时要把myapp放到哪个目录”,CPack就不知道要打包什么。说白了,install 命令就是给CPack画了个圈,告诉它:“圈里的东西,才是要打包的。”
3.2 添加CPack配置
CMake项目有了,接下来就是CPack的配置。你可以在 CMakeLists.txt 里直接写,也可以单独创建一个 CPackConfig.cmake 文件。我个人更喜欢后者,配置多了好管理。
在 cpack_demo 目录下,新建 CPackConfig.cmake:
set(CPACK_PACKAGE_NAME "MyApp")
set(CPACK_PACKAGE_VERSION "1.0.0")
set(CPACK_PACKAGE_VENDOR "MyCompany")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "A simple CPack demo")
set(CPACK_GENERATOR "TGZ;DEB;RPM")
include(CPack)
这里我设置了三个生成器:TGZ(tar.gz压缩包)、DEB(Debian包)、RPM(Red Hat包)。
你可能会问:“为什么一次生成这么多格式?”
其实在开发阶段,我通常只开TGZ,因为快。但到了发布阶段,我会把DEB和RPM都加上。为什么呢?因为我在项目中遇到过,同一个二进制包在Ubuntu和CentOS上安装路径不一样,提前用不同格式验证一下,能省去后面很多麻烦。
CMakeLists.txt 末尾加上 include(CPack)。如果你用了单独的配置文件,就在配置文件的末尾加。这一步是激活CPack的开关,少了它,后面所有操作都白搭。
3.3 生成第一个安装包
配置写完了,咱们来见证奇迹。
打开终端,进入 cpack_demo 目录,执行标准的CMake构建流程:
mkdir build
cd build
cmake ..
make
这时候你应该能看到 myapp 可执行文件被编译出来了。但别急,咱们要的是安装包。
在 build 目录下,执行:
cpack
如果一切顺利,你会看到类似这样的输出:
CPack: Create package using TGZ
CPack: Install projects
CPack: - Run preinstall target for: MyApp
CPack: - Install project: MyApp
CPack: Create package
CPack: - package: /path/to/cpack_demo/build/MyApp-1.0.0-Linux.tar.gz generated.
CPack: Create package using DEB
CPack: - package: /path/to/cpack_demo/build/MyApp-1.0.0-Linux.deb generated.
CPack: Create package using RPM
CPack: - package: /path/to/cpack_demo/build/MyApp-1.0.0-Linux.rpm generated.
打开 build 目录,你会看到三个安装包整整齐齐地躺在那里。
cpack 时,如果提示找不到 cpack 命令,多半是CMake没装全,或者没加到PATH里。另外,生成DEB包需要系统安装 dpkg,生成RPM包需要 rpmbuild。如果某个生成器报错,可以先把它从 CPACK_GENERATOR 里去掉,先跑通TGZ再说。
3.4 验证安装包内容
包生成了,怎么知道里面装的对不对?
对于TGZ包,你可以直接解压查看:
tar -tzf MyApp-1.0.0-Linux.tar.gz
你应该能看到类似这样的结构:
MyApp-1.0.0-Linux/
MyApp-1.0.0-Linux/bin/
MyApp-1.0.0-Linux/bin/myapp
嗯,myapp 被正确地放在了 bin 目录下。这就是我们在 install 命令里指定的目标路径。
对于DEB包,可以用 dpkg-deb -c 查看:
dpkg-deb -c MyApp-1.0.0-Linux.deb
你会看到安装路径变成了 /usr/local/bin/myapp。这是CPack根据DEB的规范自动调整的。你看,不同格式的包,安装路径的约定是不一样的。CPack帮我们处理了这些差异。
cpack -G TGZ 单独生成TGZ包来做快速验证。等所有配置都调好了,再一次性生成所有格式。这样能节省不少调试时间。
3.5 本章小结
咱们回顾一下,这一章做了三件事:
- 创建了一个包含
install命令的最小CMake项目 - 添加了CPack配置文件,指定了包名、版本和生成器
- 用
cpack命令生成了TGZ、DEB、RPM三种格式的安装包
说白了,CPack的核心流程就三步:写install → 配CPack → 跑cpack。后面的所有高级功能,都是在这个基础上叠加的。
下一章,咱们会深入聊聊 install 命令的各种玩法。毕竟,安装规则写得越精细,生成的安装包就越专业。
嗯,动手试试吧。有问题随时回来翻翻这一章。