# CMake命令install - CPack打包完全指南:跨平台安装包制作
你是否遇到过这样的困扰:
- 编译好的程序不知道如何分发给用户
- 手动复制文件到系统目录,容易出错
- 不同平台需要不同的打包方式,维护成本高
- 用户安装后不知道如何卸载
- 缺少专业的安装包,影响项目形象
这些问题都可以通过CMake的**安装和打包**功能来解决。CMake提供了完整的安装配置和CPack打包工具,可以轻松制作专业的安装包。
### 手动部署的痛点
文件分散
```bash
# 手动部署需要复制多个文件
cp myapp /usr/local/bin/
cp libmylib.so /usr/local/lib/
cp mylib.h /usr/local/include/
cp config.json /etc/myapp/
# 容易遗漏,路径不一致
```
**平台差异**
- • Windows需要NSIS或WiX安装包
- • Linux需要deb/rpm包
- • macOS需要dmg/pkg包
- • 手动制作耗时耗力
**卸载困难**
- • 用户不知道安装了哪些文件
- • 手动删除容易遗漏
- • 无法完全清理
### CMake安装和打包的价值
**自动化安装**
```bash
# 一条命令完成安装
cmake --install build
# 自动处理所有文件
# - 可执行文件到bin目录
# - 库文件到lib目录
# - 头文件到include目录
# - 配置文件到etc目录
```
跨平台打包
```bash
# 自动生成对应平台的安装包
cpack -G NSIS # Windows
cpack -G DEB # Debian/Ubuntu
cpack -G RPM # RedHat/CentOS
cpack -G DragNDrop # macOS
```
**核心优势**:
- ✅ **自动化**:一条命令完成安装和打包
- ✅ **跨平台**:统一配置,自动适配不同平台
- ✅ **专业**:生成标准的安装包格式
- ✅ **可维护**:配置集中管理,易于更新
## install命令基础(CPack的前置知识)
CPack需要基于install命令定义的安装规则来打包,所以先简单了解install命令。
### 基本用法
**安装可执行文件和库**
```cmake
include(GNUInstallDirs)
# 安装可执行文件到bin目录
install(TARGETS myapp
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
# 安装库文件
install(TARGETS mylib
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # 静态库
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # 动态库
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # Windows DLL
)
# 同时安装多个目标
install(TARGETS myapp mylib
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
```
**安装文件**
```cmake
# 安装头文件
install(FILES include/mylib.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject
)
# 安装目录
install(DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject
FILES_MATCHING PATTERN "*.h"
)
# 安装配置文件
install(FILES config/config.json
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/myproject
)
```
**标准路径变量**(推荐使用):
• `CMAKE_INSTALL_BINDIR`:bin目录
• `CMAKE_INSTALL_LIBDIR`:lib目录
• `CMAKE_INSTALL_INCLUDEDIR`:include目录
• `CMAKE_INSTALL_DATADIR`:share目录
• `CMAKE_INSTALL_SYSCONFDIR`:etc目录
完整示例
```cmake
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0.0)
add_executable(myapp src/main.cpp)
add_library(mylib STATIC src/mylib.cpp)
include(GNUInstallDirs)
install(TARGETS myapp mylib
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES include/mylib.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/myproject
)
```
# CPack打包工具详解
### CPack简介
CPack是CMake内置的打包工具,可以自动生成各种平台的安装包,无需手动编写打包脚本。
**核心特点**:
- • 🎯 **跨平台**:支持Windows、Linux、macOS
- • 📦 **多格式**:NSIS、DEB、RPM、DMG、ZIP等
- • 🔧 **易配置**:基于CMake配置,与构建流程集成
- • 📊 **自动化**:一条命令生成安装包
- • 🆓 **完全免费**:CMake内置,无需额外工具(部分生成器需要)
### 启用CPack
**基础配置**
```cmake
# 在CMakeLists.txt末尾添加
include(CPack)
```
基本设置
```cmake
set(CPACK_PACKAGE_NAME "MyProject")
set(CPACK_PACKAGE_VENDOR "MyCompany")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My Project Description")
set(CPACK_PACKAGE_DESCRIPTION "Detailed description of the project")
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_GENERATOR "ZIP") # 默认生成器
# 设置安装包文件名格式(可选)
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}")
include(CPack)
```
**重要提示**:
- `include(CPack)`必须在所有CPack配置之后
- 版本信息建议使用`PROJECT_VERSION`变量,保持一致性
- 包名建议使用小写,符合Linux包管理规范
### 多生成器配置
**同时支持多个平台**
```cmake
# 检测平台并设置生成器
if(WIN32)
set(CPACK_GENERATOR "NSIS;ZIP")
elseif(APPLE)
set(CPACK_GENERATOR "DragNDrop;TGZ")
elseif(UNIX)
set(CPACK_GENERATOR "DEB;RPM;TGZ")
endif()
include(CPack)
```
生成所有格式
```cmake
cpack -G "NSIS;ZIP" # Windows
cpack -G "DEB;RPM;TGZ" # Linux
```
# 常见问题
Q:CPack找不到生成器怎么办?
A:
• **NSIS**:Windows上需要安装NSIS(https://nsis.sourceforge.io/)
• **DEB**:Linux上需要安装`dpkg-dev`:`sudo apt-get install dpkg-dev`
• **RPM**:Linux上需要安装`rpmbuild`:`sudo yum install rpm-build`
Q:如何为不同平台生成不同的安装包?
A:
```cmake
if(WIN32)
set(CPACK_GENERATOR "NSIS;ZIP")
elseif(APPLE)
set(CPACK_GENERATOR "DragNDrop")
elseif(UNIX)
set(CPACK_GENERATOR "DEB;RPM")
endif()
```
### 核心要点回顾
**CPack的核心价值**:
- • ✅ **自动化打包**:一条命令生成安装包
- • ✅ **跨平台支持**:Windows/Linux/macOS统一配置
- • ✅ **专业格式**:生成标准安装包格式
- • ✅ **易于集成**:与CMake构建流程无缝集成
**使用建议**:
- • **基础项目**:使用install命令 + CPack基本配置即可
- • **复杂项目**:添加依赖声明、图标、许可证等
- • **CI/CD**:集成到自动化流程,自动生成安装包
**最佳实践**:
- • 使用标准安装路径(GNUInstallDirs)
- • 明确声明运行时依赖
- • 提供清晰的包描述信息
- • 集成到CI/CD流程实现自动化
### 推荐资源
**官方文档**:
- • CMake install命令
- • CPack文档
- • GNUInstallDirs
# 附录
install命令常用模式
```cmake
# 安装可执行文件
install(TARGETS myapp RUNTIME DESTINATION bin)
# 安装库文件
install(TARGETS mylib
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
# 安装头文件
install(FILES mylib.h DESTINATION include)
# 安装目录
install(DIRECTORY include/ DESTINATION include)
```
CPack常用配置
```cmake
set(CPACK_PACKAGE_NAME "MyProject")
set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
set(CPACK_GENERATOR "NSIS;DEB;RPM")
include(CPack)
```
标准安装路径
```cmake
include(GNUInstallDirs)
# ${CMAKE_INSTALL_BINDIR} # bin
# ${CMAKE_INSTALL_LIBDIR} # lib
# ${CMAKE_INSTALL_INCLUDEDIR} # include
# ${CMAKE_INSTALL_DATADIR} # share
```